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