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