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