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