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