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