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