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