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