Add WKUIDelegatePrivate equivalent of WKPageUIClient's toolbarsAreVisible
[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), toWTFString(baseURLRef), toWTFString(unreachableURLRef));
213 }
214
215 void WKPageLoadAlternateHTMLStringWithUserData(WKPageRef pageRef, WKStringRef htmlStringRef, WKURLRef baseURLRef, WKURLRef unreachableURLRef, WKTypeRef userDataRef)
216 {
217     toImpl(pageRef)->loadAlternateHTMLString(toWTFString(htmlStringRef), toWTFString(baseURLRef), 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         RefPtr<WebPageProxy> createNewPage(WebPageProxy* page, API::FrameInfo& sourceFrameInfo, ResourceRequest&& resourceRequest, const WindowFeatures& windowFeatures, NavigationActionData&& navigationActionData) 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, nullptr, WTFMove(resourceRequest), WebCore::URL(), shouldOpenAppLinks, WTFMove(userInitiatedActivity));
1577
1578                 auto apiWindowFeatures = API::WindowFeatures::create(windowFeatures);
1579
1580                 return 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 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 adoptRef(toImpl(m_client.createNewPage_deprecatedForUseWithV0(toAPI(page), toAPI(featuresMap.ptr()), toAPI(navigationActionData.modifiers), toAPI(navigationActionData.mouseButton), m_client.base.clientInfo)));
1610             }
1611
1612             return 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             RefPtr<API::HitTestResult> webHitTestResult = API::HitTestResult::create(data);
1787             m_client.mouseDidMoveOverElement(toAPI(page), toAPI(webHitTestResult.get()), 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         bool menuBarIsVisible(WebPageProxy* page) final
1850         {
1851             if (!m_client.menuBarIsVisible)
1852                 return true;
1853             return 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         bool statusBarIsVisible(WebPageProxy* page) final
1864         {
1865             if (!m_client.statusBarIsVisible)
1866                 return true;
1867             return 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         bool isResizable(WebPageProxy* page) final
1878         {
1879             if (!m_client.isResizable)
1880                 return true;
1881             return m_client.isResizable(toAPI(page), m_client.base.clientInfo);
1882         }
1883
1884         void setIsResizable(WebPageProxy* page, bool resizable) final
1885         {
1886             if (!m_client.setIsResizable)
1887                 return;
1888             m_client.setIsResizable(toAPI(page), resizable, m_client.base.clientInfo);
1889         }
1890
1891         void setWindowFrame(WebPageProxy* page, const FloatRect& frame) final
1892         {
1893             if (!m_client.setWindowFrame)
1894                 return;
1895
1896             m_client.setWindowFrame(toAPI(page), toAPI(frame), m_client.base.clientInfo);
1897         }
1898
1899         FloatRect windowFrame(WebPageProxy* page) final
1900         {
1901             if (!m_client.getWindowFrame)
1902                 return FloatRect();
1903
1904             return toFloatRect(m_client.getWindowFrame(toAPI(page), m_client.base.clientInfo));
1905         }
1906
1907         bool canRunBeforeUnloadConfirmPanel() const final
1908         {
1909             return m_client.runBeforeUnloadConfirmPanel_deprecatedForUseWithV6 || m_client.runBeforeUnloadConfirmPanel;
1910         }
1911
1912         void runBeforeUnloadConfirmPanel(WebKit::WebPageProxy* page, const WTF::String& message, WebKit::WebFrameProxy* frame, const SecurityOriginData&, Function<void(bool)>&& completionHandler) final
1913         {
1914             if (m_client.runBeforeUnloadConfirmPanel) {
1915                 RefPtr<RunBeforeUnloadConfirmPanelResultListener> listener = RunBeforeUnloadConfirmPanelResultListener::create(WTFMove(completionHandler));
1916                 m_client.runBeforeUnloadConfirmPanel(toAPI(page), toAPI(message.impl()), toAPI(frame), toAPI(listener.get()), m_client.base.clientInfo);
1917                 return;
1918             }
1919
1920             if (m_client.runBeforeUnloadConfirmPanel_deprecatedForUseWithV6) {
1921                 bool result = m_client.runBeforeUnloadConfirmPanel_deprecatedForUseWithV6(toAPI(page), toAPI(message.impl()), toAPI(frame), m_client.base.clientInfo);
1922                 completionHandler(result);
1923                 return;
1924             }
1925
1926             completionHandler(true);
1927         }
1928
1929         void pageDidScroll(WebPageProxy* page) final
1930         {
1931             if (!m_client.pageDidScroll)
1932                 return;
1933
1934             m_client.pageDidScroll(toAPI(page), m_client.base.clientInfo);
1935         }
1936
1937         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
1938         {
1939             if (!m_client.exceededDatabaseQuota) {
1940                 completionHandler(currentQuota);
1941                 return;
1942             }
1943
1944             completionHandler(m_client.exceededDatabaseQuota(toAPI(page), toAPI(frame), toAPI(origin), toAPI(databaseName.impl()), toAPI(databaseDisplayName.impl()), currentQuota, currentOriginUsage, currentDatabaseUsage, expectedUsage, m_client.base.clientInfo));
1945         }
1946
1947         bool runOpenPanel(WebPageProxy* page, WebFrameProxy* frame, const WebCore::SecurityOriginData&, API::OpenPanelParameters* parameters, WebOpenPanelResultListenerProxy* listener) final
1948         {
1949             if (!m_client.runOpenPanel)
1950                 return false;
1951
1952             m_client.runOpenPanel(toAPI(page), toAPI(frame), toAPI(parameters), toAPI(listener), m_client.base.clientInfo);
1953             return true;
1954         }
1955
1956         bool decidePolicyForGeolocationPermissionRequest(WebPageProxy* page, WebFrameProxy* frame, API::SecurityOrigin* origin, GeolocationPermissionRequestProxy* permissionRequest) final
1957         {
1958             if (!m_client.decidePolicyForGeolocationPermissionRequest)
1959                 return false;
1960
1961             m_client.decidePolicyForGeolocationPermissionRequest(toAPI(page), toAPI(frame), toAPI(origin), toAPI(permissionRequest), m_client.base.clientInfo);
1962             return true;
1963         }
1964
1965         bool decidePolicyForUserMediaPermissionRequest(WebPageProxy& page, WebFrameProxy& frame, API::SecurityOrigin& userMediaDocumentOrigin, API::SecurityOrigin& topLevelDocumentOrigin, UserMediaPermissionRequestProxy& permissionRequest) final
1966         {
1967             if (!m_client.decidePolicyForUserMediaPermissionRequest)
1968                 return false;
1969
1970             m_client.decidePolicyForUserMediaPermissionRequest(toAPI(&page), toAPI(&frame), toAPI(&userMediaDocumentOrigin), toAPI(&topLevelDocumentOrigin), toAPI(&permissionRequest), m_client.base.clientInfo);
1971             return true;
1972         }
1973
1974         bool checkUserMediaPermissionForOrigin(WebPageProxy& page, WebFrameProxy& frame, API::SecurityOrigin& userMediaDocumentOrigin, API::SecurityOrigin& topLevelDocumentOrigin, UserMediaPermissionCheckProxy& request) final
1975         {
1976             if (!m_client.checkUserMediaPermissionForOrigin)
1977                 return false;
1978
1979             m_client.checkUserMediaPermissionForOrigin(toAPI(&page), toAPI(&frame), toAPI(&userMediaDocumentOrigin), toAPI(&topLevelDocumentOrigin), toAPI(&request), m_client.base.clientInfo);
1980             return true;
1981         }
1982         
1983         bool decidePolicyForNotificationPermissionRequest(WebPageProxy* page, API::SecurityOrigin* origin, NotificationPermissionRequest* permissionRequest) final
1984         {
1985             if (!m_client.decidePolicyForNotificationPermissionRequest)
1986                 return false;
1987
1988             m_client.decidePolicyForNotificationPermissionRequest(toAPI(page), toAPI(origin), toAPI(permissionRequest), m_client.base.clientInfo);
1989             return true;
1990         }
1991
1992         // Printing.
1993         float headerHeight(WebPageProxy* page, WebFrameProxy* frame) final
1994         {
1995             if (!m_client.headerHeight)
1996                 return 0;
1997
1998             return m_client.headerHeight(toAPI(page), toAPI(frame), m_client.base.clientInfo);
1999         }
2000
2001         float footerHeight(WebPageProxy* page, WebFrameProxy* frame) final
2002         {
2003             if (!m_client.footerHeight)
2004                 return 0;
2005
2006             return m_client.footerHeight(toAPI(page), toAPI(frame), m_client.base.clientInfo);
2007         }
2008
2009         void drawHeader(WebPageProxy* page, WebFrameProxy* frame, const WebCore::FloatRect& rect) final
2010         {
2011             if (!m_client.drawHeader)
2012                 return;
2013
2014             m_client.drawHeader(toAPI(page), toAPI(frame), toAPI(rect), m_client.base.clientInfo);
2015         }
2016
2017         void drawFooter(WebPageProxy* page, WebFrameProxy* frame, const WebCore::FloatRect& rect) final
2018         {
2019             if (!m_client.drawFooter)
2020                 return;
2021
2022             m_client.drawFooter(toAPI(page), toAPI(frame), toAPI(rect), m_client.base.clientInfo);
2023         }
2024
2025         void printFrame(WebPageProxy* page, WebFrameProxy* frame) final
2026         {
2027             if (!m_client.printFrame)
2028                 return;
2029
2030             m_client.printFrame(toAPI(page), toAPI(frame), m_client.base.clientInfo);
2031         }
2032
2033         bool canRunModal() const final
2034         {
2035             return m_client.runModal;
2036         }
2037
2038         void runModal(WebPageProxy* page) final
2039         {
2040             if (!m_client.runModal)
2041                 return;
2042
2043             m_client.runModal(toAPI(page), m_client.base.clientInfo);
2044         }
2045
2046         void saveDataToFileInDownloadsFolder(WebPageProxy* page, const String& suggestedFilename, const String& mimeType, const WebCore::URL& originatingURL, API::Data& data) final
2047         {
2048             if (!m_client.saveDataToFileInDownloadsFolder)
2049                 return;
2050
2051             m_client.saveDataToFileInDownloadsFolder(toAPI(page), toAPI(suggestedFilename.impl()), toAPI(mimeType.impl()), toURLRef(originatingURL.string().impl()), toAPI(&data), m_client.base.clientInfo);
2052         }
2053
2054         void pinnedStateDidChange(WebPageProxy& page) final
2055         {
2056             if (!m_client.pinnedStateDidChange)
2057                 return;
2058
2059             m_client.pinnedStateDidChange(toAPI(&page), m_client.base.clientInfo);
2060         }
2061
2062         void isPlayingMediaDidChange(WebPageProxy& page) final
2063         {
2064             if (!m_client.isPlayingAudioDidChange)
2065                 return;
2066
2067             m_client.isPlayingAudioDidChange(toAPI(&page), m_client.base.clientInfo);
2068         }
2069
2070         void didClickAutoFillButton(WebPageProxy& page, API::Object* userInfo) final
2071         {
2072             if (!m_client.didClickAutoFillButton)
2073                 return;
2074
2075             m_client.didClickAutoFillButton(toAPI(&page), toAPI(userInfo), m_client.base.clientInfo);
2076         }
2077
2078 #if ENABLE(MEDIA_SESSION)
2079         void mediaSessionMetadataDidChange(WebPageProxy& page, WebMediaSessionMetadata* metadata) final
2080         {
2081             if (!m_client.mediaSessionMetadataDidChange)
2082                 return;
2083
2084             m_client.mediaSessionMetadataDidChange(toAPI(&page), toAPI(metadata), m_client.base.clientInfo);
2085         }
2086 #endif
2087 #if ENABLE(POINTER_LOCK)
2088         void requestPointerLock(WebPageProxy* page) final
2089         {
2090             if (!m_client.requestPointerLock)
2091                 return;
2092             
2093             m_client.requestPointerLock(toAPI(page), m_client.base.clientInfo);
2094         }
2095
2096         void didLosePointerLock(WebPageProxy* page) final
2097         {
2098             if (!m_client.didLosePointerLock)
2099                 return;
2100
2101             m_client.didLosePointerLock(toAPI(page), m_client.base.clientInfo);
2102         }
2103 #endif
2104
2105         static WKAutoplayEventFlags toWKAutoplayEventFlags(OptionSet<WebCore::AutoplayEventFlags> flags)
2106         {
2107             WKAutoplayEventFlags wkFlags = kWKAutoplayEventFlagsNone;
2108             if (flags.contains(WebCore::AutoplayEventFlags::HasAudio))
2109                 wkFlags |= kWKAutoplayEventFlagsHasAudio;
2110
2111             return wkFlags;
2112         }
2113
2114         static WKAutoplayEvent toWKAutoplayEvent(WebCore::AutoplayEvent event)
2115         {
2116             switch (event) {
2117             case WebCore::AutoplayEvent::DidAutoplayMediaPastThresholdWithoutUserInterference:
2118                 return kWKAutoplayEventDidAutoplayMediaPastThresholdWithoutUserInterference;
2119             case WebCore::AutoplayEvent::DidPlayMediaPreventedFromPlaying:
2120                 return kWKAutoplayEventDidPlayMediaPreventedFromAutoplaying;
2121             case WebCore::AutoplayEvent::DidPreventMediaFromPlaying:
2122                 return kWKAutoplayEventDidPreventFromAutoplaying;
2123             case WebCore::AutoplayEvent::UserDidInterfereWithPlayback:
2124                 return kWKAutoplayEventUserDidInterfereWithPlayback;
2125             }
2126
2127             RELEASE_ASSERT_NOT_REACHED();
2128         }
2129
2130         void handleAutoplayEvent(WebPageProxy& page, WebCore::AutoplayEvent event, OptionSet<WebCore::AutoplayEventFlags> flags) final
2131         {
2132             if (!m_client.handleAutoplayEvent)
2133                 return;
2134
2135             m_client.handleAutoplayEvent(toAPI(&page), toWKAutoplayEvent(event), toWKAutoplayEventFlags(flags), m_client.base.clientInfo);
2136         }
2137     };
2138
2139     toImpl(pageRef)->setUIClient(std::make_unique<UIClient>(wkClient));
2140 }
2141
2142 void WKPageSetPageNavigationClient(WKPageRef pageRef, const WKPageNavigationClientBase* wkClient)
2143 {
2144     class NavigationClient : public API::Client<WKPageNavigationClientBase>, public API::NavigationClient {
2145     public:
2146         explicit NavigationClient(const WKPageNavigationClientBase* client)
2147         {
2148             initialize(client);
2149         }
2150
2151     private:
2152         void decidePolicyForNavigationAction(WebPageProxy& page, Ref<API::NavigationAction>&& navigationAction, Ref<WebKit::WebFramePolicyListenerProxy>&& listener, API::Object* userData) final
2153         {
2154             if (!m_client.decidePolicyForNavigationAction) {
2155                 listener->use({ });
2156                 return;
2157             }
2158             m_client.decidePolicyForNavigationAction(toAPI(&page), toAPI(navigationAction.ptr()), toAPI(listener.ptr()), toAPI(userData), m_client.base.clientInfo);
2159         }
2160
2161         void decidePolicyForNavigationResponse(WebPageProxy& page, API::NavigationResponse& navigationResponse, Ref<WebKit::WebFramePolicyListenerProxy>&& listener, API::Object* userData) override
2162         {
2163             if (!m_client.decidePolicyForNavigationResponse) {
2164                 listener->use({ });
2165                 return;
2166             }
2167             m_client.decidePolicyForNavigationResponse(toAPI(&page), toAPI(&navigationResponse), toAPI(listener.ptr()), toAPI(userData), m_client.base.clientInfo);
2168         }
2169
2170         void didStartProvisionalNavigation(WebPageProxy& page, API::Navigation* navigation, API::Object* userData) override
2171         {
2172             if (!m_client.didStartProvisionalNavigation)
2173                 return;
2174             m_client.didStartProvisionalNavigation(toAPI(&page), toAPI(navigation), toAPI(userData), m_client.base.clientInfo);
2175         }
2176
2177         void didReceiveServerRedirectForProvisionalNavigation(WebPageProxy& page, API::Navigation* navigation, API::Object* userData) override
2178         {
2179             if (!m_client.didReceiveServerRedirectForProvisionalNavigation)
2180                 return;
2181             m_client.didReceiveServerRedirectForProvisionalNavigation(toAPI(&page), toAPI(navigation), toAPI(userData), m_client.base.clientInfo);
2182         }
2183
2184         void didFailProvisionalNavigationWithError(WebPageProxy& page, WebFrameProxy&, API::Navigation* navigation, const WebCore::ResourceError& error, API::Object* userData) override
2185         {
2186             if (!m_client.didFailProvisionalNavigation)
2187                 return;
2188             m_client.didFailProvisionalNavigation(toAPI(&page), toAPI(navigation), toAPI(error), toAPI(userData), m_client.base.clientInfo);
2189         }
2190
2191         void didCommitNavigation(WebPageProxy& page, API::Navigation* navigation, API::Object* userData) override
2192         {
2193             if (!m_client.didCommitNavigation)
2194                 return;
2195             m_client.didCommitNavigation(toAPI(&page), toAPI(navigation), toAPI(userData), m_client.base.clientInfo);
2196         }
2197
2198         void didFinishNavigation(WebPageProxy& page, API::Navigation* navigation, API::Object* userData) override
2199         {
2200             if (!m_client.didFinishNavigation)
2201                 return;
2202             m_client.didFinishNavigation(toAPI(&page), toAPI(navigation), toAPI(userData), m_client.base.clientInfo);
2203         }
2204
2205         void didFailNavigationWithError(WebPageProxy& page, WebFrameProxy&, API::Navigation* navigation, const WebCore::ResourceError& error, API::Object* userData) override
2206         {
2207             if (!m_client.didFailNavigation)
2208                 return;
2209             m_client.didFailNavigation(toAPI(&page), toAPI(navigation), toAPI(error), toAPI(userData), m_client.base.clientInfo);
2210         }
2211
2212         void didFailProvisionalLoadInSubframeWithError(WebPageProxy& page, WebFrameProxy& subframe, const WebCore::SecurityOriginData& securityOriginData, API::Navigation* navigation, const WebCore::ResourceError& error, API::Object* userData) override
2213         {
2214             if (!m_client.didFailProvisionalLoadInSubframe)
2215                 return;
2216             m_client.didFailProvisionalLoadInSubframe(toAPI(&page), toAPI(navigation), toAPI(API::FrameInfo::create(subframe, securityOriginData.securityOrigin()).ptr()), toAPI(error), toAPI(userData), m_client.base.clientInfo);
2217         }
2218
2219         void didFinishDocumentLoad(WebPageProxy& page, API::Navigation* navigation, API::Object* userData) override
2220         {
2221             if (!m_client.didFinishDocumentLoad)
2222                 return;
2223             m_client.didFinishDocumentLoad(toAPI(&page), toAPI(navigation), toAPI(userData), m_client.base.clientInfo);
2224         }
2225
2226         void didSameDocumentNavigation(WebPageProxy& page, API::Navigation* navigation, WebKit::SameDocumentNavigationType navigationType, API::Object* userData) override
2227         {
2228             if (!m_client.didSameDocumentNavigation)
2229                 return;
2230             m_client.didSameDocumentNavigation(toAPI(&page), toAPI(navigation), toAPI(navigationType), toAPI(userData), m_client.base.clientInfo);
2231         }
2232         
2233         void renderingProgressDidChange(WebPageProxy& page, WebCore::LayoutMilestones milestones) override
2234         {
2235             if (!m_client.renderingProgressDidChange)
2236                 return;
2237             m_client.renderingProgressDidChange(toAPI(&page), pageRenderingProgressEvents(milestones), nullptr, m_client.base.clientInfo);
2238         }
2239         
2240         bool canAuthenticateAgainstProtectionSpace(WebPageProxy& page, WebProtectionSpace* protectionSpace) override
2241         {
2242             if (!m_client.canAuthenticateAgainstProtectionSpace)
2243                 return false;
2244             return m_client.canAuthenticateAgainstProtectionSpace(toAPI(&page), toAPI(protectionSpace), m_client.base.clientInfo);
2245         }
2246         
2247         void didReceiveAuthenticationChallenge(WebPageProxy& page, AuthenticationChallengeProxy* authenticationChallenge) override
2248         {
2249             if (!m_client.didReceiveAuthenticationChallenge)
2250                 return;
2251             m_client.didReceiveAuthenticationChallenge(toAPI(&page), toAPI(authenticationChallenge), m_client.base.clientInfo);
2252         }
2253
2254         void processDidTerminate(WebPageProxy& page, WebKit::ProcessTerminationReason reason) override
2255         {
2256             if (m_client.webProcessDidTerminate) {
2257                 m_client.webProcessDidTerminate(toAPI(&page), toAPI(reason), m_client.base.clientInfo);
2258                 return;
2259             }
2260
2261             if (m_client.webProcessDidCrash && reason != WebKit::ProcessTerminationReason::RequestedByClient)
2262                 m_client.webProcessDidCrash(toAPI(&page), m_client.base.clientInfo);
2263         }
2264
2265         RefPtr<API::Data> webCryptoMasterKey(WebPageProxy& page) override
2266         {
2267             if (m_client.copyWebCryptoMasterKey)
2268                 return adoptRef(toImpl(m_client.copyWebCryptoMasterKey(toAPI(&page), m_client.base.clientInfo)));
2269
2270             Vector<uint8_t> masterKey;
2271 #if ENABLE(SUBTLE_CRYPTO)
2272             if (!getDefaultWebCryptoMasterKey(masterKey))
2273                 return nullptr;
2274 #endif
2275
2276             return API::Data::create(masterKey.data(), masterKey.size());
2277         }
2278
2279         void didBeginNavigationGesture(WebPageProxy& page) override
2280         {
2281             if (!m_client.didBeginNavigationGesture)
2282                 return;
2283             m_client.didBeginNavigationGesture(toAPI(&page), m_client.base.clientInfo);
2284         }
2285
2286         void didEndNavigationGesture(WebPageProxy& page, bool willNavigate, WebKit::WebBackForwardListItem& item) override
2287         {
2288             if (!m_client.didEndNavigationGesture)
2289                 return;
2290             m_client.didEndNavigationGesture(toAPI(&page), willNavigate ? toAPI(&item) : nullptr, m_client.base.clientInfo);
2291         }
2292
2293         void willEndNavigationGesture(WebPageProxy& page, bool willNavigate, WebKit::WebBackForwardListItem& item) override
2294         {
2295             if (!m_client.willEndNavigationGesture)
2296                 return;
2297             m_client.willEndNavigationGesture(toAPI(&page), willNavigate ? toAPI(&item) : nullptr, m_client.base.clientInfo);
2298         }
2299
2300         void didRemoveNavigationGestureSnapshot(WebPageProxy& page) override
2301         {
2302             if (!m_client.didRemoveNavigationGestureSnapshot)
2303                 return;
2304             m_client.didRemoveNavigationGestureSnapshot(toAPI(&page), m_client.base.clientInfo);
2305         }
2306         
2307 #if ENABLE(NETSCAPE_PLUGIN_API)
2308         PluginModuleLoadPolicy decidePolicyForPluginLoad(WebPageProxy& page, PluginModuleLoadPolicy currentPluginLoadPolicy, API::Dictionary* pluginInformation, String& unavailabilityDescription) override
2309         {
2310             WKStringRef unavailabilityDescriptionOut = 0;
2311             PluginModuleLoadPolicy loadPolicy = currentPluginLoadPolicy;
2312             
2313             if (m_client.decidePolicyForPluginLoad)
2314                 loadPolicy = toPluginModuleLoadPolicy(m_client.decidePolicyForPluginLoad(toAPI(&page), toWKPluginLoadPolicy(currentPluginLoadPolicy), toAPI(pluginInformation), &unavailabilityDescriptionOut, m_client.base.clientInfo));
2315             
2316             if (unavailabilityDescriptionOut) {
2317                 RefPtr<API::String> webUnavailabilityDescription = adoptRef(toImpl(unavailabilityDescriptionOut));
2318                 unavailabilityDescription = webUnavailabilityDescription->string();
2319             }
2320             
2321             return loadPolicy;
2322         }
2323 #endif
2324     };
2325
2326     WebPageProxy* webPageProxy = toImpl(pageRef);
2327
2328     auto navigationClient = std::make_unique<NavigationClient>(wkClient);
2329     webPageProxy->setNavigationClient(WTFMove(navigationClient));
2330 }
2331
2332 void WKPageRunJavaScriptInMainFrame(WKPageRef pageRef, WKStringRef scriptRef, void* context, WKPageRunJavaScriptFunction callback)
2333 {
2334     toImpl(pageRef)->runJavaScriptInMainFrame(toImpl(scriptRef)->string(), true, [context, callback](API::SerializedScriptValue* returnValue, bool, const WebCore::ExceptionDetails&, CallbackBase::Error error) {
2335         callback(toAPI(returnValue), (error != CallbackBase::Error::None) ? toAPI(API::Error::create().ptr()) : 0, context);
2336     });
2337 }
2338
2339 #ifdef __BLOCKS__
2340 static void callRunJavaScriptBlockAndRelease(WKSerializedScriptValueRef resultValue, WKErrorRef error, void* context)
2341 {
2342     WKPageRunJavaScriptBlock block = (WKPageRunJavaScriptBlock)context;
2343     block(resultValue, error);
2344     Block_release(block);
2345 }
2346
2347 void WKPageRunJavaScriptInMainFrame_b(WKPageRef pageRef, WKStringRef scriptRef, WKPageRunJavaScriptBlock block)
2348 {
2349     WKPageRunJavaScriptInMainFrame(pageRef, scriptRef, Block_copy(block), callRunJavaScriptBlockAndRelease);
2350 }
2351 #endif
2352
2353 static WTF::Function<void (const String&, WebKit::CallbackBase::Error)> toGenericCallbackFunction(void* context, void (*callback)(WKStringRef, WKErrorRef, void*))
2354 {
2355     return [context, callback](const String& returnValue, WebKit::CallbackBase::Error error) {
2356         callback(toAPI(API::String::create(returnValue).ptr()), error != WebKit::CallbackBase::Error::None ? toAPI(API::Error::create().ptr()) : 0, context);
2357     };
2358 }
2359
2360 void WKPageRenderTreeExternalRepresentation(WKPageRef pageRef, void* context, WKPageRenderTreeExternalRepresentationFunction callback)
2361 {
2362     toImpl(pageRef)->getRenderTreeExternalRepresentation(toGenericCallbackFunction(context, callback));
2363 }
2364
2365 void WKPageGetSourceForFrame(WKPageRef pageRef, WKFrameRef frameRef, void* context, WKPageGetSourceForFrameFunction callback)
2366 {
2367     toImpl(pageRef)->getSourceForFrame(toImpl(frameRef), toGenericCallbackFunction(context, callback));
2368 }
2369
2370 void WKPageGetContentsAsString(WKPageRef pageRef, void* context, WKPageGetContentsAsStringFunction callback)
2371 {
2372     toImpl(pageRef)->getContentsAsString(toGenericCallbackFunction(context, callback));
2373 }
2374
2375 void WKPageGetBytecodeProfile(WKPageRef pageRef, void* context, WKPageGetBytecodeProfileFunction callback)
2376 {
2377     toImpl(pageRef)->getBytecodeProfile(toGenericCallbackFunction(context, callback));
2378 }
2379
2380 void WKPageGetSamplingProfilerOutput(WKPageRef pageRef, void* context, WKPageGetSamplingProfilerOutputFunction callback)
2381 {
2382     toImpl(pageRef)->getSamplingProfilerOutput(toGenericCallbackFunction(context, callback));
2383 }
2384
2385 void WKPageIsWebProcessResponsive(WKPageRef pageRef, void* context, WKPageIsWebProcessResponsiveFunction callback)
2386 {
2387     toImpl(pageRef)->isWebProcessResponsive([context, callback](bool isWebProcessResponsive) {
2388         callback(isWebProcessResponsive, context);
2389     });
2390 }
2391
2392 void WKPageGetSelectionAsWebArchiveData(WKPageRef pageRef, void* context, WKPageGetSelectionAsWebArchiveDataFunction callback)
2393 {
2394     toImpl(pageRef)->getSelectionAsWebArchiveData(toGenericCallbackFunction(context, callback));
2395 }
2396
2397 void WKPageGetContentsAsMHTMLData(WKPageRef pageRef, void* context, WKPageGetContentsAsMHTMLDataFunction callback)
2398 {
2399 #if ENABLE(MHTML)
2400     toImpl(pageRef)->getContentsAsMHTMLData(toGenericCallbackFunction(context, callback));
2401 #else
2402     UNUSED_PARAM(pageRef);
2403     UNUSED_PARAM(context);
2404     UNUSED_PARAM(callback);
2405 #endif
2406 }
2407
2408 void WKPageForceRepaint(WKPageRef pageRef, void* context, WKPageForceRepaintFunction callback)
2409 {
2410     toImpl(pageRef)->forceRepaint(VoidCallback::create([context, callback](WebKit::CallbackBase::Error error) {
2411         callback(error == WebKit::CallbackBase::Error::None ? nullptr : toAPI(API::Error::create().ptr()), context);
2412     }));
2413 }
2414
2415 WK_EXPORT WKURLRef WKPageCopyPendingAPIRequestURL(WKPageRef pageRef)
2416 {
2417     const String& pendingAPIRequestURL = toImpl(pageRef)->pageLoadState().pendingAPIRequestURL();
2418
2419     if (pendingAPIRequestURL.isNull())
2420         return nullptr;
2421
2422     return toCopiedURLAPI(pendingAPIRequestURL);
2423 }
2424
2425 WKURLRef WKPageCopyActiveURL(WKPageRef pageRef)
2426 {
2427     return toCopiedURLAPI(toImpl(pageRef)->pageLoadState().activeURL());
2428 }
2429
2430 WKURLRef WKPageCopyProvisionalURL(WKPageRef pageRef)
2431 {
2432     return toCopiedURLAPI(toImpl(pageRef)->pageLoadState().provisionalURL());
2433 }
2434
2435 WKURLRef WKPageCopyCommittedURL(WKPageRef pageRef)
2436 {
2437     return toCopiedURLAPI(toImpl(pageRef)->pageLoadState().url());
2438 }
2439
2440 WKStringRef WKPageCopyStandardUserAgentWithApplicationName(WKStringRef applicationName)
2441 {
2442     return toCopiedAPI(WebPageProxy::standardUserAgent(toImpl(applicationName)->string()));
2443 }
2444
2445 void WKPageValidateCommand(WKPageRef pageRef, WKStringRef command, void* context, WKPageValidateCommandCallback callback)
2446 {
2447     toImpl(pageRef)->validateCommand(toImpl(command)->string(), [context, callback](const String& commandName, bool isEnabled, int32_t state, WebKit::CallbackBase::Error error) {
2448         callback(toAPI(API::String::create(commandName).ptr()), isEnabled, state, error != WebKit::CallbackBase::Error::None ? toAPI(API::Error::create().ptr()) : 0, context);
2449     });
2450 }
2451
2452 void WKPageExecuteCommand(WKPageRef pageRef, WKStringRef command)
2453 {
2454     toImpl(pageRef)->executeEditCommand(toImpl(command)->string());
2455 }
2456
2457 #if PLATFORM(COCOA)
2458 static PrintInfo printInfoFromWKPrintInfo(const WKPrintInfo& printInfo)
2459 {
2460     PrintInfo result;
2461     result.pageSetupScaleFactor = printInfo.pageSetupScaleFactor;
2462     result.availablePaperWidth = printInfo.availablePaperWidth;
2463     result.availablePaperHeight = printInfo.availablePaperHeight;
2464     return result;
2465 }
2466
2467 void WKPageComputePagesForPrinting(WKPageRef page, WKFrameRef frame, WKPrintInfo printInfo, WKPageComputePagesForPrintingFunction callback, void* context)
2468 {
2469     toImpl(page)->computePagesForPrinting(toImpl(frame), printInfoFromWKPrintInfo(printInfo), ComputedPagesCallback::create([context, callback](const Vector<WebCore::IntRect>& rects, double scaleFactor, WebKit::CallbackBase::Error error) {
2470         Vector<WKRect> wkRects(rects.size());
2471         for (size_t i = 0; i < rects.size(); ++i)
2472             wkRects[i] = toAPI(rects[i]);
2473         callback(wkRects.data(), wkRects.size(), scaleFactor, error != WebKit::CallbackBase::Error::None ? toAPI(API::Error::create().ptr()) : 0, context);
2474     }));
2475 }
2476
2477 void WKPageBeginPrinting(WKPageRef page, WKFrameRef frame, WKPrintInfo printInfo)
2478 {
2479     toImpl(page)->beginPrinting(toImpl(frame), printInfoFromWKPrintInfo(printInfo));
2480 }
2481
2482 void WKPageDrawPagesToPDF(WKPageRef page, WKFrameRef frame, WKPrintInfo printInfo, uint32_t first, uint32_t count, WKPageDrawToPDFFunction callback, void* context)
2483 {
2484     toImpl(page)->drawPagesToPDF(toImpl(frame), printInfoFromWKPrintInfo(printInfo), first, count, DataCallback::create(toGenericCallbackFunction(context, callback)));
2485 }
2486
2487 void WKPageEndPrinting(WKPageRef page)
2488 {
2489     toImpl(page)->endPrinting();
2490 }
2491 #endif
2492
2493 bool WKPageGetIsControlledByAutomation(WKPageRef page)
2494 {
2495     return toImpl(page)->isControlledByAutomation();
2496 }
2497
2498 void WKPageSetControlledByAutomation(WKPageRef page, bool controlled)
2499 {
2500     toImpl(page)->setControlledByAutomation(controlled);
2501 }
2502
2503 bool WKPageGetAllowsRemoteInspection(WKPageRef page)
2504 {
2505 #if ENABLE(REMOTE_INSPECTOR)
2506     return toImpl(page)->allowsRemoteInspection();
2507 #else
2508     UNUSED_PARAM(page);
2509     return false;
2510 #endif    
2511 }
2512
2513 void WKPageSetAllowsRemoteInspection(WKPageRef page, bool allow)
2514 {
2515 #if ENABLE(REMOTE_INSPECTOR)
2516     toImpl(page)->setAllowsRemoteInspection(allow);
2517 #else
2518     UNUSED_PARAM(page);
2519     UNUSED_PARAM(allow);
2520 #endif
2521 }
2522
2523 void WKPageSetMediaVolume(WKPageRef page, float volume)
2524 {
2525     toImpl(page)->setMediaVolume(volume);    
2526 }
2527
2528 void WKPageSetMuted(WKPageRef page, WKMediaMutedState muted)
2529 {
2530     toImpl(page)->setMuted(muted);
2531 }
2532
2533 void WKPageSetMediaCaptureEnabled(WKPageRef page, bool enabled)
2534 {
2535     toImpl(page)->setMediaCaptureEnabled(enabled);
2536 }
2537
2538 bool WKPageGetMediaCaptureEnabled(WKPageRef page)
2539 {
2540     return toImpl(page)->mediaCaptureEnabled();
2541 }
2542
2543 void WKPageDidAllowPointerLock(WKPageRef page)
2544 {
2545 #if ENABLE(POINTER_LOCK)
2546     toImpl(page)->didAllowPointerLock();
2547 #else
2548     UNUSED_PARAM(page);
2549 #endif
2550 }
2551
2552 void WKPageClearUserMediaState(WKPageRef page)
2553 {
2554 #if ENABLE(MEDIA_STREAM)
2555     toImpl(page)->clearUserMediaState();
2556 #else
2557     UNUSED_PARAM(page);
2558 #endif
2559 }
2560
2561 void WKPageDidDenyPointerLock(WKPageRef page)
2562 {
2563 #if ENABLE(POINTER_LOCK)
2564     toImpl(page)->didDenyPointerLock();
2565 #else
2566     UNUSED_PARAM(page);
2567 #endif
2568 }
2569
2570 bool WKPageHasMediaSessionWithActiveMediaElements(WKPageRef page)
2571 {
2572 #if ENABLE(MEDIA_SESSION)
2573     return toImpl(page)->hasMediaSessionWithActiveMediaElements();
2574 #else
2575     UNUSED_PARAM(page);
2576     return false;
2577 #endif
2578 }
2579
2580 void WKPageHandleMediaEvent(WKPageRef page, WKMediaEventType wkEventType)
2581 {
2582 #if ENABLE(MEDIA_SESSION)
2583     MediaEventType eventType;
2584
2585     switch (wkEventType) {
2586     case kWKMediaEventTypePlayPause:
2587         eventType = MediaEventType::PlayPause;
2588         break;
2589     case kWKMediaEventTypeTrackNext:
2590         eventType = MediaEventType::TrackNext;
2591         break;
2592     case kWKMediaEventTypeTrackPrevious:
2593         eventType = MediaEventType::TrackPrevious;
2594         break;
2595     default:
2596         ASSERT_NOT_REACHED();
2597         return;
2598     }
2599
2600     toImpl(page)->handleMediaEvent(eventType);
2601 #else
2602     UNUSED_PARAM(page);
2603     UNUSED_PARAM(wkEventType);
2604 #endif
2605 }
2606
2607 void WKPagePostMessageToInjectedBundle(WKPageRef pageRef, WKStringRef messageNameRef, WKTypeRef messageBodyRef)
2608 {
2609     toImpl(pageRef)->postMessageToInjectedBundle(toImpl(messageNameRef)->string(), toImpl(messageBodyRef));
2610 }
2611
2612 WKArrayRef WKPageCopyRelatedPages(WKPageRef pageRef)
2613 {
2614     Vector<RefPtr<API::Object>> relatedPages;
2615
2616     for (auto& page : toImpl(pageRef)->process().pages()) {
2617         if (page != toImpl(pageRef))
2618             relatedPages.append(page);
2619     }
2620
2621     return toAPI(&API::Array::create(WTFMove(relatedPages)).leakRef());
2622 }
2623
2624 WKFrameRef WKPageLookUpFrameFromHandle(WKPageRef pageRef, WKFrameHandleRef handleRef)
2625 {
2626     auto page = toImpl(pageRef);
2627     auto frame = page->process().webFrame(toImpl(handleRef)->frameID());
2628     if (!frame || frame->page() != page)
2629         return nullptr;
2630
2631     return toAPI(frame);
2632 }
2633
2634 void WKPageSetMayStartMediaWhenInWindow(WKPageRef pageRef, bool mayStartMedia)
2635 {
2636     toImpl(pageRef)->setMayStartMediaWhenInWindow(mayStartMedia);
2637 }
2638
2639
2640 void WKPageSelectContextMenuItem(WKPageRef page, WKContextMenuItemRef item)
2641 {
2642 #if ENABLE(CONTEXT_MENUS)
2643     toImpl(page)->contextMenuItemSelected((toImpl(item)->data()));
2644 #else
2645     UNUSED_PARAM(page);
2646     UNUSED_PARAM(item);
2647 #endif
2648 }
2649
2650 WKScrollPinningBehavior WKPageGetScrollPinningBehavior(WKPageRef page)
2651 {
2652     ScrollPinningBehavior pinning = toImpl(page)->scrollPinningBehavior();
2653     
2654     switch (pinning) {
2655     case WebCore::ScrollPinningBehavior::DoNotPin:
2656         return kWKScrollPinningBehaviorDoNotPin;
2657     case WebCore::ScrollPinningBehavior::PinToTop:
2658         return kWKScrollPinningBehaviorPinToTop;
2659     case WebCore::ScrollPinningBehavior::PinToBottom:
2660         return kWKScrollPinningBehaviorPinToBottom;
2661     }
2662     
2663     ASSERT_NOT_REACHED();
2664     return kWKScrollPinningBehaviorDoNotPin;
2665 }
2666
2667 void WKPageSetScrollPinningBehavior(WKPageRef page, WKScrollPinningBehavior pinning)
2668 {
2669     ScrollPinningBehavior corePinning = ScrollPinningBehavior::DoNotPin;
2670
2671     switch (pinning) {
2672     case kWKScrollPinningBehaviorDoNotPin:
2673         corePinning = ScrollPinningBehavior::DoNotPin;
2674         break;
2675     case kWKScrollPinningBehaviorPinToTop:
2676         corePinning = ScrollPinningBehavior::PinToTop;
2677         break;
2678     case kWKScrollPinningBehaviorPinToBottom:
2679         corePinning = ScrollPinningBehavior::PinToBottom;
2680         break;
2681     default:
2682         ASSERT_NOT_REACHED();
2683     }
2684     
2685     toImpl(page)->setScrollPinningBehavior(corePinning);
2686 }
2687
2688 bool WKPageGetAddsVisitedLinks(WKPageRef page)
2689 {
2690     return toImpl(page)->addsVisitedLinks();
2691 }
2692
2693 void WKPageSetAddsVisitedLinks(WKPageRef page, bool addsVisitedLinks)
2694 {
2695     toImpl(page)->setAddsVisitedLinks(addsVisitedLinks);
2696 }
2697
2698 bool WKPageIsPlayingAudio(WKPageRef page)
2699 {
2700     return toImpl(page)->isPlayingAudio();
2701 }
2702
2703 WKMediaState WKPageGetMediaState(WKPageRef page)
2704 {
2705     WebCore::MediaProducer::MediaStateFlags coreState = toImpl(page)->mediaStateFlags();
2706     WKMediaState state = kWKMediaIsNotPlaying;
2707
2708     if (coreState & WebCore::MediaProducer::IsPlayingAudio)
2709         state |= kWKMediaIsPlayingAudio;
2710     if (coreState & WebCore::MediaProducer::IsPlayingVideo)
2711         state |= kWKMediaIsPlayingVideo;
2712     if (coreState & WebCore::MediaProducer::HasActiveAudioCaptureDevice)
2713         state |= kWKMediaHasActiveAudioCaptureDevice;
2714     if (coreState & WebCore::MediaProducer::HasActiveVideoCaptureDevice)
2715         state |= kWKMediaHasActiveVideoCaptureDevice;
2716     if (coreState & WebCore::MediaProducer::HasMutedAudioCaptureDevice)
2717         state |= kWKMediaHasMutedAudioCaptureDevice;
2718     if (coreState & WebCore::MediaProducer::HasMutedVideoCaptureDevice)
2719         state |= kWKMediaHasMutedVideoCaptureDevice;
2720
2721     return state;
2722 }
2723
2724 void WKPageClearWheelEventTestTrigger(WKPageRef pageRef)
2725 {
2726     toImpl(pageRef)->clearWheelEventTestTrigger();
2727 }
2728
2729 void WKPageCallAfterNextPresentationUpdate(WKPageRef pageRef, void* context, WKPagePostPresentationUpdateFunction callback)
2730 {
2731     toImpl(pageRef)->callAfterNextPresentationUpdate([context, callback](WebKit::CallbackBase::Error error) {
2732         callback(error != WebKit::CallbackBase::Error::None ? toAPI(API::Error::create().ptr()) : 0, context);
2733     });
2734 }
2735
2736 bool WKPageGetResourceCachingDisabled(WKPageRef page)
2737 {
2738     return toImpl(page)->isResourceCachingDisabled();
2739 }
2740
2741 void WKPageSetResourceCachingDisabled(WKPageRef page, bool disabled)
2742 {
2743     toImpl(page)->setResourceCachingDisabled(disabled);
2744 }
2745
2746 void WKPageSetIgnoresViewportScaleLimits(WKPageRef page, bool ignoresViewportScaleLimits)
2747 {
2748 #if PLATFORM(IOS)
2749     toImpl(page)->setForceAlwaysUserScalable(ignoresViewportScaleLimits);
2750 #endif
2751 }
2752
2753 pid_t WKPageGetProcessIdentifier(WKPageRef page)
2754 {
2755     return toImpl(page)->processIdentifier();
2756 }