Add support for Device Orientation / Motion permission API
[WebKit-https.git] / Source / WebKit / UIProcess / API / C / WKPage.cpp
1 /*
2  * Copyright (C) 2010, 2015-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 #include "config.h"
27 #include "WKPage.h"
28 #include "WKPagePrivate.h"
29
30 #include "APIArray.h"
31 #include "APIContextMenuClient.h"
32 #include "APIData.h"
33 #include "APIDictionary.h"
34 #include "APIFindClient.h"
35 #include "APIFindMatchesClient.h"
36 #include "APIFrameHandle.h"
37 #include "APIFrameInfo.h"
38 #include "APIGeometry.h"
39 #include "APIHitTestResult.h"
40 #include "APILoaderClient.h"
41 #include "APINavigation.h"
42 #include "APINavigationAction.h"
43 #include "APINavigationClient.h"
44 #include "APINavigationResponse.h"
45 #include "APIOpenPanelParameters.h"
46 #include "APIPageConfiguration.h"
47 #include "APIPolicyClient.h"
48 #include "APISessionState.h"
49 #include "APIUIClient.h"
50 #include "APIWebsitePolicies.h"
51 #include "APIWindowFeatures.h"
52 #include "AuthenticationChallengeDisposition.h"
53 #include "AuthenticationChallengeProxy.h"
54 #include "AuthenticationDecisionListener.h"
55 #include "LegacySessionStateCoding.h"
56 #include "Logging.h"
57 #include "NativeWebKeyboardEvent.h"
58 #include "NativeWebWheelEvent.h"
59 #include "NavigationActionData.h"
60 #include "PageClient.h"
61 #include "PluginInformation.h"
62 #include "PrintInfo.h"
63 #include "WKAPICast.h"
64 #include "WKPagePolicyClientInternal.h"
65 #include "WKPageRenderingProgressEventsInternal.h"
66 #include "WKPluginInformation.h"
67 #include "WebBackForwardList.h"
68 #include "WebFormClient.h"
69 #include "WebImage.h"
70 #include "WebInspectorProxy.h"
71 #include "WebOpenPanelResultListenerProxy.h"
72 #include "WebPageGroup.h"
73 #include "WebPageMessages.h"
74 #include "WebPageProxy.h"
75 #include "WebProcessPool.h"
76 #include "WebProcessProxy.h"
77 #include "WebProtectionSpace.h"
78 #include <WebCore/Page.h>
79 #include <WebCore/SSLKeyGenerator.h>
80 #include <WebCore/SecurityOriginData.h>
81 #include <WebCore/SerializedCryptoKeyWrap.h>
82 #include <WebCore/WindowFeatures.h>
83
84 #ifdef __BLOCKS__
85 #include <Block.h>
86 #endif
87
88 #if ENABLE(CONTEXT_MENUS)
89 #include "WebContextMenuItem.h"
90 #endif
91
92 #if ENABLE(MEDIA_SESSION)
93 #include "WebMediaSessionMetadata.h"
94 #include <WebCore/MediaSessionEvents.h>
95 #endif
96
97 #if PLATFORM(COCOA)
98 #include "VersionChecks.h"
99 #endif
100
101 namespace API {
102 using namespace WebCore;
103 using namespace WebKit;
104     
105 template<> struct ClientTraits<WKPageLoaderClientBase> {
106     typedef std::tuple<WKPageLoaderClientV0, WKPageLoaderClientV1, WKPageLoaderClientV2, WKPageLoaderClientV3, WKPageLoaderClientV4, WKPageLoaderClientV5, WKPageLoaderClientV6> Versions;
107 };
108
109 template<> struct ClientTraits<WKPageNavigationClientBase> {
110     typedef std::tuple<WKPageNavigationClientV0, WKPageNavigationClientV1, WKPageNavigationClientV2, WKPageNavigationClientV3> Versions;
111 };
112
113 template<> struct ClientTraits<WKPagePolicyClientBase> {
114     typedef std::tuple<WKPagePolicyClientV0, WKPagePolicyClientV1, WKPagePolicyClientInternal> Versions;
115 };
116
117 template<> struct ClientTraits<WKPageUIClientBase> {
118     typedef std::tuple<WKPageUIClientV0, WKPageUIClientV1, WKPageUIClientV2, WKPageUIClientV3, WKPageUIClientV4, WKPageUIClientV5, WKPageUIClientV6, WKPageUIClientV7, WKPageUIClientV8, WKPageUIClientV9, WKPageUIClientV10, WKPageUIClientV11, WKPageUIClientV12, WKPageUIClientV13> Versions;
119 };
120
121 #if ENABLE(CONTEXT_MENUS)
122 template<> struct ClientTraits<WKPageContextMenuClientBase> {
123     typedef std::tuple<WKPageContextMenuClientV0, WKPageContextMenuClientV1, WKPageContextMenuClientV2, WKPageContextMenuClientV3, WKPageContextMenuClientV4> Versions;
124 };
125 #endif
126
127 template<> struct ClientTraits<WKPageFindClientBase> {
128     typedef std::tuple<WKPageFindClientV0> Versions;
129 };
130
131 template<> struct ClientTraits<WKPageFindMatchesClientBase> {
132     typedef std::tuple<WKPageFindMatchesClientV0> Versions;
133 };
134     
135 } // namespace API
136
137 using namespace WebKit;
138
139 WKTypeID WKPageGetTypeID()
140 {
141     return toAPI(WebPageProxy::APIType);
142 }
143
144 WKContextRef WKPageGetContext(WKPageRef pageRef)
145 {
146     return toAPI(&toImpl(pageRef)->process().processPool());
147 }
148
149 WKPageGroupRef WKPageGetPageGroup(WKPageRef pageRef)
150 {
151     return toAPI(&toImpl(pageRef)->pageGroup());
152 }
153
154 WKPageConfigurationRef WKPageCopyPageConfiguration(WKPageRef pageRef)
155 {
156     return toAPI(&toImpl(pageRef)->configuration().copy().leakRef());
157 }
158
159 void WKPageLoadURL(WKPageRef pageRef, WKURLRef URLRef)
160 {
161     toImpl(pageRef)->loadRequest(URL(URL(), toWTFString(URLRef)));
162 }
163
164 void WKPageLoadURLWithShouldOpenExternalURLsPolicy(WKPageRef pageRef, WKURLRef URLRef, bool shouldOpenExternalURLs)
165 {
166     WebCore::ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicy = shouldOpenExternalURLs ? WebCore::ShouldOpenExternalURLsPolicy::ShouldAllow : WebCore::ShouldOpenExternalURLsPolicy::ShouldNotAllow;
167     toImpl(pageRef)->loadRequest(URL(URL(), toWTFString(URLRef)), shouldOpenExternalURLsPolicy);
168 }
169
170 void WKPageLoadURLWithUserData(WKPageRef pageRef, WKURLRef URLRef, WKTypeRef userDataRef)
171 {
172     toImpl(pageRef)->loadRequest(URL(URL(), toWTFString(URLRef)), WebCore::ShouldOpenExternalURLsPolicy::ShouldNotAllow, toImpl(userDataRef));
173 }
174
175 void WKPageLoadURLRequest(WKPageRef pageRef, WKURLRequestRef urlRequestRef)
176 {
177     auto resourceRequest = toImpl(urlRequestRef)->resourceRequest();
178     toImpl(pageRef)->loadRequest(WTFMove(resourceRequest));
179 }
180
181 void WKPageLoadURLRequestWithUserData(WKPageRef pageRef, WKURLRequestRef urlRequestRef, WKTypeRef userDataRef)
182 {
183     auto resourceRequest = toImpl(urlRequestRef)->resourceRequest();
184     toImpl(pageRef)->loadRequest(WTFMove(resourceRequest), WebCore::ShouldOpenExternalURLsPolicy::ShouldNotAllow, toImpl(userDataRef));
185 }
186
187 void WKPageLoadFile(WKPageRef pageRef, WKURLRef fileURL, WKURLRef resourceDirectoryURL)
188 {
189     toImpl(pageRef)->loadFile(toWTFString(fileURL), toWTFString(resourceDirectoryURL));
190 }
191
192 void WKPageLoadFileWithUserData(WKPageRef pageRef, WKURLRef fileURL, WKURLRef resourceDirectoryURL, WKTypeRef userDataRef)
193 {
194     toImpl(pageRef)->loadFile(toWTFString(fileURL), toWTFString(resourceDirectoryURL), toImpl(userDataRef));
195 }
196
197 void WKPageLoadData(WKPageRef pageRef, WKDataRef dataRef, WKStringRef MIMETypeRef, WKStringRef encodingRef, WKURLRef baseURLRef)
198 {
199     toImpl(pageRef)->loadData(toImpl(dataRef)->dataReference(), toWTFString(MIMETypeRef), toWTFString(encodingRef), toWTFString(baseURLRef));
200 }
201
202 void WKPageLoadDataWithUserData(WKPageRef pageRef, WKDataRef dataRef, WKStringRef MIMETypeRef, WKStringRef encodingRef, WKURLRef baseURLRef, WKTypeRef userDataRef)
203 {
204     toImpl(pageRef)->loadData(toImpl(dataRef)->dataReference(), toWTFString(MIMETypeRef), toWTFString(encodingRef), toWTFString(baseURLRef), toImpl(userDataRef));
205 }
206
207 static String encodingOf(const String& string)
208 {
209     if (string.isNull() || !string.is8Bit())
210         return "utf-16"_s;
211     return "latin1"_s;
212 }
213
214 static IPC::DataReference dataFrom(const String& string)
215 {
216     if (string.isNull() || !string.is8Bit())
217         return { reinterpret_cast<const uint8_t*>(string.characters16()), string.length() * sizeof(UChar) };
218     return { reinterpret_cast<const uint8_t*>(string.characters8()), string.length() * sizeof(LChar) };
219 }
220
221 static void loadString(WKPageRef pageRef, WKStringRef stringRef, const String& mimeType, const String& baseURL, WKTypeRef userDataRef)
222 {
223     String string = toWTFString(stringRef);
224     toImpl(pageRef)->loadData(dataFrom(string), mimeType, encodingOf(string), baseURL, toImpl(userDataRef));
225 }
226
227 void WKPageLoadHTMLString(WKPageRef pageRef, WKStringRef htmlStringRef, WKURLRef baseURLRef)
228 {
229     WKPageLoadHTMLStringWithUserData(pageRef, htmlStringRef, baseURLRef, nullptr);
230 }
231
232 void WKPageLoadHTMLStringWithUserData(WKPageRef pageRef, WKStringRef htmlStringRef, WKURLRef baseURLRef, WKTypeRef userDataRef)
233 {
234     loadString(pageRef, htmlStringRef, "text/html"_s, toWTFString(baseURLRef), userDataRef);
235 }
236
237 void WKPageLoadAlternateHTMLString(WKPageRef pageRef, WKStringRef htmlStringRef, WKURLRef baseURLRef, WKURLRef unreachableURLRef)
238 {
239     WKPageLoadAlternateHTMLStringWithUserData(pageRef, htmlStringRef, baseURLRef, unreachableURLRef, nullptr);
240 }
241
242 void WKPageLoadAlternateHTMLStringWithUserData(WKPageRef pageRef, WKStringRef htmlStringRef, WKURLRef baseURLRef, WKURLRef unreachableURLRef, WKTypeRef userDataRef)
243 {
244     String string = toWTFString(htmlStringRef);
245     toImpl(pageRef)->loadAlternateHTML(dataFrom(string), encodingOf(string), URL(URL(), toWTFString(baseURLRef)), URL(URL(), toWTFString(unreachableURLRef)), toImpl(userDataRef));
246 }
247
248 void WKPageLoadPlainTextString(WKPageRef pageRef, WKStringRef plainTextStringRef)
249 {
250     WKPageLoadPlainTextStringWithUserData(pageRef, plainTextStringRef, nullptr);
251 }
252
253 void WKPageLoadPlainTextStringWithUserData(WKPageRef pageRef, WKStringRef plainTextStringRef, WKTypeRef userDataRef)
254 {
255     loadString(pageRef, plainTextStringRef, "text/plain"_s, WTF::blankURL().string(), userDataRef);
256 }
257
258 void WKPageLoadWebArchiveData(WKPageRef pageRef, WKDataRef webArchiveDataRef)
259 {
260     toImpl(pageRef)->loadWebArchiveData(toImpl(webArchiveDataRef));
261 }
262
263 void WKPageLoadWebArchiveDataWithUserData(WKPageRef pageRef, WKDataRef webArchiveDataRef, WKTypeRef userDataRef)
264 {
265     toImpl(pageRef)->loadWebArchiveData(toImpl(webArchiveDataRef), toImpl(userDataRef));
266 }
267
268 void WKPageStopLoading(WKPageRef pageRef)
269 {
270     toImpl(pageRef)->stopLoading();
271 }
272
273 void WKPageReload(WKPageRef pageRef)
274 {
275     OptionSet<WebCore::ReloadOption> reloadOptions;
276 #if PLATFORM(COCOA)
277     if (linkedOnOrAfter(WebKit::SDKVersion::FirstWithExpiredOnlyReloadBehavior))
278         reloadOptions.add(WebCore::ReloadOption::ExpiredOnly);
279 #endif
280
281     toImpl(pageRef)->reload(reloadOptions);
282 }
283
284 void WKPageReloadWithoutContentBlockers(WKPageRef pageRef)
285 {
286     toImpl(pageRef)->reload(WebCore::ReloadOption::DisableContentBlockers);
287 }
288
289 void WKPageReloadFromOrigin(WKPageRef pageRef)
290 {
291     toImpl(pageRef)->reload(WebCore::ReloadOption::FromOrigin);
292 }
293
294 void WKPageReloadExpiredOnly(WKPageRef pageRef)
295 {
296     toImpl(pageRef)->reload(WebCore::ReloadOption::ExpiredOnly);
297 }
298
299 bool WKPageTryClose(WKPageRef pageRef)
300 {
301     return toImpl(pageRef)->tryClose();
302 }
303
304 void WKPageClose(WKPageRef pageRef)
305 {
306     toImpl(pageRef)->close();
307 }
308
309 bool WKPageIsClosed(WKPageRef pageRef)
310 {
311     return toImpl(pageRef)->isClosed();
312 }
313
314 void WKPageGoForward(WKPageRef pageRef)
315 {
316     toImpl(pageRef)->goForward();
317 }
318
319 bool WKPageCanGoForward(WKPageRef pageRef)
320 {
321     return toImpl(pageRef)->backForwardList().forwardItem();
322 }
323
324 void WKPageGoBack(WKPageRef pageRef)
325 {
326     auto& page = *toImpl(pageRef);
327     if (page.pageClient().hasSafeBrowsingWarning()) {
328         WKPageReload(pageRef);
329         return;
330     }
331     page.goBack();
332 }
333
334 bool WKPageCanGoBack(WKPageRef pageRef)
335 {
336     return toImpl(pageRef)->backForwardList().backItem();
337 }
338
339 void WKPageGoToBackForwardListItem(WKPageRef pageRef, WKBackForwardListItemRef itemRef)
340 {
341     toImpl(pageRef)->goToBackForwardItem(*toImpl(itemRef));
342 }
343
344 void WKPageTryRestoreScrollPosition(WKPageRef pageRef)
345 {
346     toImpl(pageRef)->tryRestoreScrollPosition();
347 }
348
349 WKBackForwardListRef WKPageGetBackForwardList(WKPageRef pageRef)
350 {
351     return toAPI(&toImpl(pageRef)->backForwardList());
352 }
353
354 bool WKPageWillHandleHorizontalScrollEvents(WKPageRef pageRef)
355 {
356     return toImpl(pageRef)->willHandleHorizontalScrollEvents();
357 }
358
359 void WKPageUpdateWebsitePolicies(WKPageRef pageRef, WKWebsitePoliciesRef websitePoliciesRef)
360 {
361     auto data = toImpl(websitePoliciesRef)->data();
362     RELEASE_ASSERT_WITH_MESSAGE(!data.websiteDataStoreParameters, "Setting WebsitePolicies.WebsiteDataStore is only supported during WKFramePolicyListenerUseWithPolicies().");
363     toImpl(pageRef)->updateWebsitePolicies(WTFMove(data));
364 }
365
366 WKStringRef WKPageCopyTitle(WKPageRef pageRef)
367 {
368     return toCopiedAPI(toImpl(pageRef)->pageLoadState().title());
369 }
370
371 WKFrameRef WKPageGetMainFrame(WKPageRef pageRef)
372 {
373     return toAPI(toImpl(pageRef)->mainFrame());
374 }
375
376 WKFrameRef WKPageGetFocusedFrame(WKPageRef pageRef)
377 {
378     return toAPI(toImpl(pageRef)->focusedFrame());
379 }
380
381 WKFrameRef WKPageGetFrameSetLargestFrame(WKPageRef pageRef)
382 {
383     return toAPI(toImpl(pageRef)->frameSetLargestFrame());
384 }
385
386 uint64_t WKPageGetRenderTreeSize(WKPageRef page)
387 {
388     return toImpl(page)->renderTreeSize();
389 }
390
391 WKInspectorRef WKPageGetInspector(WKPageRef pageRef)
392 {
393     return toAPI(toImpl(pageRef)->inspector());
394 }
395
396 double WKPageGetEstimatedProgress(WKPageRef pageRef)
397 {
398     return toImpl(pageRef)->estimatedProgress();
399 }
400
401 WKStringRef WKPageCopyUserAgent(WKPageRef pageRef)
402 {
403     return toCopiedAPI(toImpl(pageRef)->userAgent());
404 }
405
406 WKStringRef WKPageCopyApplicationNameForUserAgent(WKPageRef pageRef)
407 {
408     return toCopiedAPI(toImpl(pageRef)->applicationNameForUserAgent());
409 }
410
411 void WKPageSetApplicationNameForUserAgent(WKPageRef pageRef, WKStringRef applicationNameRef)
412 {
413     toImpl(pageRef)->setApplicationNameForUserAgent(toWTFString(applicationNameRef));
414 }
415
416 WKStringRef WKPageCopyCustomUserAgent(WKPageRef pageRef)
417 {
418     return toCopiedAPI(toImpl(pageRef)->customUserAgent());
419 }
420
421 void WKPageSetCustomUserAgent(WKPageRef pageRef, WKStringRef userAgentRef)
422 {
423     toImpl(pageRef)->setCustomUserAgent(toWTFString(userAgentRef));
424 }
425
426 void WKPageSetUserContentExtensionsEnabled(WKPageRef pageRef, bool enabled)
427 {
428     // FIXME: Remove this function once it is no longer used.
429 }
430
431 bool WKPageSupportsTextEncoding(WKPageRef pageRef)
432 {
433     return toImpl(pageRef)->supportsTextEncoding();
434 }
435
436 WKStringRef WKPageCopyCustomTextEncodingName(WKPageRef pageRef)
437 {
438     return toCopiedAPI(toImpl(pageRef)->customTextEncodingName());
439 }
440
441 void WKPageSetCustomTextEncodingName(WKPageRef pageRef, WKStringRef encodingNameRef)
442 {
443     toImpl(pageRef)->setCustomTextEncodingName(toWTFString(encodingNameRef));
444 }
445
446 void WKPageTerminate(WKPageRef pageRef)
447 {
448     Ref<WebProcessProxy> protectedProcessProxy(toImpl(pageRef)->process());
449     protectedProcessProxy->requestTermination(ProcessTerminationReason::RequestedByClient);
450 }
451
452 WKStringRef WKPageGetSessionHistoryURLValueType()
453 {
454     static API::String& sessionHistoryURLValueType = API::String::create("SessionHistoryURL").leakRef();
455     return toAPI(&sessionHistoryURLValueType);
456 }
457
458 WKStringRef WKPageGetSessionBackForwardListItemValueType()
459 {
460     static API::String& sessionBackForwardListValueType = API::String::create("SessionBackForwardListItem").leakRef();
461     return toAPI(&sessionBackForwardListValueType);
462 }
463
464 WKTypeRef WKPageCopySessionState(WKPageRef pageRef, void* context, WKPageSessionStateFilterCallback filter)
465 {
466     // FIXME: This is a hack to make sure we return a WKDataRef to maintain compatibility with older versions of Safari.
467     bool shouldReturnData = !(reinterpret_cast<uintptr_t>(context) & 1);
468     context = reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(context) & ~1);
469
470     auto sessionState = toImpl(pageRef)->sessionState([pageRef, context, filter](WebBackForwardListItem& item) {
471         if (filter) {
472             if (!filter(pageRef, WKPageGetSessionBackForwardListItemValueType(), toAPI(&item), context))
473                 return false;
474
475             if (!filter(pageRef, WKPageGetSessionHistoryURLValueType(), toURLRef(item.originalURL().impl()), context))
476                 return false;
477         }
478
479         return true;
480     });
481
482     if (shouldReturnData)
483         return toAPI(encodeLegacySessionState(sessionState).leakRef());
484
485     return toAPI(&API::SessionState::create(WTFMove(sessionState)).leakRef());
486 }
487
488 static void restoreFromSessionState(WKPageRef pageRef, WKTypeRef sessionStateRef, bool navigate)
489 {
490     SessionState sessionState;
491
492     // FIXME: This is for backwards compatibility with Safari. Remove it once Safari no longer depends on it.
493     if (toImpl(sessionStateRef)->type() == API::Object::Type::Data) {
494         if (!decodeLegacySessionState(toImpl(static_cast<WKDataRef>(sessionStateRef))->bytes(), toImpl(static_cast<WKDataRef>(sessionStateRef))->size(), sessionState))
495             return;
496     } else {
497         ASSERT(toImpl(sessionStateRef)->type() == API::Object::Type::SessionState);
498
499         sessionState = toImpl(static_cast<WKSessionStateRef>(sessionStateRef))->sessionState();
500     }
501
502     toImpl(pageRef)->restoreFromSessionState(WTFMove(sessionState), navigate);
503 }
504
505 void WKPageRestoreFromSessionState(WKPageRef pageRef, WKTypeRef sessionStateRef)
506 {
507     restoreFromSessionState(pageRef, sessionStateRef, true);
508 }
509
510 void WKPageRestoreFromSessionStateWithoutNavigation(WKPageRef pageRef, WKTypeRef sessionStateRef)
511 {
512     restoreFromSessionState(pageRef, sessionStateRef, false);
513 }
514
515 double WKPageGetTextZoomFactor(WKPageRef pageRef)
516 {
517     return toImpl(pageRef)->textZoomFactor();
518 }
519
520 double WKPageGetBackingScaleFactor(WKPageRef pageRef)
521 {
522     return toImpl(pageRef)->deviceScaleFactor();
523 }
524
525 void WKPageSetCustomBackingScaleFactor(WKPageRef pageRef, double customScaleFactor)
526 {
527     toImpl(pageRef)->setCustomDeviceScaleFactor(customScaleFactor);
528 }
529
530 bool WKPageSupportsTextZoom(WKPageRef pageRef)
531 {
532     return toImpl(pageRef)->supportsTextZoom();
533 }
534
535 void WKPageSetTextZoomFactor(WKPageRef pageRef, double zoomFactor)
536 {
537     toImpl(pageRef)->setTextZoomFactor(zoomFactor);
538 }
539
540 double WKPageGetPageZoomFactor(WKPageRef pageRef)
541 {
542     return toImpl(pageRef)->pageZoomFactor();
543 }
544
545 void WKPageSetPageZoomFactor(WKPageRef pageRef, double zoomFactor)
546 {
547     toImpl(pageRef)->setPageZoomFactor(zoomFactor);
548 }
549
550 void WKPageSetPageAndTextZoomFactors(WKPageRef pageRef, double pageZoomFactor, double textZoomFactor)
551 {
552     toImpl(pageRef)->setPageAndTextZoomFactors(pageZoomFactor, textZoomFactor);
553 }
554
555 void WKPageSetScaleFactor(WKPageRef pageRef, double scale, WKPoint origin)
556 {
557     toImpl(pageRef)->scalePage(scale, toIntPoint(origin));
558 }
559
560 double WKPageGetScaleFactor(WKPageRef pageRef)
561 {
562     return toImpl(pageRef)->pageScaleFactor();
563 }
564
565 void WKPageSetUseFixedLayout(WKPageRef pageRef, bool fixed)
566 {
567     toImpl(pageRef)->setUseFixedLayout(fixed);
568 }
569
570 void WKPageSetFixedLayoutSize(WKPageRef pageRef, WKSize size)
571 {
572     toImpl(pageRef)->setFixedLayoutSize(toIntSize(size));
573 }
574
575 bool WKPageUseFixedLayout(WKPageRef pageRef)
576 {
577     return toImpl(pageRef)->useFixedLayout();
578 }
579
580 WKSize WKPageFixedLayoutSize(WKPageRef pageRef)
581 {
582     return toAPI(toImpl(pageRef)->fixedLayoutSize());
583 }
584
585 void WKPageListenForLayoutMilestones(WKPageRef pageRef, WKLayoutMilestones milestones)
586 {
587     toImpl(pageRef)->listenForLayoutMilestones(toLayoutMilestones(milestones));
588 }
589
590 bool WKPageHasHorizontalScrollbar(WKPageRef pageRef)
591 {
592     return toImpl(pageRef)->hasHorizontalScrollbar();
593 }
594
595 bool WKPageHasVerticalScrollbar(WKPageRef pageRef)
596 {
597     return toImpl(pageRef)->hasVerticalScrollbar();
598 }
599
600 void WKPageSetSuppressScrollbarAnimations(WKPageRef pageRef, bool suppressAnimations)
601 {
602     toImpl(pageRef)->setSuppressScrollbarAnimations(suppressAnimations);
603 }
604
605 bool WKPageAreScrollbarAnimationsSuppressed(WKPageRef pageRef)
606 {
607     return toImpl(pageRef)->areScrollbarAnimationsSuppressed();
608 }
609
610 bool WKPageIsPinnedToLeftSide(WKPageRef pageRef)
611 {
612     return toImpl(pageRef)->isPinnedToLeftSide();
613 }
614
615 bool WKPageIsPinnedToRightSide(WKPageRef pageRef)
616 {
617     return toImpl(pageRef)->isPinnedToRightSide();
618 }
619
620 bool WKPageIsPinnedToTopSide(WKPageRef pageRef)
621 {
622     return toImpl(pageRef)->isPinnedToTopSide();
623 }
624
625 bool WKPageIsPinnedToBottomSide(WKPageRef pageRef)
626 {
627     return toImpl(pageRef)->isPinnedToBottomSide();
628 }
629
630 bool WKPageRubberBandsAtLeft(WKPageRef pageRef)
631 {
632     return toImpl(pageRef)->rubberBandsAtLeft();
633 }
634
635 void WKPageSetRubberBandsAtLeft(WKPageRef pageRef, bool rubberBandsAtLeft)
636 {
637     toImpl(pageRef)->setRubberBandsAtLeft(rubberBandsAtLeft);
638 }
639
640 bool WKPageRubberBandsAtRight(WKPageRef pageRef)
641 {
642     return toImpl(pageRef)->rubberBandsAtRight();
643 }
644
645 void WKPageSetRubberBandsAtRight(WKPageRef pageRef, bool rubberBandsAtRight)
646 {
647     toImpl(pageRef)->setRubberBandsAtRight(rubberBandsAtRight);
648 }
649
650 bool WKPageRubberBandsAtTop(WKPageRef pageRef)
651 {
652     return toImpl(pageRef)->rubberBandsAtTop();
653 }
654
655 void WKPageSetRubberBandsAtTop(WKPageRef pageRef, bool rubberBandsAtTop)
656 {
657     toImpl(pageRef)->setRubberBandsAtTop(rubberBandsAtTop);
658 }
659
660 bool WKPageRubberBandsAtBottom(WKPageRef pageRef)
661 {
662     return toImpl(pageRef)->rubberBandsAtBottom();
663 }
664
665 void WKPageSetRubberBandsAtBottom(WKPageRef pageRef, bool rubberBandsAtBottom)
666 {
667     toImpl(pageRef)->setRubberBandsAtBottom(rubberBandsAtBottom);
668 }
669
670 bool WKPageVerticalRubberBandingIsEnabled(WKPageRef pageRef)
671 {
672     return toImpl(pageRef)->verticalRubberBandingIsEnabled();
673 }
674
675 void WKPageSetEnableVerticalRubberBanding(WKPageRef pageRef, bool enableVerticalRubberBanding)
676 {
677     toImpl(pageRef)->setEnableVerticalRubberBanding(enableVerticalRubberBanding);
678 }
679
680 bool WKPageHorizontalRubberBandingIsEnabled(WKPageRef pageRef)
681 {
682     return toImpl(pageRef)->horizontalRubberBandingIsEnabled();
683 }
684
685 void WKPageSetEnableHorizontalRubberBanding(WKPageRef pageRef, bool enableHorizontalRubberBanding)
686 {
687     toImpl(pageRef)->setEnableHorizontalRubberBanding(enableHorizontalRubberBanding);
688 }
689
690 void WKPageSetBackgroundExtendsBeyondPage(WKPageRef pageRef, bool backgroundExtendsBeyondPage)
691 {
692     toImpl(pageRef)->setBackgroundExtendsBeyondPage(backgroundExtendsBeyondPage);
693 }
694
695 bool WKPageBackgroundExtendsBeyondPage(WKPageRef pageRef)
696 {
697     return toImpl(pageRef)->backgroundExtendsBeyondPage();
698 }
699
700 void WKPageSetPaginationMode(WKPageRef pageRef, WKPaginationMode paginationMode)
701 {
702     WebCore::Pagination::Mode mode;
703     switch (paginationMode) {
704     case kWKPaginationModeUnpaginated:
705         mode = WebCore::Pagination::Unpaginated;
706         break;
707     case kWKPaginationModeLeftToRight:
708         mode = WebCore::Pagination::LeftToRightPaginated;
709         break;
710     case kWKPaginationModeRightToLeft:
711         mode = WebCore::Pagination::RightToLeftPaginated;
712         break;
713     case kWKPaginationModeTopToBottom:
714         mode = WebCore::Pagination::TopToBottomPaginated;
715         break;
716     case kWKPaginationModeBottomToTop:
717         mode = WebCore::Pagination::BottomToTopPaginated;
718         break;
719     default:
720         return;
721     }
722     toImpl(pageRef)->setPaginationMode(mode);
723 }
724
725 WKPaginationMode WKPageGetPaginationMode(WKPageRef pageRef)
726 {
727     switch (toImpl(pageRef)->paginationMode()) {
728     case WebCore::Pagination::Unpaginated:
729         return kWKPaginationModeUnpaginated;
730     case WebCore::Pagination::LeftToRightPaginated:
731         return kWKPaginationModeLeftToRight;
732     case WebCore::Pagination::RightToLeftPaginated:
733         return kWKPaginationModeRightToLeft;
734     case WebCore::Pagination::TopToBottomPaginated:
735         return kWKPaginationModeTopToBottom;
736     case WebCore::Pagination::BottomToTopPaginated:
737         return kWKPaginationModeBottomToTop;
738     }
739
740     ASSERT_NOT_REACHED();
741     return kWKPaginationModeUnpaginated;
742 }
743
744 void WKPageSetPaginationBehavesLikeColumns(WKPageRef pageRef, bool behavesLikeColumns)
745 {
746     toImpl(pageRef)->setPaginationBehavesLikeColumns(behavesLikeColumns);
747 }
748
749 bool WKPageGetPaginationBehavesLikeColumns(WKPageRef pageRef)
750 {
751     return toImpl(pageRef)->paginationBehavesLikeColumns();
752 }
753
754 void WKPageSetPageLength(WKPageRef pageRef, double pageLength)
755 {
756     toImpl(pageRef)->setPageLength(pageLength);
757 }
758
759 double WKPageGetPageLength(WKPageRef pageRef)
760 {
761     return toImpl(pageRef)->pageLength();
762 }
763
764 void WKPageSetGapBetweenPages(WKPageRef pageRef, double gap)
765 {
766     toImpl(pageRef)->setGapBetweenPages(gap);
767 }
768
769 double WKPageGetGapBetweenPages(WKPageRef pageRef)
770 {
771     return toImpl(pageRef)->gapBetweenPages();
772 }
773
774 void WKPageSetPaginationLineGridEnabled(WKPageRef pageRef, bool lineGridEnabled)
775 {
776     toImpl(pageRef)->setPaginationLineGridEnabled(lineGridEnabled);
777 }
778
779 bool WKPageGetPaginationLineGridEnabled(WKPageRef pageRef)
780 {
781     return toImpl(pageRef)->paginationLineGridEnabled();
782 }
783
784 unsigned WKPageGetPageCount(WKPageRef pageRef)
785 {
786     return toImpl(pageRef)->pageCount();
787 }
788
789 bool WKPageCanDelete(WKPageRef pageRef)
790 {
791     return toImpl(pageRef)->canDelete();
792 }
793
794 bool WKPageHasSelectedRange(WKPageRef pageRef)
795 {
796     return toImpl(pageRef)->hasSelectedRange();
797 }
798
799 bool WKPageIsContentEditable(WKPageRef pageRef)
800 {
801     return toImpl(pageRef)->isContentEditable();
802 }
803
804 void WKPageSetMaintainsInactiveSelection(WKPageRef pageRef, bool newValue)
805 {
806     return toImpl(pageRef)->setMaintainsInactiveSelection(newValue);
807 }
808
809 void WKPageCenterSelectionInVisibleArea(WKPageRef pageRef)
810 {
811     return toImpl(pageRef)->centerSelectionInVisibleArea();
812 }
813
814 void WKPageFindStringMatches(WKPageRef pageRef, WKStringRef string, WKFindOptions options, unsigned maxMatchCount)
815 {
816     toImpl(pageRef)->findStringMatches(toImpl(string)->string(), toFindOptions(options), maxMatchCount);
817 }
818
819 void WKPageGetImageForFindMatch(WKPageRef pageRef, int32_t matchIndex)
820 {
821     toImpl(pageRef)->getImageForFindMatch(matchIndex);
822 }
823
824 void WKPageSelectFindMatch(WKPageRef pageRef, int32_t matchIndex)
825 {
826     toImpl(pageRef)->selectFindMatch(matchIndex);
827 }
828
829 void WKPageFindString(WKPageRef pageRef, WKStringRef string, WKFindOptions options, unsigned maxMatchCount)
830 {
831     toImpl(pageRef)->findString(toImpl(string)->string(), toFindOptions(options), maxMatchCount);
832 }
833
834 void WKPageHideFindUI(WKPageRef pageRef)
835 {
836     toImpl(pageRef)->hideFindUI();
837 }
838
839 void WKPageCountStringMatches(WKPageRef pageRef, WKStringRef string, WKFindOptions options, unsigned maxMatchCount)
840 {
841     toImpl(pageRef)->countStringMatches(toImpl(string)->string(), toFindOptions(options), maxMatchCount);
842 }
843
844 void WKPageSetPageContextMenuClient(WKPageRef pageRef, const WKPageContextMenuClientBase* wkClient)
845 {
846 #if ENABLE(CONTEXT_MENUS)
847     class ContextMenuClient final : public API::Client<WKPageContextMenuClientBase>, public API::ContextMenuClient {
848     public:
849         explicit ContextMenuClient(const WKPageContextMenuClientBase* client)
850         {
851             initialize(client);
852         }
853
854     private:
855         void getContextMenuFromProposedMenu(WebPageProxy& page, Vector<Ref<WebKit::WebContextMenuItem>>&& proposedMenuVector, WebKit::WebContextMenuListenerProxy& contextMenuListener, const WebHitTestResultData& hitTestResultData, API::Object* userData) override
856         {
857             if (m_client.base.version >= 4 && m_client.getContextMenuFromProposedMenuAsync) {
858                 Vector<RefPtr<API::Object>> proposedMenuItems;
859                 proposedMenuItems.reserveInitialCapacity(proposedMenuVector.size());
860                 
861                 for (const auto& menuItem : proposedMenuVector)
862                     proposedMenuItems.uncheckedAppend(menuItem.ptr());
863                 
864                 auto webHitTestResult = API::HitTestResult::create(hitTestResultData);
865                 m_client.getContextMenuFromProposedMenuAsync(toAPI(&page), toAPI(API::Array::create(WTFMove(proposedMenuItems)).ptr()), toAPI(&contextMenuListener), toAPI(webHitTestResult.ptr()), toAPI(userData), m_client.base.clientInfo);
866                 return;
867             }
868             
869             if (!m_client.getContextMenuFromProposedMenu && !m_client.getContextMenuFromProposedMenu_deprecatedForUseWithV0) {
870                 contextMenuListener.useContextMenuItems(WTFMove(proposedMenuVector));
871                 return;
872             }
873
874             if (m_client.base.version >= 2 && !m_client.getContextMenuFromProposedMenu) {
875                 contextMenuListener.useContextMenuItems(WTFMove(proposedMenuVector));
876                 return;
877             }
878
879             Vector<RefPtr<API::Object>> proposedMenuItems;
880             proposedMenuItems.reserveInitialCapacity(proposedMenuVector.size());
881
882             for (const auto& menuItem : proposedMenuVector)
883                 proposedMenuItems.uncheckedAppend(menuItem.ptr());
884
885             WKArrayRef newMenu = nullptr;
886             if (m_client.base.version >= 2) {
887                 auto webHitTestResult = API::HitTestResult::create(hitTestResultData);
888                 m_client.getContextMenuFromProposedMenu(toAPI(&page), toAPI(API::Array::create(WTFMove(proposedMenuItems)).ptr()), &newMenu, toAPI(webHitTestResult.ptr()), toAPI(userData), m_client.base.clientInfo);
889             } else
890                 m_client.getContextMenuFromProposedMenu_deprecatedForUseWithV0(toAPI(&page), toAPI(API::Array::create(WTFMove(proposedMenuItems)).ptr()), &newMenu, toAPI(userData), m_client.base.clientInfo);
891
892             RefPtr<API::Array> array = adoptRef(toImpl(newMenu));
893
894             Vector<Ref<WebContextMenuItem>> customMenu;
895             size_t newSize = array ? array->size() : 0;
896             customMenu.reserveInitialCapacity(newSize);
897             for (size_t i = 0; i < newSize; ++i) {
898                 WebContextMenuItem* item = array->at<WebContextMenuItem>(i);
899                 if (!item) {
900                     LOG(ContextMenu, "New menu entry at index %i is not a WebContextMenuItem", (int)i);
901                     continue;
902                 }
903
904                 customMenu.uncheckedAppend(*item);
905             }
906
907             contextMenuListener.useContextMenuItems(WTFMove(customMenu));
908         }
909
910         void customContextMenuItemSelected(WebPageProxy& page, const WebContextMenuItemData& itemData) override
911         {
912             if (!m_client.customContextMenuItemSelected)
913                 return;
914
915             m_client.customContextMenuItemSelected(toAPI(&page), toAPI(WebContextMenuItem::create(itemData).ptr()), m_client.base.clientInfo);
916         }
917
918         bool showContextMenu(WebPageProxy& page, const WebCore::IntPoint& menuLocation, const Vector<Ref<WebContextMenuItem>>& menuItemsVector) override
919         {
920             if (!m_client.showContextMenu)
921                 return false;
922
923             Vector<RefPtr<API::Object>> menuItems;
924             menuItems.reserveInitialCapacity(menuItemsVector.size());
925
926             for (const auto& menuItem : menuItemsVector)
927                 menuItems.uncheckedAppend(menuItem.ptr());
928
929             m_client.showContextMenu(toAPI(&page), toAPI(menuLocation), toAPI(API::Array::create(WTFMove(menuItems)).ptr()), m_client.base.clientInfo);
930
931             return true;
932         }
933
934         bool hideContextMenu(WebPageProxy& page) override
935         {
936             if (!m_client.hideContextMenu)
937                 return false;
938
939             m_client.hideContextMenu(toAPI(&page), m_client.base.clientInfo);
940
941             return true;
942         }
943     };
944
945     toImpl(pageRef)->setContextMenuClient(std::make_unique<ContextMenuClient>(wkClient));
946 #else
947     UNUSED_PARAM(pageRef);
948     UNUSED_PARAM(wkClient);
949 #endif
950 }
951
952 void WKPageSetPageDiagnosticLoggingClient(WKPageRef pageRef, const WKPageDiagnosticLoggingClientBase* wkClient)
953 {
954     toImpl(pageRef)->setDiagnosticLoggingClient(std::make_unique<WebPageDiagnosticLoggingClient>(wkClient));
955 }
956
957 void WKPageSetPageFindClient(WKPageRef pageRef, const WKPageFindClientBase* wkClient)
958 {
959     class FindClient : public API::Client<WKPageFindClientBase>, public API::FindClient {
960     public:
961         explicit FindClient(const WKPageFindClientBase* client)
962         {
963             initialize(client);
964         }
965
966     private:
967         void didFindString(WebPageProxy* page, const String& string, const Vector<WebCore::IntRect>&, uint32_t matchCount, int32_t, bool didWrapAround) override
968         {
969             if (!m_client.didFindString)
970                 return;
971             
972             m_client.didFindString(toAPI(page), toAPI(string.impl()), matchCount, m_client.base.clientInfo);
973         }
974
975         void didFailToFindString(WebPageProxy* page, const String& string) override
976         {
977             if (!m_client.didFailToFindString)
978                 return;
979             
980             m_client.didFailToFindString(toAPI(page), toAPI(string.impl()), m_client.base.clientInfo);
981         }
982
983         void didCountStringMatches(WebPageProxy* page, const String& string, uint32_t matchCount) override
984         {
985             if (!m_client.didCountStringMatches)
986                 return;
987
988             m_client.didCountStringMatches(toAPI(page), toAPI(string.impl()), matchCount, m_client.base.clientInfo);
989         }
990     };
991
992     toImpl(pageRef)->setFindClient(std::make_unique<FindClient>(wkClient));
993 }
994
995 void WKPageSetPageFindMatchesClient(WKPageRef pageRef, const WKPageFindMatchesClientBase* wkClient)
996 {
997     class FindMatchesClient : public API::Client<WKPageFindMatchesClientBase>, public API::FindMatchesClient {
998     public:
999         explicit FindMatchesClient(const WKPageFindMatchesClientBase* client)
1000         {
1001             initialize(client);
1002         }
1003
1004     private:
1005         void didFindStringMatches(WebPageProxy* page, const String& string, const Vector<Vector<WebCore::IntRect>>& matchRects, int32_t index) override
1006         {
1007             if (!m_client.didFindStringMatches)
1008                 return;
1009
1010             Vector<RefPtr<API::Object>> matches;
1011             matches.reserveInitialCapacity(matchRects.size());
1012
1013             for (const auto& rects : matchRects) {
1014                 Vector<RefPtr<API::Object>> apiRects;
1015                 apiRects.reserveInitialCapacity(rects.size());
1016
1017                 for (const auto& rect : rects)
1018                     apiRects.uncheckedAppend(API::Rect::create(toAPI(rect)));
1019
1020                 matches.uncheckedAppend(API::Array::create(WTFMove(apiRects)));
1021             }
1022
1023             m_client.didFindStringMatches(toAPI(page), toAPI(string.impl()), toAPI(API::Array::create(WTFMove(matches)).ptr()), index, m_client.base.clientInfo);
1024         }
1025
1026         void didGetImageForMatchResult(WebPageProxy* page, WebImage* image, int32_t index) override
1027         {
1028             if (!m_client.didGetImageForMatchResult)
1029                 return;
1030
1031             m_client.didGetImageForMatchResult(toAPI(page), toAPI(image), index, m_client.base.clientInfo);
1032         }
1033     };
1034
1035     toImpl(pageRef)->setFindMatchesClient(std::make_unique<FindMatchesClient>(wkClient));
1036 }
1037
1038 void WKPageSetPageInjectedBundleClient(WKPageRef pageRef, const WKPageInjectedBundleClientBase* wkClient)
1039 {
1040     toImpl(pageRef)->setInjectedBundleClient(wkClient);
1041 }
1042
1043 void WKPageSetPageFormClient(WKPageRef pageRef, const WKPageFormClientBase* wkClient)
1044 {
1045     toImpl(pageRef)->setFormClient(std::make_unique<WebFormClient>(wkClient));
1046 }
1047
1048 void WKPageSetPageLoaderClient(WKPageRef pageRef, const WKPageLoaderClientBase* wkClient)
1049 {
1050     class LoaderClient : public API::Client<WKPageLoaderClientBase>, public API::LoaderClient {
1051     public:
1052         explicit LoaderClient(const WKPageLoaderClientBase* client)
1053         {
1054             initialize(client);
1055             
1056 #if !PLATFORM(MAC) || __MAC_OS_X_VERSION_MIN_REQUIRED > 101400
1057             // WKPageSetPageLoaderClient is deprecated. Use WKPageSetPageNavigationClient instead.
1058             RELEASE_ASSERT(!m_client.didFinishDocumentLoadForFrame);
1059             RELEASE_ASSERT(!m_client.didSameDocumentNavigationForFrame);
1060             RELEASE_ASSERT(!m_client.didReceiveTitleForFrame);
1061             RELEASE_ASSERT(!m_client.didFirstLayoutForFrame);
1062             RELEASE_ASSERT(!m_client.didRemoveFrameFromHierarchy);
1063             RELEASE_ASSERT(!m_client.didDisplayInsecureContentForFrame);
1064             RELEASE_ASSERT(!m_client.didRunInsecureContentForFrame);
1065             RELEASE_ASSERT(!m_client.canAuthenticateAgainstProtectionSpaceInFrame);
1066             RELEASE_ASSERT(!m_client.didReceiveAuthenticationChallengeInFrame);
1067             RELEASE_ASSERT(!m_client.didStartProgress);
1068             RELEASE_ASSERT(!m_client.didChangeProgress);
1069             RELEASE_ASSERT(!m_client.didFinishProgress);
1070             RELEASE_ASSERT(!m_client.processDidBecomeUnresponsive);
1071             RELEASE_ASSERT(!m_client.processDidBecomeResponsive);
1072             RELEASE_ASSERT(!m_client.shouldGoToBackForwardListItem);
1073             RELEASE_ASSERT(!m_client.didFailToInitializePlugin_deprecatedForUseWithV0);
1074             RELEASE_ASSERT(!m_client.didDetectXSSForFrame);
1075             RELEASE_ASSERT(!m_client.didNewFirstVisuallyNonEmptyLayout_unavailable);
1076             RELEASE_ASSERT(!m_client.willGoToBackForwardListItem);
1077             RELEASE_ASSERT(!m_client.interactionOccurredWhileProcessUnresponsive);
1078             RELEASE_ASSERT(!m_client.pluginDidFail_deprecatedForUseWithV1);
1079             RELEASE_ASSERT(!m_client.didReceiveIntentForFrame_unavailable);
1080             RELEASE_ASSERT(!m_client.registerIntentServiceForFrame_unavailable);
1081             RELEASE_ASSERT(!m_client.pluginLoadPolicy_deprecatedForUseWithV2);
1082             RELEASE_ASSERT(!m_client.pluginDidFail);
1083             RELEASE_ASSERT(!m_client.pluginLoadPolicy);
1084             RELEASE_ASSERT(!m_client.webGLLoadPolicy);
1085             RELEASE_ASSERT(!m_client.resolveWebGLLoadPolicy);
1086             RELEASE_ASSERT(!m_client.navigationGestureDidBegin);
1087             RELEASE_ASSERT(!m_client.navigationGestureWillEnd);
1088             RELEASE_ASSERT(!m_client.navigationGestureDidEnd);
1089 #endif
1090         }
1091
1092     private:
1093         
1094         void didCommitLoadForFrame(WebPageProxy& page, WebFrameProxy& frame, API::Navigation*, API::Object* userData) override
1095         {
1096             if (!m_client.didCommitLoadForFrame)
1097                 return;
1098
1099             m_client.didCommitLoadForFrame(toAPI(&page), toAPI(&frame), toAPI(userData), m_client.base.clientInfo);
1100         }
1101         
1102         void didStartProvisionalLoadForFrame(WebPageProxy& page, WebFrameProxy& frame, API::Navigation*, API::Object* userData) override
1103         {
1104             if (!m_client.didStartProvisionalLoadForFrame)
1105                 return;
1106
1107             m_client.didStartProvisionalLoadForFrame(toAPI(&page), toAPI(&frame), toAPI(userData), m_client.base.clientInfo);
1108         }
1109
1110         void didReceiveServerRedirectForProvisionalLoadForFrame(WebPageProxy& page, WebFrameProxy& frame, API::Navigation*, API::Object* userData) override
1111         {
1112             if (!m_client.didReceiveServerRedirectForProvisionalLoadForFrame)
1113                 return;
1114
1115             m_client.didReceiveServerRedirectForProvisionalLoadForFrame(toAPI(&page), toAPI(&frame), toAPI(userData), m_client.base.clientInfo);
1116         }
1117
1118         void didFailProvisionalLoadWithErrorForFrame(WebPageProxy& page, WebFrameProxy& frame, API::Navigation*, const WebCore::ResourceError& error, API::Object* userData) override
1119         {
1120             if (!m_client.didFailProvisionalLoadWithErrorForFrame)
1121                 return;
1122
1123             m_client.didFailProvisionalLoadWithErrorForFrame(toAPI(&page), toAPI(&frame), toAPI(error), toAPI(userData), m_client.base.clientInfo);
1124         }
1125
1126         void didFinishLoadForFrame(WebPageProxy& page, WebFrameProxy& frame, API::Navigation*, API::Object* userData) override
1127         {
1128             if (!m_client.didFinishLoadForFrame)
1129                 return;
1130
1131             m_client.didFinishLoadForFrame(toAPI(&page), toAPI(&frame), toAPI(userData), m_client.base.clientInfo);
1132         }
1133
1134         void didFailLoadWithErrorForFrame(WebPageProxy& page, WebFrameProxy& frame, API::Navigation*, const WebCore::ResourceError& error, API::Object* userData) override
1135         {
1136             if (!m_client.didFailLoadWithErrorForFrame)
1137                 return;
1138
1139             m_client.didFailLoadWithErrorForFrame(toAPI(&page), toAPI(&frame), toAPI(error), toAPI(userData), m_client.base.clientInfo);
1140         }
1141
1142         void didFirstVisuallyNonEmptyLayoutForFrame(WebPageProxy& page, WebFrameProxy& frame, API::Object* userData) override
1143         {
1144             if (!m_client.didFirstVisuallyNonEmptyLayoutForFrame)
1145                 return;
1146
1147             m_client.didFirstVisuallyNonEmptyLayoutForFrame(toAPI(&page), toAPI(&frame), toAPI(userData), m_client.base.clientInfo);
1148         }
1149
1150         void didReachLayoutMilestone(WebPageProxy& page, OptionSet<WebCore::LayoutMilestone> milestones) override
1151         {
1152             if (!m_client.didLayout)
1153                 return;
1154
1155             m_client.didLayout(toAPI(&page), toWKLayoutMilestones(milestones), nullptr, m_client.base.clientInfo);
1156         }
1157
1158         bool processDidCrash(WebPageProxy& page) override
1159         {
1160             if (!m_client.processDidCrash)
1161                 return false;
1162
1163             m_client.processDidCrash(toAPI(&page), m_client.base.clientInfo);
1164             return true;
1165         }
1166
1167         void didChangeBackForwardList(WebPageProxy& page, WebBackForwardListItem* addedItem, Vector<Ref<WebBackForwardListItem>>&& removedItems) override
1168         {
1169             if (!m_client.didChangeBackForwardList)
1170                 return;
1171
1172             RefPtr<API::Array> removedItemsArray;
1173             if (!removedItems.isEmpty()) {
1174                 Vector<RefPtr<API::Object>> removedItemsVector;
1175                 removedItemsVector.reserveInitialCapacity(removedItems.size());
1176                 for (auto& removedItem : removedItems)
1177                 removedItemsVector.append(WTFMove(removedItem));
1178
1179                 removedItemsArray = API::Array::create(WTFMove(removedItemsVector));
1180             }
1181
1182             m_client.didChangeBackForwardList(toAPI(&page), toAPI(addedItem), toAPI(removedItemsArray.get()), m_client.base.clientInfo);
1183         }
1184         
1185         bool shouldKeepCurrentBackForwardListItemInList(WebKit::WebPageProxy& page, WebKit::WebBackForwardListItem& item) override
1186         {
1187             if (!m_client.shouldKeepCurrentBackForwardListItemInList)
1188                 return true;
1189
1190             return m_client.shouldKeepCurrentBackForwardListItemInList(toAPI(&page), toAPI(&item), m_client.base.clientInfo);
1191         }
1192     };
1193
1194     WebPageProxy* webPageProxy = toImpl(pageRef);
1195
1196     auto loaderClient = std::make_unique<LoaderClient>(wkClient);
1197
1198     // It would be nice to get rid of this code and transition all clients to using didLayout instead of
1199     // didFirstLayoutInFrame and didFirstVisuallyNonEmptyLayoutInFrame. In the meantime, this is required
1200     // for backwards compatibility.
1201     OptionSet<WebCore::LayoutMilestone> milestones;
1202     if (loaderClient->client().didFirstLayoutForFrame)
1203         milestones.add(WebCore::DidFirstLayout);
1204     if (loaderClient->client().didFirstVisuallyNonEmptyLayoutForFrame)
1205         milestones.add(WebCore::DidFirstVisuallyNonEmptyLayout);
1206
1207     if (milestones)
1208         webPageProxy->process().send(Messages::WebPage::ListenForLayoutMilestones(milestones), webPageProxy->pageID());
1209
1210     webPageProxy->setLoaderClient(WTFMove(loaderClient));
1211 }
1212
1213 void WKPageSetPagePolicyClient(WKPageRef pageRef, const WKPagePolicyClientBase* wkClient)
1214 {
1215     class PolicyClient : public API::Client<WKPagePolicyClientBase>, public API::PolicyClient {
1216     public:
1217         explicit PolicyClient(const WKPagePolicyClientBase* client)
1218         {
1219             initialize(client);
1220         }
1221
1222     private:
1223         void decidePolicyForNavigationAction(WebPageProxy& page, WebFrameProxy* frame, const NavigationActionData& navigationActionData, WebFrameProxy* originatingFrame, const WebCore::ResourceRequest& originalResourceRequest, const WebCore::ResourceRequest& resourceRequest, Ref<WebFramePolicyListenerProxy>&& listener, API::Object* userData) override
1224         {
1225             if (!m_client.decidePolicyForNavigationAction_deprecatedForUseWithV0 && !m_client.decidePolicyForNavigationAction_deprecatedForUseWithV1 && !m_client.decidePolicyForNavigationAction) {
1226                 listener->use();
1227                 return;
1228             }
1229
1230             Ref<API::URLRequest> originalRequest = API::URLRequest::create(originalResourceRequest);
1231             Ref<API::URLRequest> request = API::URLRequest::create(resourceRequest);
1232
1233             if (m_client.decidePolicyForNavigationAction_deprecatedForUseWithV0)
1234                 m_client.decidePolicyForNavigationAction_deprecatedForUseWithV0(toAPI(&page), toAPI(frame), toAPI(navigationActionData.navigationType), toAPI(navigationActionData.modifiers), toAPI(navigationActionData.mouseButton), toAPI(request.ptr()), toAPI(listener.ptr()), toAPI(userData), m_client.base.clientInfo);
1235             else if (m_client.decidePolicyForNavigationAction_deprecatedForUseWithV1)
1236                 m_client.decidePolicyForNavigationAction_deprecatedForUseWithV1(toAPI(&page), toAPI(frame), toAPI(navigationActionData.navigationType), toAPI(navigationActionData.modifiers), toAPI(navigationActionData.mouseButton), toAPI(originatingFrame), toAPI(request.ptr()), toAPI(listener.ptr()), toAPI(userData), m_client.base.clientInfo);
1237             else
1238                 m_client.decidePolicyForNavigationAction(toAPI(&page), toAPI(frame), toAPI(navigationActionData.navigationType), toAPI(navigationActionData.modifiers), toAPI(navigationActionData.mouseButton), toAPI(originatingFrame), toAPI(originalRequest.ptr()), toAPI(request.ptr()), toAPI(listener.ptr()), toAPI(userData), m_client.base.clientInfo);
1239         }
1240
1241         void decidePolicyForNewWindowAction(WebPageProxy& page, WebFrameProxy& frame, const NavigationActionData& navigationActionData, const WebCore::ResourceRequest& resourceRequest, const String& frameName, Ref<WebFramePolicyListenerProxy>&& listener, API::Object* userData) override
1242         {
1243             if (!m_client.decidePolicyForNewWindowAction) {
1244                 listener->use();
1245                 return;
1246             }
1247
1248             Ref<API::URLRequest> request = API::URLRequest::create(resourceRequest);
1249
1250             m_client.decidePolicyForNewWindowAction(toAPI(&page), toAPI(&frame), toAPI(navigationActionData.navigationType), toAPI(navigationActionData.modifiers), toAPI(navigationActionData.mouseButton), toAPI(request.ptr()), toAPI(frameName.impl()), toAPI(listener.ptr()), toAPI(userData), m_client.base.clientInfo);
1251         }
1252
1253         void decidePolicyForResponse(WebPageProxy& page, WebFrameProxy& frame, const WebCore::ResourceResponse& resourceResponse, const WebCore::ResourceRequest& resourceRequest, bool canShowMIMEType, Ref<WebFramePolicyListenerProxy>&& listener, API::Object* userData) override
1254         {
1255             if (!m_client.decidePolicyForResponse_deprecatedForUseWithV0 && !m_client.decidePolicyForResponse) {
1256                 listener->use();
1257                 return;
1258             }
1259
1260             Ref<API::URLResponse> response = API::URLResponse::create(resourceResponse);
1261             Ref<API::URLRequest> request = API::URLRequest::create(resourceRequest);
1262
1263             if (m_client.decidePolicyForResponse_deprecatedForUseWithV0)
1264                 m_client.decidePolicyForResponse_deprecatedForUseWithV0(toAPI(&page), toAPI(&frame), toAPI(response.ptr()), toAPI(request.ptr()), toAPI(listener.ptr()), toAPI(userData), m_client.base.clientInfo);
1265             else
1266                 m_client.decidePolicyForResponse(toAPI(&page), toAPI(&frame), toAPI(response.ptr()), toAPI(request.ptr()), canShowMIMEType, toAPI(listener.ptr()), toAPI(userData), m_client.base.clientInfo);
1267         }
1268
1269         void unableToImplementPolicy(WebPageProxy& page, WebFrameProxy& frame, const WebCore::ResourceError& error, API::Object* userData) override
1270         {
1271             if (!m_client.unableToImplementPolicy)
1272                 return;
1273             
1274             m_client.unableToImplementPolicy(toAPI(&page), toAPI(&frame), toAPI(error), toAPI(userData), m_client.base.clientInfo);
1275         }
1276     };
1277
1278     toImpl(pageRef)->setPolicyClient(std::make_unique<PolicyClient>(wkClient));
1279 }
1280
1281 namespace WebKit {
1282 using namespace WebCore;
1283     
1284 class RunBeforeUnloadConfirmPanelResultListener : public API::ObjectImpl<API::Object::Type::RunBeforeUnloadConfirmPanelResultListener> {
1285 public:
1286     static Ref<RunBeforeUnloadConfirmPanelResultListener> create(Function<void(bool)>&& completionHandler)
1287     {
1288         return adoptRef(*new RunBeforeUnloadConfirmPanelResultListener(WTFMove(completionHandler)));
1289     }
1290
1291     virtual ~RunBeforeUnloadConfirmPanelResultListener()
1292     {
1293     }
1294
1295     void call(bool result)
1296     {
1297         m_completionHandler(result);
1298     }
1299
1300 private:
1301     explicit RunBeforeUnloadConfirmPanelResultListener(Function<void (bool)>&& completionHandler)
1302         : m_completionHandler(WTFMove(completionHandler))
1303     {
1304     }
1305
1306     Function<void (bool)> m_completionHandler;
1307 };
1308
1309 class RunJavaScriptAlertResultListener : public API::ObjectImpl<API::Object::Type::RunJavaScriptAlertResultListener> {
1310 public:
1311     static Ref<RunJavaScriptAlertResultListener> create(Function<void()>&& completionHandler)
1312     {
1313         return adoptRef(*new RunJavaScriptAlertResultListener(WTFMove(completionHandler)));
1314     }
1315
1316     virtual ~RunJavaScriptAlertResultListener()
1317     {
1318     }
1319
1320     void call()
1321     {
1322         m_completionHandler();
1323     }
1324
1325 private:
1326     explicit RunJavaScriptAlertResultListener(Function<void ()>&& completionHandler)
1327         : m_completionHandler(WTFMove(completionHandler))
1328     {
1329     }
1330     
1331     Function<void ()> m_completionHandler;
1332 };
1333
1334 class RunJavaScriptConfirmResultListener : public API::ObjectImpl<API::Object::Type::RunJavaScriptConfirmResultListener> {
1335 public:
1336     static Ref<RunJavaScriptConfirmResultListener> create(Function<void(bool)>&& completionHandler)
1337     {
1338         return adoptRef(*new RunJavaScriptConfirmResultListener(WTFMove(completionHandler)));
1339     }
1340
1341     virtual ~RunJavaScriptConfirmResultListener()
1342     {
1343     }
1344
1345     void call(bool result)
1346     {
1347         m_completionHandler(result);
1348     }
1349
1350 private:
1351     explicit RunJavaScriptConfirmResultListener(Function<void(bool)>&& completionHandler)
1352         : m_completionHandler(WTFMove(completionHandler))
1353     {
1354     }
1355
1356     Function<void (bool)> m_completionHandler;
1357 };
1358
1359 class RunJavaScriptPromptResultListener : public API::ObjectImpl<API::Object::Type::RunJavaScriptPromptResultListener> {
1360 public:
1361     static Ref<RunJavaScriptPromptResultListener> create(Function<void(const String&)>&& completionHandler)
1362     {
1363         return adoptRef(*new RunJavaScriptPromptResultListener(WTFMove(completionHandler)));
1364     }
1365
1366     virtual ~RunJavaScriptPromptResultListener()
1367     {
1368     }
1369
1370     void call(const String& result)
1371     {
1372         m_completionHandler(result);
1373     }
1374
1375 private:
1376     explicit RunJavaScriptPromptResultListener(Function<void(const String&)>&& completionHandler)
1377         : m_completionHandler(WTFMove(completionHandler))
1378     {
1379     }
1380
1381     Function<void (const String&)> m_completionHandler;
1382 };
1383
1384 class RequestStorageAccessConfirmResultListener : public API::ObjectImpl<API::Object::Type::RequestStorageAccessConfirmResultListener> {
1385 public:
1386     static Ref<RequestStorageAccessConfirmResultListener> create(CompletionHandler<void(bool)>&& completionHandler)
1387     {
1388         return adoptRef(*new RequestStorageAccessConfirmResultListener(WTFMove(completionHandler)));
1389     }
1390     
1391     virtual ~RequestStorageAccessConfirmResultListener()
1392     {
1393     }
1394     
1395     void call(bool result)
1396     {
1397         m_completionHandler(result);
1398     }
1399     
1400 private:
1401     explicit RequestStorageAccessConfirmResultListener(CompletionHandler<void(bool)>&& completionHandler)
1402         : m_completionHandler(WTFMove(completionHandler))
1403     {
1404     }
1405     
1406     CompletionHandler<void(bool)> m_completionHandler;
1407 };
1408
1409 WK_ADD_API_MAPPING(WKPageRunBeforeUnloadConfirmPanelResultListenerRef, RunBeforeUnloadConfirmPanelResultListener)
1410 WK_ADD_API_MAPPING(WKPageRunJavaScriptAlertResultListenerRef, RunJavaScriptAlertResultListener)
1411 WK_ADD_API_MAPPING(WKPageRunJavaScriptConfirmResultListenerRef, RunJavaScriptConfirmResultListener)
1412 WK_ADD_API_MAPPING(WKPageRunJavaScriptPromptResultListenerRef, RunJavaScriptPromptResultListener)
1413 WK_ADD_API_MAPPING(WKPageRequestStorageAccessConfirmResultListenerRef, RequestStorageAccessConfirmResultListener)
1414
1415 }
1416
1417 WKTypeID WKPageRunBeforeUnloadConfirmPanelResultListenerGetTypeID()
1418 {
1419     return toAPI(RunBeforeUnloadConfirmPanelResultListener::APIType);
1420 }
1421
1422 void WKPageRunBeforeUnloadConfirmPanelResultListenerCall(WKPageRunBeforeUnloadConfirmPanelResultListenerRef listener, bool result)
1423 {
1424     toImpl(listener)->call(result);
1425 }
1426
1427 WKTypeID WKPageRunJavaScriptAlertResultListenerGetTypeID()
1428 {
1429     return toAPI(RunJavaScriptAlertResultListener::APIType);
1430 }
1431
1432 void WKPageRunJavaScriptAlertResultListenerCall(WKPageRunJavaScriptAlertResultListenerRef listener)
1433 {
1434     toImpl(listener)->call();
1435 }
1436
1437 WKTypeID WKPageRunJavaScriptConfirmResultListenerGetTypeID()
1438 {
1439     return toAPI(RunJavaScriptConfirmResultListener::APIType);
1440 }
1441
1442 void WKPageRunJavaScriptConfirmResultListenerCall(WKPageRunJavaScriptConfirmResultListenerRef listener, bool result)
1443 {
1444     toImpl(listener)->call(result);
1445 }
1446
1447 WKTypeID WKPageRunJavaScriptPromptResultListenerGetTypeID()
1448 {
1449     return toAPI(RunJavaScriptPromptResultListener::APIType);
1450 }
1451
1452 void WKPageRunJavaScriptPromptResultListenerCall(WKPageRunJavaScriptPromptResultListenerRef listener, WKStringRef result)
1453 {
1454     toImpl(listener)->call(toWTFString(result));
1455 }
1456
1457 WKTypeID WKPageRequestStorageAccessConfirmResultListenerGetTypeID()
1458 {
1459     return toAPI(RequestStorageAccessConfirmResultListener::APIType);
1460 }
1461
1462 void WKPageRequestStorageAccessConfirmResultListenerCall(WKPageRequestStorageAccessConfirmResultListenerRef listener, bool result)
1463 {
1464     toImpl(listener)->call(result);
1465 }
1466
1467 void WKPageSetPageUIClient(WKPageRef pageRef, const WKPageUIClientBase* wkClient)
1468 {
1469     class UIClient : public API::Client<WKPageUIClientBase>, public API::UIClient {
1470     public:
1471         explicit UIClient(const WKPageUIClientBase* client)
1472         {
1473             initialize(client);
1474         }
1475
1476     private:
1477         void createNewPage(WebPageProxy& page, Ref<API::FrameInfo>&& sourceFrameInfo, WebCore::ResourceRequest&& resourceRequest, WebCore::WindowFeatures&& windowFeatures, NavigationActionData&& navigationActionData, CompletionHandler<void(RefPtr<WebPageProxy>&&)>&& completionHandler) final
1478         {
1479             if (m_client.createNewPage) {
1480                 auto configuration = page.configuration().copy();
1481                 configuration->setRelatedPage(&page);
1482
1483                 auto userInitiatedActivity = page.process().userInitiatedActivity(navigationActionData.userGestureTokenIdentifier);
1484                 bool shouldOpenAppLinks = !hostsAreEqual(sourceFrameInfo->request().url(), resourceRequest.url());
1485                 auto apiNavigationAction = API::NavigationAction::create(WTFMove(navigationActionData), sourceFrameInfo.ptr(), nullptr, WTF::nullopt, WTFMove(resourceRequest), URL(), shouldOpenAppLinks, WTFMove(userInitiatedActivity));
1486
1487                 auto apiWindowFeatures = API::WindowFeatures::create(windowFeatures);
1488
1489                 return completionHandler(adoptRef(toImpl(m_client.createNewPage(toAPI(&page), toAPI(configuration.ptr()), toAPI(apiNavigationAction.ptr()), toAPI(apiWindowFeatures.ptr()), m_client.base.clientInfo))));
1490             }
1491         
1492             if (m_client.createNewPage_deprecatedForUseWithV1 || m_client.createNewPage_deprecatedForUseWithV0) {
1493                 API::Dictionary::MapType map;
1494                 if (windowFeatures.x)
1495                     map.set("x", API::Double::create(*windowFeatures.x));
1496                 if (windowFeatures.y)
1497                     map.set("y", API::Double::create(*windowFeatures.y));
1498                 if (windowFeatures.width)
1499                     map.set("width", API::Double::create(*windowFeatures.width));
1500                 if (windowFeatures.height)
1501                     map.set("height", API::Double::create(*windowFeatures.height));
1502                 map.set("menuBarVisible", API::Boolean::create(windowFeatures.menuBarVisible));
1503                 map.set("statusBarVisible", API::Boolean::create(windowFeatures.statusBarVisible));
1504                 map.set("toolBarVisible", API::Boolean::create(windowFeatures.toolBarVisible));
1505                 map.set("locationBarVisible", API::Boolean::create(windowFeatures.locationBarVisible));
1506                 map.set("scrollbarsVisible", API::Boolean::create(windowFeatures.scrollbarsVisible));
1507                 map.set("resizable", API::Boolean::create(windowFeatures.resizable));
1508                 map.set("fullscreen", API::Boolean::create(windowFeatures.fullscreen));
1509                 map.set("dialog", API::Boolean::create(windowFeatures.dialog));
1510                 Ref<API::Dictionary> featuresMap = API::Dictionary::create(WTFMove(map));
1511
1512                 if (m_client.createNewPage_deprecatedForUseWithV1) {
1513                     Ref<API::URLRequest> request = API::URLRequest::create(resourceRequest);
1514                     return completionHandler(adoptRef(toImpl(m_client.createNewPage_deprecatedForUseWithV1(toAPI(&page), toAPI(request.ptr()), toAPI(featuresMap.ptr()), toAPI(navigationActionData.modifiers), toAPI(navigationActionData.mouseButton), m_client.base.clientInfo))));
1515                 }
1516     
1517                 ASSERT(m_client.createNewPage_deprecatedForUseWithV0);
1518                 return completionHandler(adoptRef(toImpl(m_client.createNewPage_deprecatedForUseWithV0(toAPI(&page), toAPI(featuresMap.ptr()), toAPI(navigationActionData.modifiers), toAPI(navigationActionData.mouseButton), m_client.base.clientInfo))));
1519             }
1520
1521             completionHandler(nullptr);
1522         }
1523
1524         void showPage(WebPageProxy* page) final
1525         {
1526             if (!m_client.showPage)
1527                 return;
1528
1529             m_client.showPage(toAPI(page), m_client.base.clientInfo);
1530         }
1531
1532         void fullscreenMayReturnToInline(WebPageProxy* page) final
1533         {
1534             if (!m_client.fullscreenMayReturnToInline)
1535                 return;
1536
1537             m_client.fullscreenMayReturnToInline(toAPI(page), m_client.base.clientInfo);
1538         }
1539         
1540         void hasVideoInPictureInPictureDidChange(WebPageProxy* page, bool hasVideoInPictureInPicture) final
1541         {
1542             if (!m_client.hasVideoInPictureInPictureDidChange)
1543                 return;
1544             
1545             m_client.hasVideoInPictureInPictureDidChange(toAPI(page), hasVideoInPictureInPicture, m_client.base.clientInfo);
1546         }
1547
1548         void didExceedBackgroundResourceLimitWhileInForeground(WebPageProxy& page, WKResourceLimit limit) final
1549         {
1550             if (!m_client.didExceedBackgroundResourceLimitWhileInForeground)
1551                 return;
1552
1553             m_client.didExceedBackgroundResourceLimitWhileInForeground(toAPI(&page), limit, m_client.base.clientInfo);
1554         }
1555
1556         void close(WebPageProxy* page) final
1557         {
1558             if (!m_client.close)
1559                 return;
1560
1561             m_client.close(toAPI(page), m_client.base.clientInfo);
1562         }
1563
1564         bool takeFocus(WebPageProxy* page, WKFocusDirection direction) final
1565         {
1566             if (!m_client.takeFocus)
1567                 return false;
1568
1569             m_client.takeFocus(toAPI(page), direction, m_client.base.clientInfo);
1570             return true;
1571         }
1572
1573         void focus(WebPageProxy* page) final
1574         {
1575             if (!m_client.focus)
1576                 return;
1577
1578             m_client.focus(toAPI(page), m_client.base.clientInfo);
1579         }
1580
1581         void unfocus(WebPageProxy* page) final
1582         {
1583             if (!m_client.unfocus)
1584                 return;
1585
1586             m_client.unfocus(toAPI(page), m_client.base.clientInfo);
1587         }
1588
1589         void runJavaScriptAlert(WebPageProxy* page, const String& message, WebFrameProxy* frame, const SecurityOriginData& securityOriginData, Function<void()>&& completionHandler) final
1590         {
1591             if (m_client.runJavaScriptAlert) {
1592                 RefPtr<RunJavaScriptAlertResultListener> listener = RunJavaScriptAlertResultListener::create(WTFMove(completionHandler));
1593                 RefPtr<API::SecurityOrigin> securityOrigin = API::SecurityOrigin::create(securityOriginData.protocol, securityOriginData.host, securityOriginData.port);
1594                 m_client.runJavaScriptAlert(toAPI(page), toAPI(message.impl()), toAPI(frame), toAPI(securityOrigin.get()), toAPI(listener.get()), m_client.base.clientInfo);
1595                 return;
1596             }
1597
1598             if (m_client.runJavaScriptAlert_deprecatedForUseWithV5) {
1599                 RefPtr<API::SecurityOrigin> securityOrigin = API::SecurityOrigin::create(securityOriginData.protocol, securityOriginData.host, securityOriginData.port);
1600                 m_client.runJavaScriptAlert_deprecatedForUseWithV5(toAPI(page), toAPI(message.impl()), toAPI(frame), toAPI(securityOrigin.get()), m_client.base.clientInfo);
1601                 completionHandler();
1602                 return;
1603             }
1604             
1605             if (m_client.runJavaScriptAlert_deprecatedForUseWithV0) {
1606                 m_client.runJavaScriptAlert_deprecatedForUseWithV0(toAPI(page), toAPI(message.impl()), toAPI(frame), m_client.base.clientInfo);
1607                 completionHandler();
1608                 return;
1609             }
1610
1611
1612             completionHandler();
1613         }
1614
1615         void runJavaScriptConfirm(WebPageProxy* page, const String& message, WebFrameProxy* frame, const SecurityOriginData& securityOriginData, Function<void(bool)>&& completionHandler) final
1616         {
1617             if (m_client.runJavaScriptConfirm) {
1618                 RefPtr<RunJavaScriptConfirmResultListener> listener = RunJavaScriptConfirmResultListener::create(WTFMove(completionHandler));
1619                 RefPtr<API::SecurityOrigin> securityOrigin = API::SecurityOrigin::create(securityOriginData.protocol, securityOriginData.host, securityOriginData.port);
1620                 m_client.runJavaScriptConfirm(toAPI(page), toAPI(message.impl()), toAPI(frame), toAPI(securityOrigin.get()), toAPI(listener.get()), m_client.base.clientInfo);
1621                 return;
1622             }
1623
1624             if (m_client.runJavaScriptConfirm_deprecatedForUseWithV5) {
1625                 RefPtr<API::SecurityOrigin> securityOrigin = API::SecurityOrigin::create(securityOriginData.protocol, securityOriginData.host, securityOriginData.port);
1626                 bool result = m_client.runJavaScriptConfirm_deprecatedForUseWithV5(toAPI(page), toAPI(message.impl()), toAPI(frame), toAPI(securityOrigin.get()), m_client.base.clientInfo);
1627                 
1628                 completionHandler(result);
1629                 return;
1630             }
1631             
1632             if (m_client.runJavaScriptConfirm_deprecatedForUseWithV0) {
1633                 bool result = m_client.runJavaScriptConfirm_deprecatedForUseWithV0(toAPI(page), toAPI(message.impl()), toAPI(frame), m_client.base.clientInfo);
1634
1635                 completionHandler(result);
1636                 return;
1637             }
1638             
1639             completionHandler(false);
1640         }
1641
1642         void runJavaScriptPrompt(WebPageProxy* page, const String& message, const String& defaultValue, WebFrameProxy* frame, const SecurityOriginData& securityOriginData, Function<void(const String&)>&& completionHandler) final
1643         {
1644             if (m_client.runJavaScriptPrompt) {
1645                 RefPtr<RunJavaScriptPromptResultListener> listener = RunJavaScriptPromptResultListener::create(WTFMove(completionHandler));
1646                 RefPtr<API::SecurityOrigin> securityOrigin = API::SecurityOrigin::create(securityOriginData.protocol, securityOriginData.host, securityOriginData.port);
1647                 m_client.runJavaScriptPrompt(toAPI(page), toAPI(message.impl()), toAPI(defaultValue.impl()), toAPI(frame), toAPI(securityOrigin.get()), toAPI(listener.get()), m_client.base.clientInfo);
1648                 return;
1649             }
1650
1651             if (m_client.runJavaScriptPrompt_deprecatedForUseWithV5) {
1652                 RefPtr<API::SecurityOrigin> securityOrigin = API::SecurityOrigin::create(securityOriginData.protocol, securityOriginData.host, securityOriginData.port);
1653                 RefPtr<API::String> string = adoptRef(toImpl(m_client.runJavaScriptPrompt_deprecatedForUseWithV5(toAPI(page), toAPI(message.impl()), toAPI(defaultValue.impl()), toAPI(frame), toAPI(securityOrigin.get()), m_client.base.clientInfo)));
1654                 
1655                 if (string)
1656                     completionHandler(string->string());
1657                 else
1658                     completionHandler(String());
1659                 return;
1660             }
1661             
1662             if (m_client.runJavaScriptPrompt_deprecatedForUseWithV0) {
1663                 RefPtr<API::String> string = adoptRef(toImpl(m_client.runJavaScriptPrompt_deprecatedForUseWithV0(toAPI(page), toAPI(message.impl()), toAPI(defaultValue.impl()), toAPI(frame), m_client.base.clientInfo)));
1664                 
1665                 if (string)
1666                     completionHandler(string->string());
1667                 else
1668                     completionHandler(String());
1669                 return;
1670             }
1671
1672             completionHandler(String());
1673         }
1674
1675         void setStatusText(WebPageProxy* page, const String& text) final
1676         {
1677             if (!m_client.setStatusText)
1678                 return;
1679
1680             m_client.setStatusText(toAPI(page), toAPI(text.impl()), m_client.base.clientInfo);
1681         }
1682
1683         void mouseDidMoveOverElement(WebPageProxy& page, const WebHitTestResultData& data, OptionSet<WebKit::WebEvent::Modifier> modifiers, API::Object* userData) final
1684         {
1685             if (!m_client.mouseDidMoveOverElement && !m_client.mouseDidMoveOverElement_deprecatedForUseWithV0)
1686                 return;
1687
1688             if (m_client.base.version > 0 && !m_client.mouseDidMoveOverElement)
1689                 return;
1690
1691             if (!m_client.base.version) {
1692                 m_client.mouseDidMoveOverElement_deprecatedForUseWithV0(toAPI(&page), toAPI(modifiers), toAPI(userData), m_client.base.clientInfo);
1693                 return;
1694             }
1695
1696             auto apiHitTestResult = API::HitTestResult::create(data);
1697             m_client.mouseDidMoveOverElement(toAPI(&page), toAPI(apiHitTestResult.ptr()), toAPI(modifiers), toAPI(userData), m_client.base.clientInfo);
1698         }
1699
1700 #if ENABLE(NETSCAPE_PLUGIN_API)
1701         void unavailablePluginButtonClicked(WebPageProxy& page, WKPluginUnavailabilityReason pluginUnavailabilityReason, API::Dictionary& pluginInformation) final
1702         {
1703             if (pluginUnavailabilityReason == kWKPluginUnavailabilityReasonPluginMissing) {
1704                 if (m_client.missingPluginButtonClicked_deprecatedForUseWithV0)
1705                     m_client.missingPluginButtonClicked_deprecatedForUseWithV0(
1706                         toAPI(&page),
1707                         toAPI(pluginInformation.get<API::String>(pluginInformationMIMETypeKey())),
1708                         toAPI(pluginInformation.get<API::String>(pluginInformationPluginURLKey())),
1709                         toAPI(pluginInformation.get<API::String>(pluginInformationPluginspageAttributeURLKey())),
1710                         m_client.base.clientInfo);
1711             }
1712
1713             if (m_client.unavailablePluginButtonClicked_deprecatedForUseWithV1)
1714                 m_client.unavailablePluginButtonClicked_deprecatedForUseWithV1(
1715                     toAPI(&page),
1716                     pluginUnavailabilityReason,
1717                     toAPI(pluginInformation.get<API::String>(pluginInformationMIMETypeKey())),
1718                     toAPI(pluginInformation.get<API::String>(pluginInformationPluginURLKey())),
1719                     toAPI(pluginInformation.get<API::String>(pluginInformationPluginspageAttributeURLKey())),
1720                     m_client.base.clientInfo);
1721
1722             if (m_client.unavailablePluginButtonClicked)
1723                 m_client.unavailablePluginButtonClicked(
1724                     toAPI(&page),
1725                     pluginUnavailabilityReason,
1726                     toAPI(&pluginInformation),
1727                     m_client.base.clientInfo);
1728         }
1729 #endif // ENABLE(NETSCAPE_PLUGIN_API)
1730
1731         void didNotHandleKeyEvent(WebPageProxy* page, const NativeWebKeyboardEvent& event) final
1732         {
1733             if (!m_client.didNotHandleKeyEvent)
1734                 return;
1735             m_client.didNotHandleKeyEvent(toAPI(page), event.nativeEvent(), m_client.base.clientInfo);
1736         }
1737
1738         void didNotHandleWheelEvent(WebPageProxy* page, const NativeWebWheelEvent& event) final
1739         {
1740             if (!m_client.didNotHandleWheelEvent)
1741                 return;
1742             m_client.didNotHandleWheelEvent(toAPI(page), event.nativeEvent(), m_client.base.clientInfo);
1743         }
1744
1745         void toolbarsAreVisible(WebPageProxy& page, Function<void(bool)>&& completionHandler) final
1746         {
1747             if (!m_client.toolbarsAreVisible)
1748                 return completionHandler(true);
1749             completionHandler(m_client.toolbarsAreVisible(toAPI(&page), m_client.base.clientInfo));
1750         }
1751
1752         void setToolbarsAreVisible(WebPageProxy& page, bool visible) final
1753         {
1754             if (!m_client.setToolbarsAreVisible)
1755                 return;
1756             m_client.setToolbarsAreVisible(toAPI(&page), visible, m_client.base.clientInfo);
1757         }
1758
1759         void menuBarIsVisible(WebPageProxy& page, Function<void(bool)>&& completionHandler) final
1760         {
1761             if (!m_client.menuBarIsVisible)
1762                 return completionHandler(true);
1763             completionHandler(m_client.menuBarIsVisible(toAPI(&page), m_client.base.clientInfo));
1764         }
1765
1766         void setMenuBarIsVisible(WebPageProxy& page, bool visible) final
1767         {
1768             if (!m_client.setMenuBarIsVisible)
1769                 return;
1770             m_client.setMenuBarIsVisible(toAPI(&page), visible, m_client.base.clientInfo);
1771         }
1772
1773         void statusBarIsVisible(WebPageProxy& page, Function<void(bool)>&& completionHandler) final
1774         {
1775             if (!m_client.statusBarIsVisible)
1776                 return completionHandler(true);
1777             completionHandler(m_client.statusBarIsVisible(toAPI(&page), m_client.base.clientInfo));
1778         }
1779
1780         void setStatusBarIsVisible(WebPageProxy& page, bool visible) final
1781         {
1782             if (!m_client.setStatusBarIsVisible)
1783                 return;
1784             m_client.setStatusBarIsVisible(toAPI(&page), visible, m_client.base.clientInfo);
1785         }
1786
1787         void setIsResizable(WebPageProxy& page, bool resizable) final
1788         {
1789             if (!m_client.setIsResizable)
1790                 return;
1791             m_client.setIsResizable(toAPI(&page), resizable, m_client.base.clientInfo);
1792         }
1793
1794         void setWindowFrame(WebPageProxy& page, const FloatRect& frame) final
1795         {
1796             if (!m_client.setWindowFrame)
1797                 return;
1798
1799             m_client.setWindowFrame(toAPI(&page), toAPI(frame), m_client.base.clientInfo);
1800         }
1801
1802         void windowFrame(WebPageProxy& page, Function<void(WebCore::FloatRect)>&& completionHandler) final
1803         {
1804             if (!m_client.getWindowFrame)
1805                 return completionHandler({ });
1806
1807             completionHandler(toFloatRect(m_client.getWindowFrame(toAPI(&page), m_client.base.clientInfo)));
1808         }
1809
1810         bool canRunBeforeUnloadConfirmPanel() const final
1811         {
1812             return m_client.runBeforeUnloadConfirmPanel_deprecatedForUseWithV6 || m_client.runBeforeUnloadConfirmPanel;
1813         }
1814
1815         void runBeforeUnloadConfirmPanel(WebKit::WebPageProxy* page, const WTF::String& message, WebKit::WebFrameProxy* frame, const SecurityOriginData&, Function<void(bool)>&& completionHandler) final
1816         {
1817             if (m_client.runBeforeUnloadConfirmPanel) {
1818                 RefPtr<RunBeforeUnloadConfirmPanelResultListener> listener = RunBeforeUnloadConfirmPanelResultListener::create(WTFMove(completionHandler));
1819                 m_client.runBeforeUnloadConfirmPanel(toAPI(page), toAPI(message.impl()), toAPI(frame), toAPI(listener.get()), m_client.base.clientInfo);
1820                 return;
1821             }
1822
1823             if (m_client.runBeforeUnloadConfirmPanel_deprecatedForUseWithV6) {
1824                 bool result = m_client.runBeforeUnloadConfirmPanel_deprecatedForUseWithV6(toAPI(page), toAPI(message.impl()), toAPI(frame), m_client.base.clientInfo);
1825                 completionHandler(result);
1826                 return;
1827             }
1828
1829             completionHandler(true);
1830         }
1831
1832         void pageDidScroll(WebPageProxy* page) final
1833         {
1834             if (!m_client.pageDidScroll)
1835                 return;
1836
1837             m_client.pageDidScroll(toAPI(page), m_client.base.clientInfo);
1838         }
1839
1840         void exceededDatabaseQuota(WebPageProxy* page, WebFrameProxy* frame, API::SecurityOrigin* origin, const String& databaseName, const String& databaseDisplayName, unsigned long long currentQuota, unsigned long long currentOriginUsage, unsigned long long currentDatabaseUsage, unsigned long long expectedUsage, Function<void(unsigned long long)>&& completionHandler) final
1841         {
1842             if (!m_client.exceededDatabaseQuota) {
1843                 completionHandler(currentQuota);
1844                 return;
1845             }
1846
1847             completionHandler(m_client.exceededDatabaseQuota(toAPI(page), toAPI(frame), toAPI(origin), toAPI(databaseName.impl()), toAPI(databaseDisplayName.impl()), currentQuota, currentOriginUsage, currentDatabaseUsage, expectedUsage, m_client.base.clientInfo));
1848         }
1849
1850         bool runOpenPanel(WebPageProxy* page, WebFrameProxy* frame, const WebCore::SecurityOriginData&, API::OpenPanelParameters* parameters, WebOpenPanelResultListenerProxy* listener) final
1851         {
1852             if (!m_client.runOpenPanel)
1853                 return false;
1854
1855             m_client.runOpenPanel(toAPI(page), toAPI(frame), toAPI(parameters), toAPI(listener), m_client.base.clientInfo);
1856             return true;
1857         }
1858
1859         void decidePolicyForGeolocationPermissionRequest(WebPageProxy& page, WebFrameProxy& frame, API::SecurityOrigin& origin, Function<void(bool)>& completionHandler) final
1860         {
1861             if (!m_client.decidePolicyForGeolocationPermissionRequest)
1862                 return;
1863
1864             m_client.decidePolicyForGeolocationPermissionRequest(toAPI(&page), toAPI(&frame), toAPI(&origin), toAPI(GeolocationPermissionRequest::create(std::exchange(completionHandler, nullptr)).ptr()), m_client.base.clientInfo);
1865         }
1866
1867         void decidePolicyForUserMediaPermissionRequest(WebPageProxy& page, WebFrameProxy& frame, API::SecurityOrigin& userMediaDocumentOrigin, API::SecurityOrigin& topLevelDocumentOrigin, UserMediaPermissionRequestProxy& permissionRequest) final
1868         {
1869             if (!m_client.decidePolicyForUserMediaPermissionRequest) {
1870                 permissionRequest.deny();
1871                 return;
1872             }
1873
1874             m_client.decidePolicyForUserMediaPermissionRequest(toAPI(&page), toAPI(&frame), toAPI(&userMediaDocumentOrigin), toAPI(&topLevelDocumentOrigin), toAPI(&permissionRequest), m_client.base.clientInfo);
1875         }
1876
1877         void checkUserMediaPermissionForOrigin(WebPageProxy& page, WebFrameProxy& frame, API::SecurityOrigin& userMediaDocumentOrigin, API::SecurityOrigin& topLevelDocumentOrigin, UserMediaPermissionCheckProxy& request) final
1878         {
1879             if (!m_client.checkUserMediaPermissionForOrigin) {
1880                 request.deny();
1881                 return;
1882             }
1883
1884             m_client.checkUserMediaPermissionForOrigin(toAPI(&page), toAPI(&frame), toAPI(&userMediaDocumentOrigin), toAPI(&topLevelDocumentOrigin), toAPI(&request), m_client.base.clientInfo);
1885         }
1886         
1887         void decidePolicyForNotificationPermissionRequest(WebPageProxy& page, API::SecurityOrigin& origin, Function<void(bool)>&& completionHandler) final
1888         {
1889             if (!m_client.decidePolicyForNotificationPermissionRequest)
1890                 return completionHandler(false);
1891
1892             m_client.decidePolicyForNotificationPermissionRequest(toAPI(&page), toAPI(&origin), toAPI(NotificationPermissionRequest::create(WTFMove(completionHandler)).ptr()), m_client.base.clientInfo);
1893         }
1894
1895         void requestStorageAccessConfirm(WebPageProxy& page, WebFrameProxy* frame, const WTF::String& requestingDomain, const WTF::String& currentDomain, CompletionHandler<void(bool)>&& completionHandler) final
1896         {
1897             if (!m_client.requestStorageAccessConfirm) {
1898                 completionHandler(true);
1899                 return;
1900             }
1901
1902             auto listener = RequestStorageAccessConfirmResultListener::create(WTFMove(completionHandler));
1903             m_client.requestStorageAccessConfirm(toAPI(&page), toAPI(frame), toAPI(requestingDomain.impl()), toAPI(currentDomain.impl()), toAPI(listener.ptr()), m_client.base.clientInfo);
1904         }
1905
1906 #if ENABLE(DEVICE_ORIENTATION)
1907         void shouldAllowDeviceOrientationAndMotionAccess(WebPageProxy& page, API::SecurityOrigin& origin, CompletionHandler<void(bool)>&& completionHandler) final
1908         {
1909             if (!m_client.shouldAllowDeviceOrientationAndMotionAccess)
1910                 return completionHandler(true);
1911
1912             completionHandler(m_client.shouldAllowDeviceOrientationAndMotionAccess(toAPI(&page), toAPI(&origin), m_client.base.clientInfo));
1913         }
1914 #endif
1915
1916         // Printing.
1917         float headerHeight(WebPageProxy& page, WebFrameProxy& frame) final
1918         {
1919             if (!m_client.headerHeight)
1920                 return 0;
1921
1922             return m_client.headerHeight(toAPI(&page), toAPI(&frame), m_client.base.clientInfo);
1923         }
1924
1925         float footerHeight(WebPageProxy& page, WebFrameProxy& frame) final
1926         {
1927             if (!m_client.footerHeight)
1928                 return 0;
1929
1930             return m_client.footerHeight(toAPI(&page), toAPI(&frame), m_client.base.clientInfo);
1931         }
1932
1933         void drawHeader(WebPageProxy& page, WebFrameProxy& frame, WebCore::FloatRect&& rect) final
1934         {
1935             if (!m_client.drawHeader)
1936                 return;
1937
1938             m_client.drawHeader(toAPI(&page), toAPI(&frame), toAPI(rect), m_client.base.clientInfo);
1939         }
1940
1941         void drawFooter(WebPageProxy& page, WebFrameProxy& frame, WebCore::FloatRect&& rect) final
1942         {
1943             if (!m_client.drawFooter)
1944                 return;
1945
1946             m_client.drawFooter(toAPI(&page), toAPI(&frame), toAPI(rect), m_client.base.clientInfo);
1947         }
1948
1949         void printFrame(WebPageProxy& page, WebFrameProxy& frame) final
1950         {
1951             if (!m_client.printFrame)
1952                 return;
1953
1954             m_client.printFrame(toAPI(&page), toAPI(&frame), m_client.base.clientInfo);
1955         }
1956
1957         bool canRunModal() const final
1958         {
1959             return m_client.runModal;
1960         }
1961
1962         void runModal(WebPageProxy& page) final
1963         {
1964             if (!m_client.runModal)
1965                 return;
1966
1967             m_client.runModal(toAPI(&page), m_client.base.clientInfo);
1968         }
1969
1970         void saveDataToFileInDownloadsFolder(WebPageProxy* page, const String& suggestedFilename, const String& mimeType, const URL& originatingURL, API::Data& data) final
1971         {
1972             if (!m_client.saveDataToFileInDownloadsFolder)
1973                 return;
1974
1975             m_client.saveDataToFileInDownloadsFolder(toAPI(page), toAPI(suggestedFilename.impl()), toAPI(mimeType.impl()), toURLRef(originatingURL.string().impl()), toAPI(&data), m_client.base.clientInfo);
1976         }
1977
1978         void pinnedStateDidChange(WebPageProxy& page) final
1979         {
1980             if (!m_client.pinnedStateDidChange)
1981                 return;
1982
1983             m_client.pinnedStateDidChange(toAPI(&page), m_client.base.clientInfo);
1984         }
1985
1986         void isPlayingMediaDidChange(WebPageProxy& page) final
1987         {
1988             if (!m_client.isPlayingAudioDidChange)
1989                 return;
1990
1991             m_client.isPlayingAudioDidChange(toAPI(&page), m_client.base.clientInfo);
1992         }
1993
1994         void didClickAutoFillButton(WebPageProxy& page, API::Object* userInfo) final
1995         {
1996             if (!m_client.didClickAutoFillButton)
1997                 return;
1998
1999             m_client.didClickAutoFillButton(toAPI(&page), toAPI(userInfo), m_client.base.clientInfo);
2000         }
2001
2002         void didResignInputElementStrongPasswordAppearance(WebPageProxy& page, API::Object* userInfo) final
2003         {
2004             if (!m_client.didResignInputElementStrongPasswordAppearance)
2005                 return;
2006
2007             m_client.didResignInputElementStrongPasswordAppearance(toAPI(&page), toAPI(userInfo), m_client.base.clientInfo);
2008         }
2009
2010 #if ENABLE(MEDIA_SESSION)
2011         void mediaSessionMetadataDidChange(WebPageProxy& page, WebMediaSessionMetadata* metadata) final
2012         {
2013             if (!m_client.mediaSessionMetadataDidChange)
2014                 return;
2015
2016             m_client.mediaSessionMetadataDidChange(toAPI(&page), toAPI(metadata), m_client.base.clientInfo);
2017         }
2018 #endif
2019 #if ENABLE(POINTER_LOCK)
2020         void requestPointerLock(WebPageProxy* page) final
2021         {
2022             if (!m_client.requestPointerLock)
2023                 return;
2024             
2025             m_client.requestPointerLock(toAPI(page), m_client.base.clientInfo);
2026         }
2027
2028         void didLosePointerLock(WebPageProxy* page) final
2029         {
2030             if (!m_client.didLosePointerLock)
2031                 return;
2032
2033             m_client.didLosePointerLock(toAPI(page), m_client.base.clientInfo);
2034         }
2035 #endif
2036
2037         static WKAutoplayEventFlags toWKAutoplayEventFlags(OptionSet<WebCore::AutoplayEventFlags> flags)
2038         {
2039             WKAutoplayEventFlags wkFlags = kWKAutoplayEventFlagsNone;
2040             if (flags.contains(WebCore::AutoplayEventFlags::HasAudio))
2041                 wkFlags |= kWKAutoplayEventFlagsHasAudio;
2042             if (flags.contains(WebCore::AutoplayEventFlags::PlaybackWasPrevented))
2043                 wkFlags |= kWKAutoplayEventFlagsPlaybackWasPrevented;
2044             if (flags.contains(WebCore::AutoplayEventFlags::MediaIsMainContent))
2045                 wkFlags |= kWKAutoplayEventFlagsMediaIsMainContent;
2046
2047             return wkFlags;
2048         }
2049
2050         static WKAutoplayEvent toWKAutoplayEvent(WebCore::AutoplayEvent event)
2051         {
2052             switch (event) {
2053             case WebCore::AutoplayEvent::DidAutoplayMediaPastThresholdWithoutUserInterference:
2054                 return kWKAutoplayEventDidAutoplayMediaPastThresholdWithoutUserInterference;
2055             case WebCore::AutoplayEvent::DidPlayMediaWithUserGesture:
2056                 return kWKAutoplayEventDidPlayMediaWithUserGesture;
2057             case WebCore::AutoplayEvent::DidPreventMediaFromPlaying:
2058                 return kWKAutoplayEventDidPreventFromAutoplaying;
2059             case WebCore::AutoplayEvent::UserDidInterfereWithPlayback:
2060                 return kWKAutoplayEventUserDidInterfereWithPlayback;
2061             }
2062
2063             RELEASE_ASSERT_NOT_REACHED();
2064         }
2065
2066         void handleAutoplayEvent(WebPageProxy& page, WebCore::AutoplayEvent event, OptionSet<WebCore::AutoplayEventFlags> flags) final
2067         {
2068             if (!m_client.handleAutoplayEvent)
2069                 return;
2070
2071             m_client.handleAutoplayEvent(toAPI(&page), toWKAutoplayEvent(event), toWKAutoplayEventFlags(flags), m_client.base.clientInfo);
2072         }
2073     };
2074
2075     toImpl(pageRef)->setUIClient(std::make_unique<UIClient>(wkClient));
2076 }
2077
2078 void WKPageSetPageNavigationClient(WKPageRef pageRef, const WKPageNavigationClientBase* wkClient)
2079 {
2080     class NavigationClient : public API::Client<WKPageNavigationClientBase>, public API::NavigationClient {
2081     public:
2082         explicit NavigationClient(const WKPageNavigationClientBase* client)
2083         {
2084             initialize(client);
2085         }
2086
2087     private:
2088         void decidePolicyForNavigationAction(WebPageProxy& page, Ref<API::NavigationAction>&& navigationAction, Ref<WebKit::WebFramePolicyListenerProxy>&& listener, API::Object* userData) final
2089         {
2090             if (!m_client.decidePolicyForNavigationAction) {
2091                 listener->use();
2092                 return;
2093             }
2094             m_client.decidePolicyForNavigationAction(toAPI(&page), toAPI(navigationAction.ptr()), toAPI(listener.ptr()), toAPI(userData), m_client.base.clientInfo);
2095         }
2096
2097         void decidePolicyForNavigationResponse(WebPageProxy& page, Ref<API::NavigationResponse>&& navigationResponse, Ref<WebKit::WebFramePolicyListenerProxy>&& listener, API::Object* userData) override
2098         {
2099             if (!m_client.decidePolicyForNavigationResponse) {
2100                 listener->use();
2101                 return;
2102             }
2103             m_client.decidePolicyForNavigationResponse(toAPI(&page), toAPI(navigationResponse.ptr()), toAPI(listener.ptr()), toAPI(userData), m_client.base.clientInfo);
2104         }
2105
2106         void didStartProvisionalNavigation(WebPageProxy& page, API::Navigation* navigation, API::Object* userData) override
2107         {
2108             if (!m_client.didStartProvisionalNavigation)
2109                 return;
2110             m_client.didStartProvisionalNavigation(toAPI(&page), toAPI(navigation), toAPI(userData), m_client.base.clientInfo);
2111         }
2112
2113         void didReceiveServerRedirectForProvisionalNavigation(WebPageProxy& page, API::Navigation* navigation, API::Object* userData) override
2114         {
2115             if (!m_client.didReceiveServerRedirectForProvisionalNavigation)
2116                 return;
2117             m_client.didReceiveServerRedirectForProvisionalNavigation(toAPI(&page), toAPI(navigation), toAPI(userData), m_client.base.clientInfo);
2118         }
2119
2120         void didFailProvisionalNavigationWithError(WebPageProxy& page, WebFrameProxy&, API::Navigation* navigation, const WebCore::ResourceError& error, API::Object* userData) override
2121         {
2122             if (!m_client.didFailProvisionalNavigation)
2123                 return;
2124             m_client.didFailProvisionalNavigation(toAPI(&page), toAPI(navigation), toAPI(error), toAPI(userData), m_client.base.clientInfo);
2125         }
2126
2127         void didCommitNavigation(WebPageProxy& page, API::Navigation* navigation, API::Object* userData) override
2128         {
2129             if (!m_client.didCommitNavigation)
2130                 return;
2131             m_client.didCommitNavigation(toAPI(&page), toAPI(navigation), toAPI(userData), m_client.base.clientInfo);
2132         }
2133
2134         void didFinishNavigation(WebPageProxy& page, API::Navigation* navigation, API::Object* userData) override
2135         {
2136             if (!m_client.didFinishNavigation)
2137                 return;
2138             m_client.didFinishNavigation(toAPI(&page), toAPI(navigation), toAPI(userData), m_client.base.clientInfo);
2139         }
2140
2141         void didFailNavigationWithError(WebPageProxy& page, WebFrameProxy&, API::Navigation* navigation, const WebCore::ResourceError& error, API::Object* userData) override
2142         {
2143             if (!m_client.didFailNavigation)
2144                 return;
2145             m_client.didFailNavigation(toAPI(&page), toAPI(navigation), toAPI(error), toAPI(userData), m_client.base.clientInfo);
2146         }
2147
2148         void didFailProvisionalLoadInSubframeWithError(WebPageProxy& page, WebFrameProxy& subframe, const WebCore::SecurityOriginData& securityOriginData, API::Navigation* navigation, const WebCore::ResourceError& error, API::Object* userData) override
2149         {
2150             if (!m_client.didFailProvisionalLoadInSubframe)
2151                 return;
2152             m_client.didFailProvisionalLoadInSubframe(toAPI(&page), toAPI(navigation), toAPI(API::FrameInfo::create(subframe, securityOriginData.securityOrigin()).ptr()), toAPI(error), toAPI(userData), m_client.base.clientInfo);
2153         }
2154
2155         void didFinishDocumentLoad(WebPageProxy& page, API::Navigation* navigation, API::Object* userData) override
2156         {
2157             if (!m_client.didFinishDocumentLoad)
2158                 return;
2159             m_client.didFinishDocumentLoad(toAPI(&page), toAPI(navigation), toAPI(userData), m_client.base.clientInfo);
2160         }
2161
2162         void didSameDocumentNavigation(WebPageProxy& page, API::Navigation* navigation, WebKit::SameDocumentNavigationType navigationType, API::Object* userData) override
2163         {
2164             if (!m_client.didSameDocumentNavigation)
2165                 return;
2166             m_client.didSameDocumentNavigation(toAPI(&page), toAPI(navigation), toAPI(navigationType), toAPI(userData), m_client.base.clientInfo);
2167         }
2168         
2169         void renderingProgressDidChange(WebPageProxy& page, OptionSet<WebCore::LayoutMilestone> milestones) override
2170         {
2171             if (!m_client.renderingProgressDidChange)
2172                 return;
2173             m_client.renderingProgressDidChange(toAPI(&page), pageRenderingProgressEvents(milestones), nullptr, m_client.base.clientInfo);
2174         }
2175         
2176         void didReceiveAuthenticationChallenge(WebPageProxy& page, AuthenticationChallengeProxy& authenticationChallenge) override
2177         {
2178             if (m_client.canAuthenticateAgainstProtectionSpace && !m_client.canAuthenticateAgainstProtectionSpace(toAPI(&page), toAPI(WebProtectionSpace::create(authenticationChallenge.core().protectionSpace()).ptr()), m_client.base.clientInfo))
2179                 return authenticationChallenge.listener().completeChallenge(WebKit::AuthenticationChallengeDisposition::RejectProtectionSpaceAndContinue);
2180             if (!m_client.didReceiveAuthenticationChallenge)
2181                 return authenticationChallenge.listener().completeChallenge(WebKit::AuthenticationChallengeDisposition::PerformDefaultHandling);
2182             m_client.didReceiveAuthenticationChallenge(toAPI(&page), toAPI(&authenticationChallenge), m_client.base.clientInfo);
2183         }
2184
2185         bool processDidTerminate(WebPageProxy& page, WebKit::ProcessTerminationReason reason) override
2186         {
2187             if (m_client.webProcessDidTerminate) {
2188                 m_client.webProcessDidTerminate(toAPI(&page), toAPI(reason), m_client.base.clientInfo);
2189                 return true;
2190             }
2191
2192             if (m_client.webProcessDidCrash && reason != WebKit::ProcessTerminationReason::RequestedByClient) {
2193                 m_client.webProcessDidCrash(toAPI(&page), m_client.base.clientInfo);
2194                 return true;
2195             }
2196
2197             return false;
2198         }
2199
2200         RefPtr<API::Data> webCryptoMasterKey(WebPageProxy& page) override
2201         {
2202             if (m_client.copyWebCryptoMasterKey)
2203                 return adoptRef(toImpl(m_client.copyWebCryptoMasterKey(toAPI(&page), m_client.base.clientInfo)));
2204
2205             Vector<uint8_t> masterKey;
2206 #if ENABLE(WEB_CRYPTO)
2207             if (!getDefaultWebCryptoMasterKey(masterKey))
2208                 return nullptr;
2209 #endif
2210
2211             return API::Data::create(masterKey.data(), masterKey.size());
2212         }
2213
2214         RefPtr<API::String> signedPublicKeyAndChallengeString(WebPageProxy& page, unsigned keySizeIndex, const RefPtr<API::String>& challengeString, const URL& url) override
2215         {
2216             if (m_client.copySignedPublicKeyAndChallengeString)
2217                 return adoptRef(toImpl(m_client.copySignedPublicKeyAndChallengeString(toAPI(&page), m_client.base.clientInfo)));
2218             return API::String::create(WebCore::signedPublicKeyAndChallengeString(keySizeIndex, challengeString->string(), url));
2219         }
2220
2221         void didBeginNavigationGesture(WebPageProxy& page) override
2222         {
2223             if (!m_client.didBeginNavigationGesture)
2224                 return;
2225             m_client.didBeginNavigationGesture(toAPI(&page), m_client.base.clientInfo);
2226         }
2227
2228         void didEndNavigationGesture(WebPageProxy& page, bool willNavigate, WebKit::WebBackForwardListItem& item) override
2229         {
2230             if (!m_client.didEndNavigationGesture)
2231                 return;
2232             m_client.didEndNavigationGesture(toAPI(&page), willNavigate ? toAPI(&item) : nullptr, m_client.base.clientInfo);
2233         }
2234
2235         void willEndNavigationGesture(WebPageProxy& page, bool willNavigate, WebKit::WebBackForwardListItem& item) override
2236         {
2237             if (!m_client.willEndNavigationGesture)
2238                 return;
2239             m_client.willEndNavigationGesture(toAPI(&page), willNavigate ? toAPI(&item) : nullptr, m_client.base.clientInfo);
2240         }
2241
2242         void didRemoveNavigationGestureSnapshot(WebPageProxy& page) override
2243         {
2244             if (!m_client.didRemoveNavigationGestureSnapshot)
2245                 return;
2246             m_client.didRemoveNavigationGestureSnapshot(toAPI(&page), m_client.base.clientInfo);
2247         }
2248         
2249         void contentRuleListNotification(WebPageProxy& page, URL&& url, Vector<String>&& listIdentifiers, Vector<String>&& notifications) final
2250         {
2251             if (!m_client.contentRuleListNotification)
2252                 return;
2253
2254             Vector<RefPtr<API::Object>> apiListIdentifiers;
2255             for (const auto& identifier : listIdentifiers)
2256                 apiListIdentifiers.append(API::String::create(identifier));
2257
2258             Vector<RefPtr<API::Object>> apiNotifications;
2259             for (const auto& notification : notifications)
2260                 apiNotifications.append(API::String::create(notification));
2261
2262             m_client.contentRuleListNotification(toAPI(&page), toURLRef(url.string().impl()), toAPI(API::Array::create(WTFMove(apiListIdentifiers)).ptr()), toAPI(API::Array::create(WTFMove(apiNotifications)).ptr()), m_client.base.clientInfo);
2263         }
2264 #if ENABLE(NETSCAPE_PLUGIN_API)
2265         void decidePolicyForPluginLoad(WebPageProxy& page, PluginModuleLoadPolicy currentPluginLoadPolicy, API::Dictionary& pluginInformation, CompletionHandler<void(PluginModuleLoadPolicy, const String&)>&& completionHandler) override
2266         {
2267             WKStringRef unavailabilityDescriptionOut = 0;
2268             PluginModuleLoadPolicy loadPolicy = currentPluginLoadPolicy;
2269             
2270             if (m_client.decidePolicyForPluginLoad)
2271                 loadPolicy = toPluginModuleLoadPolicy(m_client.decidePolicyForPluginLoad(toAPI(&page), toWKPluginLoadPolicy(currentPluginLoadPolicy), toAPI(&pluginInformation), &unavailabilityDescriptionOut, m_client.base.clientInfo));
2272             
2273             String unavailabilityDescription;
2274             if (unavailabilityDescriptionOut) {
2275                 RefPtr<API::String> webUnavailabilityDescription = adoptRef(toImpl(unavailabilityDescriptionOut));
2276                 unavailabilityDescription = webUnavailabilityDescription->string();
2277             }
2278             
2279             completionHandler(loadPolicy, unavailabilityDescription);
2280         }
2281 #endif
2282     };
2283
2284     WebPageProxy* webPageProxy = toImpl(pageRef);
2285
2286     webPageProxy->setNavigationClient(makeUniqueRef<NavigationClient>(wkClient));
2287 }
2288
2289 void WKPageRunJavaScriptInMainFrame(WKPageRef pageRef, WKStringRef scriptRef, void* context, WKPageRunJavaScriptFunction callback)
2290 {
2291     toImpl(pageRef)->runJavaScriptInMainFrame(toImpl(scriptRef)->string(), true, [context, callback](API::SerializedScriptValue* returnValue, bool, const WebCore::ExceptionDetails&, CallbackBase::Error error) {
2292         callback(toAPI(returnValue), (error != CallbackBase::Error::None) ? toAPI(API::Error::create().ptr()) : 0, context);
2293     });
2294 }
2295
2296 #ifdef __BLOCKS__
2297 static void callRunJavaScriptBlockAndRelease(WKSerializedScriptValueRef resultValue, WKErrorRef error, void* context)
2298 {
2299     WKPageRunJavaScriptBlock block = (WKPageRunJavaScriptBlock)context;
2300     block(resultValue, error);
2301     Block_release(block);
2302 }
2303
2304 void WKPageRunJavaScriptInMainFrame_b(WKPageRef pageRef, WKStringRef scriptRef, WKPageRunJavaScriptBlock block)
2305 {
2306     WKPageRunJavaScriptInMainFrame(pageRef, scriptRef, Block_copy(block), callRunJavaScriptBlockAndRelease);
2307 }
2308 #endif
2309
2310 static WTF::Function<void (const String&, WebKit::CallbackBase::Error)> toGenericCallbackFunction(void* context, void (*callback)(WKStringRef, WKErrorRef, void*))
2311 {
2312     return [context, callback](const String& returnValue, WebKit::CallbackBase::Error error) {
2313         callback(toAPI(API::String::create(returnValue).ptr()), error != WebKit::CallbackBase::Error::None ? toAPI(API::Error::create().ptr()) : 0, context);
2314     };
2315 }
2316
2317 void WKPageRenderTreeExternalRepresentation(WKPageRef pageRef, void* context, WKPageRenderTreeExternalRepresentationFunction callback)
2318 {
2319     toImpl(pageRef)->getRenderTreeExternalRepresentation(toGenericCallbackFunction(context, callback));
2320 }
2321
2322 void WKPageGetSourceForFrame(WKPageRef pageRef, WKFrameRef frameRef, void* context, WKPageGetSourceForFrameFunction callback)
2323 {
2324     toImpl(pageRef)->getSourceForFrame(toImpl(frameRef), toGenericCallbackFunction(context, callback));
2325 }
2326
2327 void WKPageGetContentsAsString(WKPageRef pageRef, void* context, WKPageGetContentsAsStringFunction callback)
2328 {
2329     toImpl(pageRef)->getContentsAsString(toGenericCallbackFunction(context, callback));
2330 }
2331
2332 void WKPageGetBytecodeProfile(WKPageRef pageRef, void* context, WKPageGetBytecodeProfileFunction callback)
2333 {
2334     toImpl(pageRef)->getBytecodeProfile(toGenericCallbackFunction(context, callback));
2335 }
2336
2337 void WKPageGetSamplingProfilerOutput(WKPageRef pageRef, void* context, WKPageGetSamplingProfilerOutputFunction callback)
2338 {
2339     toImpl(pageRef)->getSamplingProfilerOutput(toGenericCallbackFunction(context, callback));
2340 }
2341
2342 void WKPageGetSelectionAsWebArchiveData(WKPageRef pageRef, void* context, WKPageGetSelectionAsWebArchiveDataFunction callback)
2343 {
2344     toImpl(pageRef)->getSelectionAsWebArchiveData(toGenericCallbackFunction(context, callback));
2345 }
2346
2347 void WKPageGetContentsAsMHTMLData(WKPageRef pageRef, void* context, WKPageGetContentsAsMHTMLDataFunction callback)
2348 {
2349 #if ENABLE(MHTML)
2350     toImpl(pageRef)->getContentsAsMHTMLData(toGenericCallbackFunction(context, callback));
2351 #else
2352     UNUSED_PARAM(pageRef);
2353     UNUSED_PARAM(context);
2354     UNUSED_PARAM(callback);
2355 #endif
2356 }
2357
2358 void WKPageForceRepaint(WKPageRef pageRef, void* context, WKPageForceRepaintFunction callback)
2359 {
2360     toImpl(pageRef)->forceRepaint(VoidCallback::create([context, callback](WebKit::CallbackBase::Error error) {
2361         callback(error == WebKit::CallbackBase::Error::None ? nullptr : toAPI(API::Error::create().ptr()), context);
2362     }));
2363 }
2364
2365 WK_EXPORT WKURLRef WKPageCopyPendingAPIRequestURL(WKPageRef pageRef)
2366 {
2367     const String& pendingAPIRequestURL = toImpl(pageRef)->pageLoadState().pendingAPIRequestURL();
2368
2369     if (pendingAPIRequestURL.isNull())
2370         return nullptr;
2371
2372     return toCopiedURLAPI(pendingAPIRequestURL);
2373 }
2374
2375 WKURLRef WKPageCopyActiveURL(WKPageRef pageRef)
2376 {
2377     return toCopiedURLAPI(toImpl(pageRef)->pageLoadState().activeURL());
2378 }
2379
2380 WKURLRef WKPageCopyProvisionalURL(WKPageRef pageRef)
2381 {
2382     return toCopiedURLAPI(toImpl(pageRef)->pageLoadState().provisionalURL());
2383 }
2384
2385 WKURLRef WKPageCopyCommittedURL(WKPageRef pageRef)
2386 {
2387     return toCopiedURLAPI(toImpl(pageRef)->pageLoadState().url());
2388 }
2389
2390 WKStringRef WKPageCopyStandardUserAgentWithApplicationName(WKStringRef applicationName)
2391 {
2392     return toCopiedAPI(WebPageProxy::standardUserAgent(toImpl(applicationName)->string()));
2393 }
2394
2395 void WKPageValidateCommand(WKPageRef pageRef, WKStringRef command, void* context, WKPageValidateCommandCallback callback)
2396 {
2397     toImpl(pageRef)->validateCommand(toImpl(command)->string(), [context, callback](const String& commandName, bool isEnabled, int32_t state, WebKit::CallbackBase::Error error) {
2398         callback(toAPI(API::String::create(commandName).ptr()), isEnabled, state, error != WebKit::CallbackBase::Error::None ? toAPI(API::Error::create().ptr()) : 0, context);
2399     });
2400 }
2401
2402 void WKPageExecuteCommand(WKPageRef pageRef, WKStringRef command)
2403 {
2404     toImpl(pageRef)->executeEditCommand(toImpl(command)->string());
2405 }
2406
2407 #if PLATFORM(COCOA)
2408 static PrintInfo printInfoFromWKPrintInfo(const WKPrintInfo& printInfo)
2409 {
2410     PrintInfo result;
2411     result.pageSetupScaleFactor = printInfo.pageSetupScaleFactor;
2412     result.availablePaperWidth = printInfo.availablePaperWidth;
2413     result.availablePaperHeight = printInfo.availablePaperHeight;
2414     return result;
2415 }
2416
2417 void WKPageComputePagesForPrinting(WKPageRef page, WKFrameRef frame, WKPrintInfo printInfo, WKPageComputePagesForPrintingFunction callback, void* context)
2418 {
2419     toImpl(page)->computePagesForPrinting(toImpl(frame), printInfoFromWKPrintInfo(printInfo), ComputedPagesCallback::create([context, callback](const Vector<WebCore::IntRect>& rects, double scaleFactor, WebKit::CallbackBase::Error error) {
2420         Vector<WKRect> wkRects(rects.size());
2421         for (size_t i = 0; i < rects.size(); ++i)
2422             wkRects[i] = toAPI(rects[i]);
2423         callback(wkRects.data(), wkRects.size(), scaleFactor, error != WebKit::CallbackBase::Error::None ? toAPI(API::Error::create().ptr()) : 0, context);
2424     }));
2425 }
2426
2427 void WKPageBeginPrinting(WKPageRef page, WKFrameRef frame, WKPrintInfo printInfo)
2428 {
2429     toImpl(page)->beginPrinting(toImpl(frame), printInfoFromWKPrintInfo(printInfo));
2430 }
2431
2432 void WKPageDrawPagesToPDF(WKPageRef page, WKFrameRef frame, WKPrintInfo printInfo, uint32_t first, uint32_t count, WKPageDrawToPDFFunction callback, void* context)
2433 {
2434     toImpl(page)->drawPagesToPDF(toImpl(frame), printInfoFromWKPrintInfo(printInfo), first, count, DataCallback::create(toGenericCallbackFunction(context, callback)));
2435 }
2436
2437 void WKPageEndPrinting(WKPageRef page)
2438 {
2439     toImpl(page)->endPrinting();
2440 }
2441 #endif
2442
2443 bool WKPageGetIsControlledByAutomation(WKPageRef page)
2444 {
2445     return toImpl(page)->isControlledByAutomation();
2446 }
2447
2448 void WKPageSetControlledByAutomation(WKPageRef page, bool controlled)
2449 {
2450     toImpl(page)->setControlledByAutomation(controlled);
2451 }
2452
2453 bool WKPageGetAllowsRemoteInspection(WKPageRef page)
2454 {
2455 #if ENABLE(REMOTE_INSPECTOR)
2456     return toImpl(page)->allowsRemoteInspection();
2457 #else
2458     UNUSED_PARAM(page);
2459     return false;
2460 #endif    
2461 }
2462
2463 void WKPageSetAllowsRemoteInspection(WKPageRef page, bool allow)
2464 {
2465 #if ENABLE(REMOTE_INSPECTOR)
2466     toImpl(page)->setAllowsRemoteInspection(allow);
2467 #else
2468     UNUSED_PARAM(page);
2469     UNUSED_PARAM(allow);
2470 #endif
2471 }
2472
2473 void WKPageSetMediaVolume(WKPageRef page, float volume)
2474 {
2475     toImpl(page)->setMediaVolume(volume);    
2476 }
2477
2478 void WKPageSetMuted(WKPageRef page, WKMediaMutedState muted)
2479 {
2480     toImpl(page)->setMuted(muted);
2481 }
2482
2483 void WKPageSetMediaCaptureEnabled(WKPageRef page, bool enabled)
2484 {
2485     toImpl(page)->setMediaCaptureEnabled(enabled);
2486 }
2487
2488 bool WKPageGetMediaCaptureEnabled(WKPageRef page)
2489 {
2490     return toImpl(page)->mediaCaptureEnabled();
2491 }
2492
2493 void WKPageDidAllowPointerLock(WKPageRef page)
2494 {
2495 #if ENABLE(POINTER_LOCK)
2496     toImpl(page)->didAllowPointerLock();
2497 #else
2498     UNUSED_PARAM(page);
2499 #endif
2500 }
2501
2502 void WKPageClearUserMediaState(WKPageRef page)
2503 {
2504 #if ENABLE(MEDIA_STREAM)
2505     toImpl(page)->clearUserMediaState();
2506 #else
2507     UNUSED_PARAM(page);
2508 #endif
2509 }
2510
2511 void WKPageDidDenyPointerLock(WKPageRef page)
2512 {
2513 #if ENABLE(POINTER_LOCK)
2514     toImpl(page)->didDenyPointerLock();
2515 #else
2516     UNUSED_PARAM(page);
2517 #endif
2518 }
2519
2520 bool WKPageHasMediaSessionWithActiveMediaElements(WKPageRef page)
2521 {
2522 #if ENABLE(MEDIA_SESSION)
2523     return toImpl(page)->hasMediaSessionWithActiveMediaElements();
2524 #else
2525     UNUSED_PARAM(page);
2526     return false;
2527 #endif
2528 }
2529
2530 void WKPageHandleMediaEvent(WKPageRef page, WKMediaEventType wkEventType)
2531 {
2532 #if ENABLE(MEDIA_SESSION)
2533     MediaEventType eventType;
2534
2535     switch (wkEventType) {
2536     case kWKMediaEventTypePlayPause:
2537         eventType = MediaEventType::PlayPause;
2538         break;
2539     case kWKMediaEventTypeTrackNext:
2540         eventType = MediaEventType::TrackNext;
2541         break;
2542     case kWKMediaEventTypeTrackPrevious:
2543         eventType = MediaEventType::TrackPrevious;
2544         break;
2545     default:
2546         ASSERT_NOT_REACHED();
2547         return;
2548     }
2549
2550     toImpl(page)->handleMediaEvent(eventType);
2551 #else
2552     UNUSED_PARAM(page);
2553     UNUSED_PARAM(wkEventType);
2554 #endif
2555 }
2556
2557 void WKPagePostMessageToInjectedBundle(WKPageRef pageRef, WKStringRef messageNameRef, WKTypeRef messageBodyRef)
2558 {
2559     toImpl(pageRef)->postMessageToInjectedBundle(toImpl(messageNameRef)->string(), toImpl(messageBodyRef));
2560 }
2561
2562 WKArrayRef WKPageCopyRelatedPages(WKPageRef pageRef)
2563 {
2564     Vector<RefPtr<API::Object>> relatedPages;
2565
2566     for (auto& page : toImpl(pageRef)->process().pages()) {
2567         if (page != toImpl(pageRef))
2568             relatedPages.append(page);
2569     }
2570
2571     return toAPI(&API::Array::create(WTFMove(relatedPages)).leakRef());
2572 }
2573
2574 WKFrameRef WKPageLookUpFrameFromHandle(WKPageRef pageRef, WKFrameHandleRef handleRef)
2575 {
2576     auto page = toImpl(pageRef);
2577     auto frame = page->process().webFrame(toImpl(handleRef)->frameID());
2578     if (!frame || frame->page() != page)
2579         return nullptr;
2580
2581     return toAPI(frame);
2582 }
2583
2584 void WKPageSetMayStartMediaWhenInWindow(WKPageRef pageRef, bool mayStartMedia)
2585 {
2586     toImpl(pageRef)->setMayStartMediaWhenInWindow(mayStartMedia);
2587 }
2588
2589
2590 void WKPageSelectContextMenuItem(WKPageRef page, WKContextMenuItemRef item)
2591 {
2592 #if ENABLE(CONTEXT_MENUS)
2593     toImpl(page)->contextMenuItemSelected((toImpl(item)->data()));
2594 #else
2595     UNUSED_PARAM(page);
2596     UNUSED_PARAM(item);
2597 #endif
2598 }
2599
2600 WKScrollPinningBehavior WKPageGetScrollPinningBehavior(WKPageRef page)
2601 {
2602     ScrollPinningBehavior pinning = toImpl(page)->scrollPinningBehavior();
2603     
2604     switch (pinning) {
2605     case WebCore::ScrollPinningBehavior::DoNotPin:
2606         return kWKScrollPinningBehaviorDoNotPin;
2607     case WebCore::ScrollPinningBehavior::PinToTop:
2608         return kWKScrollPinningBehaviorPinToTop;
2609     case WebCore::ScrollPinningBehavior::PinToBottom:
2610         return kWKScrollPinningBehaviorPinToBottom;
2611     }
2612     
2613     ASSERT_NOT_REACHED();
2614     return kWKScrollPinningBehaviorDoNotPin;
2615 }
2616
2617 void WKPageSetScrollPinningBehavior(WKPageRef page, WKScrollPinningBehavior pinning)
2618 {
2619     ScrollPinningBehavior corePinning = ScrollPinningBehavior::DoNotPin;
2620
2621     switch (pinning) {
2622     case kWKScrollPinningBehaviorDoNotPin:
2623         corePinning = ScrollPinningBehavior::DoNotPin;
2624         break;
2625     case kWKScrollPinningBehaviorPinToTop:
2626         corePinning = ScrollPinningBehavior::PinToTop;
2627         break;
2628     case kWKScrollPinningBehaviorPinToBottom:
2629         corePinning = ScrollPinningBehavior::PinToBottom;
2630         break;
2631     default:
2632         ASSERT_NOT_REACHED();
2633     }
2634     
2635     toImpl(page)->setScrollPinningBehavior(corePinning);
2636 }
2637
2638 bool WKPageGetAddsVisitedLinks(WKPageRef page)
2639 {
2640     return toImpl(page)->addsVisitedLinks();
2641 }
2642
2643 void WKPageSetAddsVisitedLinks(WKPageRef page, bool addsVisitedLinks)
2644 {
2645     toImpl(page)->setAddsVisitedLinks(addsVisitedLinks);
2646 }
2647
2648 bool WKPageIsPlayingAudio(WKPageRef page)
2649 {
2650     return toImpl(page)->isPlayingAudio();
2651 }
2652
2653 WKMediaState WKPageGetMediaState(WKPageRef page)
2654 {
2655     WebCore::MediaProducer::MediaStateFlags coreState = toImpl(page)->mediaStateFlags();
2656     WKMediaState state = kWKMediaIsNotPlaying;
2657
2658     if (coreState & WebCore::MediaProducer::IsPlayingAudio)
2659         state |= kWKMediaIsPlayingAudio;
2660     if (coreState & WebCore::MediaProducer::IsPlayingVideo)
2661         state |= kWKMediaIsPlayingVideo;
2662     if (coreState & WebCore::MediaProducer::HasActiveAudioCaptureDevice)
2663         state |= kWKMediaHasActiveAudioCaptureDevice;
2664     if (coreState & WebCore::MediaProducer::HasActiveVideoCaptureDevice)
2665         state |= kWKMediaHasActiveVideoCaptureDevice;
2666     if (coreState & WebCore::MediaProducer::HasMutedAudioCaptureDevice)
2667         state |= kWKMediaHasMutedAudioCaptureDevice;
2668     if (coreState & WebCore::MediaProducer::HasMutedVideoCaptureDevice)
2669         state |= kWKMediaHasMutedVideoCaptureDevice;
2670     if (coreState & WebCore::MediaProducer::HasActiveDisplayCaptureDevice)
2671         state |= kWKMediaHasActiveDisplayCaptureDevice;
2672     if (coreState & WebCore::MediaProducer::HasMutedDisplayCaptureDevice)
2673         state |= kWKMediaHasMutedDisplayCaptureDevice;
2674
2675     return state;
2676 }
2677
2678 void WKPageClearWheelEventTestTrigger(WKPageRef pageRef)
2679 {
2680     toImpl(pageRef)->clearWheelEventTestTrigger();
2681 }
2682
2683 void WKPageCallAfterNextPresentationUpdate(WKPageRef pageRef, void* context, WKPagePostPresentationUpdateFunction callback)
2684 {
2685     toImpl(pageRef)->callAfterNextPresentationUpdate([context, callback](WebKit::CallbackBase::Error error) {
2686         callback(error != WebKit::CallbackBase::Error::None ? toAPI(API::Error::create().ptr()) : 0, context);
2687     });
2688 }
2689
2690 bool WKPageGetResourceCachingDisabled(WKPageRef page)
2691 {
2692     return toImpl(page)->isResourceCachingDisabled();
2693 }
2694
2695 void WKPageSetResourceCachingDisabled(WKPageRef page, bool disabled)
2696 {
2697     toImpl(page)->setResourceCachingDisabled(disabled);
2698 }
2699
2700 void WKPageSetIgnoresViewportScaleLimits(WKPageRef page, bool ignoresViewportScaleLimits)
2701 {
2702 #if PLATFORM(IOS_FAMILY)
2703     toImpl(page)->setForceAlwaysUserScalable(ignoresViewportScaleLimits);
2704 #endif
2705 }
2706
2707 ProcessID WKPageGetProcessIdentifier(WKPageRef page)
2708 {
2709     return toImpl(page)->processIdentifier();
2710 }
2711
2712 #ifdef __BLOCKS__
2713 void WKPageGetApplicationManifest_b(WKPageRef page, WKPageGetApplicationManifestBlock block)
2714 {
2715 #if ENABLE(APPLICATION_MANIFEST)
2716     toImpl(page)->getApplicationManifest([block](const Optional<WebCore::ApplicationManifest> &manifest, CallbackBase::Error) {
2717         block();
2718     });
2719 #else // ENABLE(APPLICATION_MANIFEST)
2720     UNUSED_PARAM(page);
2721     block();
2722 #endif // not ENABLE(APPLICATION_MANIFEST)
2723 }
2724 #endif
2725
2726 void WKPageDumpAdClickAttribution(WKPageRef page, WKPageDumpAdClickAttributionFunction callback, void* callbackContext)
2727 {
2728     toImpl(page)->dumpAdClickAttribution([callbackContext, callback] (const String& adClickAttribution) {
2729         callback(WebKit::toAPI(adClickAttribution.impl()), callbackContext);
2730     });
2731 }
2732
2733 void WKPageClearAdClickAttribution(WKPageRef page, WKPageClearAdClickAttributionFunction callback, void* callbackContext)
2734 {
2735     toImpl(page)->clearAdClickAttribution([callbackContext, callback] () {
2736         callback(callbackContext);
2737     });
2738 }