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