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