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 if (shouldReturnData)
484 return toAPI(encodeLegacySessionState(sessionState).leakRef());
485
486 return toAPI(&API::SessionState::create(WTFMove(sessionState)).leakRef());
487}
488
489static void restoreFromSessionState(WKPageRef pageRef, WKTypeRef sessionStateRef, bool navigate)
490{
491 SessionState sessionState;
492
493 // FIXME: This is for backwards compatibility with Safari. Remove it once Safari no longer depends on it.
494 if (toImpl(sessionStateRef)->type() == API::Object::Type::Data) {
495 if (!decodeLegacySessionState(toImpl(static_cast<WKDataRef>(sessionStateRef))->bytes(), toImpl(static_cast<WKDataRef>(sessionStateRef))->size(), sessionState))
496 return;
497 } else {
498 ASSERT(toImpl(sessionStateRef)->type() == API::Object::Type::SessionState);
499
500 sessionState = toImpl(static_cast<WKSessionStateRef>(sessionStateRef))->sessionState();
501 }
502
503 toImpl(pageRef)->restoreFromSessionState(WTFMove(sessionState), navigate);
504}
505
506void WKPageRestoreFromSessionState(WKPageRef pageRef, WKTypeRef sessionStateRef)
507{
508 restoreFromSessionState(pageRef, sessionStateRef, true);
509}
510
511void WKPageRestoreFromSessionStateWithoutNavigation(WKPageRef pageRef, WKTypeRef sessionStateRef)
512{
513 restoreFromSessionState(pageRef, sessionStateRef, false);
514}
515
516double WKPageGetTextZoomFactor(WKPageRef pageRef)
517{
518 return toImpl(pageRef)->textZoomFactor();
519}
520
521double WKPageGetBackingScaleFactor(WKPageRef pageRef)
522{
523 return toImpl(pageRef)->deviceScaleFactor();
524}
525
526void WKPageSetCustomBackingScaleFactor(WKPageRef pageRef, double customScaleFactor)
527{
528 toImpl(pageRef)->setCustomDeviceScaleFactor(customScaleFactor);
529}
530
531bool WKPageSupportsTextZoom(WKPageRef pageRef)
532{
533 return toImpl(pageRef)->supportsTextZoom();
534}
535
536void WKPageSetTextZoomFactor(WKPageRef pageRef, double zoomFactor)
537{
538 toImpl(pageRef)->setTextZoomFactor(zoomFactor);
539}
540
541double WKPageGetPageZoomFactor(WKPageRef pageRef)
542{
543 return toImpl(pageRef)->pageZoomFactor();
544}
545
546void WKPageSetPageZoomFactor(WKPageRef pageRef, double zoomFactor)
547{
548 toImpl(pageRef)->setPageZoomFactor(zoomFactor);
549}
550
551void WKPageSetPageAndTextZoomFactors(WKPageRef pageRef, double pageZoomFactor, double textZoomFactor)
552{
553 toImpl(pageRef)->setPageAndTextZoomFactors(pageZoomFactor, textZoomFactor);
554}
555
556void WKPageSetScaleFactor(WKPageRef pageRef, double scale, WKPoint origin)
557{
558 toImpl(pageRef)->scalePage(scale, toIntPoint(origin));
559}
560
561double WKPageGetScaleFactor(WKPageRef pageRef)
562{
563 return toImpl(pageRef)->pageScaleFactor();
564}
565
566void WKPageSetUseFixedLayout(WKPageRef pageRef, bool fixed)
567{
568 toImpl(pageRef)->setUseFixedLayout(fixed);
569}
570
571void WKPageSetFixedLayoutSize(WKPageRef pageRef, WKSize size)
572{
573 toImpl(pageRef)->setFixedLayoutSize(toIntSize(size));
574}
575
576bool WKPageUseFixedLayout(WKPageRef pageRef)
577{
578 return toImpl(pageRef)->useFixedLayout();
579}
580
581WKSize WKPageFixedLayoutSize(WKPageRef pageRef)
582{
583 return toAPI(toImpl(pageRef)->fixedLayoutSize());
584}
585
586void WKPageListenForLayoutMilestones(WKPageRef pageRef, WKLayoutMilestones milestones)
587{
588 toImpl(pageRef)->listenForLayoutMilestones(toLayoutMilestones(milestones));
589}
590
591bool WKPageHasHorizontalScrollbar(WKPageRef pageRef)
592{
593 return toImpl(pageRef)->hasHorizontalScrollbar();
594}
595
596bool WKPageHasVerticalScrollbar(WKPageRef pageRef)
597{
598 return toImpl(pageRef)->hasVerticalScrollbar();
599}
600
601void WKPageSetSuppressScrollbarAnimations(WKPageRef pageRef, bool suppressAnimations)
602{
603 toImpl(pageRef)->setSuppressScrollbarAnimations(suppressAnimations);
604}
605
606bool WKPageAreScrollbarAnimationsSuppressed(WKPageRef pageRef)
607{
608 return toImpl(pageRef)->areScrollbarAnimationsSuppressed();
609}
610
611bool WKPageIsPinnedToLeftSide(WKPageRef pageRef)
612{
613 return toImpl(pageRef)->isPinnedToLeftSide();
614}
615
616bool WKPageIsPinnedToRightSide(WKPageRef pageRef)
617{
618 return toImpl(pageRef)->isPinnedToRightSide();
619}
620
621bool WKPageIsPinnedToTopSide(WKPageRef pageRef)
622{
623 return toImpl(pageRef)->isPinnedToTopSide();
624}
625
626bool WKPageIsPinnedToBottomSide(WKPageRef pageRef)
627{
628 return toImpl(pageRef)->isPinnedToBottomSide();
629}
630
631bool WKPageRubberBandsAtLeft(WKPageRef pageRef)
632{
633 return toImpl(pageRef)->rubberBandsAtLeft();
634}
635
636void WKPageSetRubberBandsAtLeft(WKPageRef pageRef, bool rubberBandsAtLeft)
637{
638 toImpl(pageRef)->setRubberBandsAtLeft(rubberBandsAtLeft);
639}
640
641bool WKPageRubberBandsAtRight(WKPageRef pageRef)
642{
643 return toImpl(pageRef)->rubberBandsAtRight();
644}
645
646void WKPageSetRubberBandsAtRight(WKPageRef pageRef, bool rubberBandsAtRight)
647{
648 toImpl(pageRef)->setRubberBandsAtRight(rubberBandsAtRight);
649}
650
651bool WKPageRubberBandsAtTop(WKPageRef pageRef)
652{
653 return toImpl(pageRef)->rubberBandsAtTop();
654}
655
656void WKPageSetRubberBandsAtTop(WKPageRef pageRef, bool rubberBandsAtTop)
657{
658 toImpl(pageRef)->setRubberBandsAtTop(rubberBandsAtTop);
659}
660
661bool WKPageRubberBandsAtBottom(WKPageRef pageRef)
662{
663 return toImpl(pageRef)->rubberBandsAtBottom();
664}
665
666void WKPageSetRubberBandsAtBottom(WKPageRef pageRef, bool rubberBandsAtBottom)
667{
668 toImpl(pageRef)->setRubberBandsAtBottom(rubberBandsAtBottom);
669}
670
671bool WKPageVerticalRubberBandingIsEnabled(WKPageRef pageRef)
672{
673 return toImpl(pageRef)->verticalRubberBandingIsEnabled();
674}
675
676void WKPageSetEnableVerticalRubberBanding(WKPageRef pageRef, bool enableVerticalRubberBanding)
677{
678 toImpl(pageRef)->setEnableVerticalRubberBanding(enableVerticalRubberBanding);
679}
680
681bool WKPageHorizontalRubberBandingIsEnabled(WKPageRef pageRef)
682{
683 return toImpl(pageRef)->horizontalRubberBandingIsEnabled();
684}
685
686void WKPageSetEnableHorizontalRubberBanding(WKPageRef pageRef, bool enableHorizontalRubberBanding)
687{
688 toImpl(pageRef)->setEnableHorizontalRubberBanding(enableHorizontalRubberBanding);
689}
690
691void WKPageSetBackgroundExtendsBeyondPage(WKPageRef pageRef, bool backgroundExtendsBeyondPage)
692{
693 toImpl(pageRef)->setBackgroundExtendsBeyondPage(backgroundExtendsBeyondPage);
694}
695
696bool WKPageBackgroundExtendsBeyondPage(WKPageRef pageRef)
697{
698 return toImpl(pageRef)->backgroundExtendsBeyondPage();
699}
700
701void WKPageSetPaginationMode(WKPageRef pageRef, WKPaginationMode paginationMode)
702{
703 WebCore::Pagination::Mode mode;
704 switch (paginationMode) {
705 case kWKPaginationModeUnpaginated:
706 mode = WebCore::Pagination::Unpaginated;
707 break;
708 case kWKPaginationModeLeftToRight:
709 mode = WebCore::Pagination::LeftToRightPaginated;
710 break;
711 case kWKPaginationModeRightToLeft:
712 mode = WebCore::Pagination::RightToLeftPaginated;
713 break;
714 case kWKPaginationModeTopToBottom:
715 mode = WebCore::Pagination::TopToBottomPaginated;
716 break;
717 case kWKPaginationModeBottomToTop:
718 mode = WebCore::Pagination::BottomToTopPaginated;
719 break;
720 default:
721 return;
722 }
723 toImpl(pageRef)->setPaginationMode(mode);
724}
725
726WKPaginationMode WKPageGetPaginationMode(WKPageRef pageRef)
727{
728 switch (toImpl(pageRef)->paginationMode()) {
729 case WebCore::Pagination::Unpaginated:
730 return kWKPaginationModeUnpaginated;
731 case WebCore::Pagination::LeftToRightPaginated:
732 return kWKPaginationModeLeftToRight;
733 case WebCore::Pagination::RightToLeftPaginated:
734 return kWKPaginationModeRightToLeft;
735 case WebCore::Pagination::TopToBottomPaginated:
736 return kWKPaginationModeTopToBottom;
737 case WebCore::Pagination::BottomToTopPaginated:
738 return kWKPaginationModeBottomToTop;
739 }
740
741 ASSERT_NOT_REACHED();
742 return kWKPaginationModeUnpaginated;
743}
744
745void WKPageSetPaginationBehavesLikeColumns(WKPageRef pageRef, bool behavesLikeColumns)
746{
747 toImpl(pageRef)->setPaginationBehavesLikeColumns(behavesLikeColumns);
748}
749
750bool WKPageGetPaginationBehavesLikeColumns(WKPageRef pageRef)
751{
752 return toImpl(pageRef)->paginationBehavesLikeColumns();
753}
754
755void WKPageSetPageLength(WKPageRef pageRef, double pageLength)
756{
757 toImpl(pageRef)->setPageLength(pageLength);
758}
759
760double WKPageGetPageLength(WKPageRef pageRef)
761{
762 return toImpl(pageRef)->pageLength();
763}
764
765void WKPageSetGapBetweenPages(WKPageRef pageRef, double gap)
766{
767 toImpl(pageRef)->setGapBetweenPages(gap);
768}
769
770double WKPageGetGapBetweenPages(WKPageRef pageRef)
771{
772 return toImpl(pageRef)->gapBetweenPages();
773}
774
775void WKPageSetPaginationLineGridEnabled(WKPageRef pageRef, bool lineGridEnabled)
776{
777 toImpl(pageRef)->setPaginationLineGridEnabled(lineGridEnabled);
778}
779
780bool WKPageGetPaginationLineGridEnabled(WKPageRef pageRef)
781{
782 return toImpl(pageRef)->paginationLineGridEnabled();
783}
784
785unsigned WKPageGetPageCount(WKPageRef pageRef)
786{
787 return toImpl(pageRef)->pageCount();
788}
789
790bool WKPageCanDelete(WKPageRef pageRef)
791{
792 return toImpl(pageRef)->canDelete();
793}
794
795bool WKPageHasSelectedRange(WKPageRef pageRef)
796{
797 return toImpl(pageRef)->hasSelectedRange();
798}
799
800bool WKPageIsContentEditable(WKPageRef pageRef)
801{
802 return toImpl(pageRef)->isContentEditable();
803}
804
805void WKPageSetMaintainsInactiveSelection(WKPageRef pageRef, bool newValue)
806{
807 return toImpl(pageRef)->setMaintainsInactiveSelection(newValue);
808}
809
810void WKPageCenterSelectionInVisibleArea(WKPageRef pageRef)
811{
812 return toImpl(pageRef)->centerSelectionInVisibleArea();
813}
814
815void WKPageFindStringMatches(WKPageRef pageRef, WKStringRef string, WKFindOptions options, unsigned maxMatchCount)
816{
817 toImpl(pageRef)->findStringMatches(toImpl(string)->string(), toFindOptions(options), maxMatchCount);
818}
819
820void WKPageGetImageForFindMatch(WKPageRef pageRef, int32_t matchIndex)
821{
822 toImpl(pageRef)->getImageForFindMatch(matchIndex);
823}
824
825void WKPageSelectFindMatch(WKPageRef pageRef, int32_t matchIndex)
826{
827 toImpl(pageRef)->selectFindMatch(matchIndex);
828}
829
830void WKPageFindString(WKPageRef pageRef, WKStringRef string, WKFindOptions options, unsigned maxMatchCount)
831{
832 toImpl(pageRef)->findString(toImpl(string)->string(), toFindOptions(options), maxMatchCount);
833}
834
835void WKPageHideFindUI(WKPageRef pageRef)
836{
837 toImpl(pageRef)->hideFindUI();
838}
839
840void WKPageCountStringMatches(WKPageRef pageRef, WKStringRef string, WKFindOptions options, unsigned maxMatchCount)
841{
842 toImpl(pageRef)->countStringMatches(toImpl(string)->string(), toFindOptions(options), maxMatchCount);
843}
844
845void WKPageSetPageContextMenuClient(WKPageRef pageRef, const WKPageContextMenuClientBase* wkClient)
846{
847#if ENABLE(CONTEXT_MENUS)
848 class ContextMenuClient final : public API::Client<WKPageContextMenuClientBase>, public API::ContextMenuClient {
849 public:
850 explicit ContextMenuClient(const WKPageContextMenuClientBase* client)
851 {
852 initialize(client);
853 }
854
855 private:
856 void getContextMenuFromProposedMenu(WebPageProxy& page, Vector<Ref<WebKit::WebContextMenuItem>>&& proposedMenuVector, WebKit::WebContextMenuListenerProxy& contextMenuListener, const WebHitTestResultData& hitTestResultData, API::Object* userData) override
857 {
858 if (m_client.base.version >= 4 && m_client.getContextMenuFromProposedMenuAsync) {
859 Vector<RefPtr<API::Object>> proposedMenuItems;
860 proposedMenuItems.reserveInitialCapacity(proposedMenuVector.size());
861
862 for (const auto& menuItem : proposedMenuVector)
863 proposedMenuItems.uncheckedAppend(menuItem.ptr());
864
865 auto webHitTestResult = API::HitTestResult::create(hitTestResultData);
866 m_client.getContextMenuFromProposedMenuAsync(toAPI(&page), toAPI(API::Array::create(WTFMove(proposedMenuItems)).ptr()), toAPI(&contextMenuListener), toAPI(webHitTestResult.ptr()), toAPI(userData), m_client.base.clientInfo);
867 return;
868 }
869
870 if (!m_client.getContextMenuFromProposedMenu && !m_client.getContextMenuFromProposedMenu_deprecatedForUseWithV0) {
871 contextMenuListener.useContextMenuItems(WTFMove(proposedMenuVector));
872 return;
873 }
874
875 if (m_client.base.version >= 2 && !m_client.getContextMenuFromProposedMenu) {
876 contextMenuListener.useContextMenuItems(WTFMove(proposedMenuVector));
877 return;
878 }
879
880 Vector<RefPtr<API::Object>> proposedMenuItems;
881 proposedMenuItems.reserveInitialCapacity(proposedMenuVector.size());
882
883 for (const auto& menuItem : proposedMenuVector)
884 proposedMenuItems.uncheckedAppend(menuItem.ptr());
885
886 WKArrayRef newMenu = nullptr;
887 if (m_client.base.version >= 2) {
888 auto webHitTestResult = API::HitTestResult::create(hitTestResultData);
889 m_client.getContextMenuFromProposedMenu(toAPI(&page), toAPI(API::Array::create(WTFMove(proposedMenuItems)).ptr()), &newMenu, toAPI(webHitTestResult.ptr()), toAPI(userData), m_client.base.clientInfo);
890 } else
891 m_client.getContextMenuFromProposedMenu_deprecatedForUseWithV0(toAPI(&page), toAPI(API::Array::create(WTFMove(proposedMenuItems)).ptr()), &newMenu, toAPI(userData), m_client.base.clientInfo);
892
893 RefPtr<API::Array> array = adoptRef(toImpl(newMenu));
894
895 Vector<Ref<WebContextMenuItem>> customMenu;
896 size_t newSize = array ? array->size() : 0;
897 customMenu.reserveInitialCapacity(newSize);
898 for (size_t i = 0; i < newSize; ++i) {
899 WebContextMenuItem* item = array->at<WebContextMenuItem>(i);
900 if (!item) {
901 LOG(ContextMenu, "New menu entry at index %i is not a WebContextMenuItem", (int)i);
902 continue;
903 }
904
905 customMenu.uncheckedAppend(*item);
906 }
907
908 contextMenuListener.useContextMenuItems(WTFMove(customMenu));
909 }
910
911 void customContextMenuItemSelected(WebPageProxy& page, const WebContextMenuItemData& itemData) override
912 {
913 if (!m_client.customContextMenuItemSelected)
914 return;
915
916 m_client.customContextMenuItemSelected(toAPI(&page), toAPI(WebContextMenuItem::create(itemData).ptr()), m_client.base.clientInfo);
917 }
918
919 bool showContextMenu(WebPageProxy& page, const WebCore::IntPoint& menuLocation, const Vector<Ref<WebContextMenuItem>>& menuItemsVector) override
920 {
921 if (!m_client.showContextMenu)
922 return false;
923
924 Vector<RefPtr<API::Object>> menuItems;
925 menuItems.reserveInitialCapacity(menuItemsVector.size());
926
927 for (const auto& menuItem : menuItemsVector)
928 menuItems.uncheckedAppend(menuItem.ptr());
929
930 m_client.showContextMenu(toAPI(&page), toAPI(menuLocation), toAPI(API::Array::create(WTFMove(menuItems)).ptr()), m_client.base.clientInfo);
931
932 return true;
933 }
934
935 bool hideContextMenu(WebPageProxy& page) override
936 {
937 if (!m_client.hideContextMenu)
938 return false;
939
940 m_client.hideContextMenu(toAPI(&page), m_client.base.clientInfo);
941
942 return true;
943 }
944 };
945
946 toImpl(pageRef)->setContextMenuClient(std::make_unique<ContextMenuClient>(wkClient));
947#else
948 UNUSED_PARAM(pageRef);
949 UNUSED_PARAM(wkClient);
950#endif
951}
952
953void WKPageSetPageDiagnosticLoggingClient(WKPageRef pageRef, const WKPageDiagnosticLoggingClientBase* wkClient)
954{
955 toImpl(pageRef)->setDiagnosticLoggingClient(std::make_unique<WebPageDiagnosticLoggingClient>(wkClient));
956}
957
958void WKPageSetPageFindClient(WKPageRef pageRef, const WKPageFindClientBase* wkClient)
959{
960 class FindClient : public API::Client<WKPageFindClientBase>, public API::FindClient {
961 public:
962 explicit FindClient(const WKPageFindClientBase* client)
963 {
964 initialize(client);
965 }
966
967 private:
968 void didFindString(WebPageProxy* page, const String& string, const Vector<WebCore::IntRect>&, uint32_t matchCount, int32_t, bool didWrapAround) override
969 {
970 if (!m_client.didFindString)
971 return;
972
973 m_client.didFindString(toAPI(page), toAPI(string.impl()), matchCount, m_client.base.clientInfo);
974 }
975
976 void didFailToFindString(WebPageProxy* page, const String& string) override
977 {
978 if (!m_client.didFailToFindString)
979 return;
980
981 m_client.didFailToFindString(toAPI(page), toAPI(string.impl()), m_client.base.clientInfo);
982 }
983
984 void didCountStringMatches(WebPageProxy* page, const String& string, uint32_t matchCount) override
985 {
986 if (!m_client.didCountStringMatches)
987 return;
988
989 m_client.didCountStringMatches(toAPI(page), toAPI(string.impl()), matchCount, m_client.base.clientInfo);
990 }
991 };
992
993 toImpl(pageRef)->setFindClient(std::make_unique<FindClient>(wkClient));
994}
995
996void WKPageSetPageFindMatchesClient(WKPageRef pageRef, const WKPageFindMatchesClientBase* wkClient)
997{
998 class FindMatchesClient : public API::Client<WKPageFindMatchesClientBase>, public API::FindMatchesClient {
999 public:
1000 explicit FindMatchesClient(const WKPageFindMatchesClientBase* client)
1001 {
1002 initialize(client);
1003 }
1004
1005 private:
1006 void didFindStringMatches(WebPageProxy* page, const String& string, const Vector<Vector<WebCore::IntRect>>& matchRects, int32_t index) override
1007 {
1008 if (!m_client.didFindStringMatches)
1009 return;
1010
1011 Vector<RefPtr<API::Object>> matches;
1012 matches.reserveInitialCapacity(matchRects.size());
1013
1014 for (const auto& rects : matchRects) {
1015 Vector<RefPtr<API::Object>> apiRects;
1016 apiRects.reserveInitialCapacity(rects.size());
1017
1018 for (const auto& rect : rects)
1019 apiRects.uncheckedAppend(API::Rect::create(toAPI(rect)));
1020
1021 matches.uncheckedAppend(API::Array::create(WTFMove(apiRects)));
1022 }
1023
1024 m_client.didFindStringMatches(toAPI(page), toAPI(string.impl()), toAPI(API::Array::create(WTFMove(matches)).ptr()), index, m_client.base.clientInfo);
1025 }
1026
1027 void didGetImageForMatchResult(WebPageProxy* page, WebImage* image, int32_t index) override
1028 {
1029 if (!m_client.didGetImageForMatchResult)
1030 return;
1031
1032 m_client.didGetImageForMatchResult(toAPI(page), toAPI(image), index, m_client.base.clientInfo);
1033 }
1034 };
1035
1036 toImpl(pageRef)->setFindMatchesClient(std::make_unique<FindMatchesClient>(wkClient));
1037}
1038
1039void WKPageSetPageInjectedBundleClient(WKPageRef pageRef, const WKPageInjectedBundleClientBase* wkClient)
1040{
1041 toImpl(pageRef)->setInjectedBundleClient(wkClient);
1042}
1043
1044void WKPageSetPageFormClient(WKPageRef pageRef, const WKPageFormClientBase* wkClient)
1045{
1046 toImpl(pageRef)->setFormClient(std::make_unique<WebFormClient>(wkClient));
1047}
1048
1049void WKPageSetPageLoaderClient(WKPageRef pageRef, const WKPageLoaderClientBase* wkClient)
1050{
1051 class LoaderClient : public API::Client<WKPageLoaderClientBase>, public API::LoaderClient {
1052 public:
1053 explicit LoaderClient(const WKPageLoaderClientBase* client)
1054 {
1055 initialize(client);
1056
1057#if !PLATFORM(MAC) || __MAC_OS_X_VERSION_MIN_REQUIRED > 101400
1058 // WKPageSetPageLoaderClient is deprecated. Use WKPageSetPageNavigationClient instead.
1059 RELEASE_ASSERT(!m_client.didFinishDocumentLoadForFrame);
1060 RELEASE_ASSERT(!m_client.didSameDocumentNavigationForFrame);
1061 RELEASE_ASSERT(!m_client.didReceiveTitleForFrame);
1062 RELEASE_ASSERT(!m_client.didFirstLayoutForFrame);
1063 RELEASE_ASSERT(!m_client.didRemoveFrameFromHierarchy);
1064 RELEASE_ASSERT(!m_client.didDisplayInsecureContentForFrame);
1065 RELEASE_ASSERT(!m_client.didRunInsecureContentForFrame);
1066 RELEASE_ASSERT(!m_client.canAuthenticateAgainstProtectionSpaceInFrame);
1067 RELEASE_ASSERT(!m_client.didReceiveAuthenticationChallengeInFrame);
1068 RELEASE_ASSERT(!m_client.didStartProgress);
1069 RELEASE_ASSERT(!m_client.didChangeProgress);
1070 RELEASE_ASSERT(!m_client.didFinishProgress);
1071 RELEASE_ASSERT(!m_client.processDidBecomeUnresponsive);
1072 RELEASE_ASSERT(!m_client.processDidBecomeResponsive);
1073 RELEASE_ASSERT(!m_client.shouldGoToBackForwardListItem);
1074 RELEASE_ASSERT(!m_client.didFailToInitializePlugin_deprecatedForUseWithV0);
1075 RELEASE_ASSERT(!m_client.didDetectXSSForFrame);
1076 RELEASE_ASSERT(!m_client.didNewFirstVisuallyNonEmptyLayout_unavailable);
1077 RELEASE_ASSERT(!m_client.willGoToBackForwardListItem);
1078 RELEASE_ASSERT(!m_client.interactionOccurredWhileProcessUnresponsive);
1079 RELEASE_ASSERT(!m_client.pluginDidFail_deprecatedForUseWithV1);
1080 RELEASE_ASSERT(!m_client.didReceiveIntentForFrame_unavailable);
1081 RELEASE_ASSERT(!m_client.registerIntentServiceForFrame_unavailable);
1082 RELEASE_ASSERT(!m_client.pluginLoadPolicy_deprecatedForUseWithV2);
1083 RELEASE_ASSERT(!m_client.pluginDidFail);
1084 RELEASE_ASSERT(!m_client.pluginLoadPolicy);
1085 RELEASE_ASSERT(!m_client.webGLLoadPolicy);
1086 RELEASE_ASSERT(!m_client.resolveWebGLLoadPolicy);
1087 RELEASE_ASSERT(!m_client.navigationGestureDidBegin);
1088 RELEASE_ASSERT(!m_client.navigationGestureWillEnd);
1089 RELEASE_ASSERT(!m_client.navigationGestureDidEnd);
1090#endif
1091 }
1092
1093 private:
1094
1095 void didCommitLoadForFrame(WebPageProxy& page, WebFrameProxy& frame, API::Navigation*, API::Object* userData) override
1096 {
1097 if (!m_client.didCommitLoadForFrame)
1098 return;
1099
1100 m_client.didCommitLoadForFrame(toAPI(&page), toAPI(&frame), toAPI(userData), m_client.base.clientInfo);
1101 }
1102
1103 void didStartProvisionalLoadForFrame(WebPageProxy& page, WebFrameProxy& frame, API::Navigation*, API::Object* userData) override
1104 {
1105 if (!m_client.didStartProvisionalLoadForFrame)
1106 return;
1107
1108 m_client.didStartProvisionalLoadForFrame(toAPI(&page), toAPI(&frame), toAPI(userData), m_client.base.clientInfo);
1109 }
1110
1111 void didReceiveServerRedirectForProvisionalLoadForFrame(WebPageProxy& page, WebFrameProxy& frame, API::Navigation*, API::Object* userData) override
1112 {
1113 if (!m_client.didReceiveServerRedirectForProvisionalLoadForFrame)
1114 return;
1115
1116 m_client.didReceiveServerRedirectForProvisionalLoadForFrame(toAPI(&page), toAPI(&frame), toAPI(userData), m_client.base.clientInfo);
1117 }
1118
1119 void didFailProvisionalLoadWithErrorForFrame(WebPageProxy& page, WebFrameProxy& frame, API::Navigation*, const WebCore::ResourceError& error, API::Object* userData) override
1120 {
1121 if (!m_client.didFailProvisionalLoadWithErrorForFrame)
1122 return;
1123
1124 m_client.didFailProvisionalLoadWithErrorForFrame(toAPI(&page), toAPI(&frame), toAPI(error), toAPI(userData), m_client.base.clientInfo);
1125 }
1126
1127 void didFinishLoadForFrame(WebPageProxy& page, WebFrameProxy& frame, API::Navigation*, API::Object* userData) override
1128 {
1129 if (!m_client.didFinishLoadForFrame)
1130 return;
1131
1132 m_client.didFinishLoadForFrame(toAPI(&page), toAPI(&frame), toAPI(userData), m_client.base.clientInfo);
1133 }
1134
1135 void didFailLoadWithErrorForFrame(WebPageProxy& page, WebFrameProxy& frame, API::Navigation*, const WebCore::ResourceError& error, API::Object* userData) override
1136 {
1137 if (!m_client.didFailLoadWithErrorForFrame)
1138 return;
1139
1140 m_client.didFailLoadWithErrorForFrame(toAPI(&page), toAPI(&frame), toAPI(error), toAPI(userData), m_client.base.clientInfo);
1141 }
1142
1143 void didFirstVisuallyNonEmptyLayoutForFrame(WebPageProxy& page, WebFrameProxy& frame, API::Object* userData) override
1144 {
1145 if (!m_client.didFirstVisuallyNonEmptyLayoutForFrame)
1146 return;
1147
1148 m_client.didFirstVisuallyNonEmptyLayoutForFrame(toAPI(&page), toAPI(&frame), toAPI(userData), m_client.base.clientInfo);
1149 }
1150
1151 void didReachLayoutMilestone(WebPageProxy& page, OptionSet<WebCore::LayoutMilestone> milestones) override
1152 {
1153 if (!m_client.didLayout)
1154 return;
1155
1156 m_client.didLayout(toAPI(&page), toWKLayoutMilestones(milestones), nullptr, m_client.base.clientInfo);
1157 }
1158
1159 bool processDidCrash(WebPageProxy& page) override
1160 {
1161 if (!m_client.processDidCrash)
1162 return false;
1163
1164 m_client.processDidCrash(toAPI(&page), m_client.base.clientInfo);
1165 return true;
1166 }
1167
1168 void didChangeBackForwardList(WebPageProxy& page, WebBackForwardListItem* addedItem, Vector<Ref<WebBackForwardListItem>>&& removedItems) override
1169 {
1170 if (!m_client.didChangeBackForwardList)
1171 return;
1172
1173 RefPtr<API::Array> removedItemsArray;
1174 if (!removedItems.isEmpty()) {
1175 Vector<RefPtr<API::Object>> removedItemsVector;
1176 removedItemsVector.reserveInitialCapacity(removedItems.size());
1177 for (auto& removedItem : removedItems)
1178 removedItemsVector.append(WTFMove(removedItem));
1179
1180 removedItemsArray = API::Array::create(WTFMove(removedItemsVector));
1181 }
1182
1183 m_client.didChangeBackForwardList(toAPI(&page), toAPI(addedItem), toAPI(removedItemsArray.get()), m_client.base.clientInfo);
1184 }
1185
1186 bool shouldKeepCurrentBackForwardListItemInList(WebKit::WebPageProxy& page, WebKit::WebBackForwardListItem& item) override
1187 {
1188 if (!m_client.shouldKeepCurrentBackForwardListItemInList)
1189 return true;
1190
1191 return m_client.shouldKeepCurrentBackForwardListItemInList(toAPI(&page), toAPI(&item), m_client.base.clientInfo);
1192 }
1193 };
1194
1195 WebPageProxy* webPageProxy = toImpl(pageRef);
1196
1197 auto loaderClient = std::make_unique<LoaderClient>(wkClient);
1198
1199 // It would be nice to get rid of this code and transition all clients to using didLayout instead of
1200 // didFirstLayoutInFrame and didFirstVisuallyNonEmptyLayoutInFrame. In the meantime, this is required
1201 // for backwards compatibility.
1202 OptionSet<WebCore::LayoutMilestone> milestones;
1203 if (loaderClient->client().didFirstLayoutForFrame)
1204 milestones.add(WebCore::DidFirstLayout);
1205 if (loaderClient->client().didFirstVisuallyNonEmptyLayoutForFrame)
1206 milestones.add(WebCore::DidFirstVisuallyNonEmptyLayout);
1207
1208 if (milestones)
1209 webPageProxy->process().send(Messages::WebPage::ListenForLayoutMilestones(milestones), webPageProxy->pageID());
1210
1211 webPageProxy->setLoaderClient(WTFMove(loaderClient));
1212}
1213
1214void WKPageSetPagePolicyClient(WKPageRef pageRef, const WKPagePolicyClientBase* wkClient)
1215{
1216 class PolicyClient : public API::Client<WKPagePolicyClientBase>, public API::PolicyClient {
1217 public:
1218 explicit PolicyClient(const WKPagePolicyClientBase* client)
1219 {
1220 initialize(client);
1221 }
1222
1223 private:
1224 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
1225 {
1226 if (!m_client.decidePolicyForNavigationAction_deprecatedForUseWithV0 && !m_client.decidePolicyForNavigationAction_deprecatedForUseWithV1 && !m_client.decidePolicyForNavigationAction) {
1227 listener->use();
1228 return;
1229 }
1230
1231 Ref<API::URLRequest> originalRequest = API::URLRequest::create(originalResourceRequest);
1232 Ref<API::URLRequest> request = API::URLRequest::create(resourceRequest);
1233
1234 if (m_client.decidePolicyForNavigationAction_deprecatedForUseWithV0)
1235 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);
1236 else if (m_client.decidePolicyForNavigationAction_deprecatedForUseWithV1)
1237 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);
1238 else
1239 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);
1240 }
1241
1242 void decidePolicyForNewWindowAction(WebPageProxy& page, WebFrameProxy& frame, const NavigationActionData& navigationActionData, const WebCore::ResourceRequest& resourceRequest, const String& frameName, Ref<WebFramePolicyListenerProxy>&& listener, API::Object* userData) override
1243 {
1244 if (!m_client.decidePolicyForNewWindowAction) {
1245 listener->use();
1246 return;
1247 }
1248
1249 Ref<API::URLRequest> request = API::URLRequest::create(resourceRequest);
1250
1251 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);
1252 }
1253
1254 void decidePolicyForResponse(WebPageProxy& page, WebFrameProxy& frame, const WebCore::ResourceResponse& resourceResponse, const WebCore::ResourceRequest& resourceRequest, bool canShowMIMEType, Ref<WebFramePolicyListenerProxy>&& listener, API::Object* userData) override
1255 {
1256 if (!m_client.decidePolicyForResponse_deprecatedForUseWithV0 && !m_client.decidePolicyForResponse) {
1257 listener->use();
1258 return;
1259 }
1260
1261 Ref<API::URLResponse> response = API::URLResponse::create(resourceResponse);
1262 Ref<API::URLRequest> request = API::URLRequest::create(resourceRequest);
1263
1264 if (m_client.decidePolicyForResponse_deprecatedForUseWithV0)
1265 m_client.decidePolicyForResponse_deprecatedForUseWithV0(toAPI(&page), toAPI(&frame), toAPI(response.ptr()), toAPI(request.ptr()), toAPI(listener.ptr()), toAPI(userData), m_client.base.clientInfo);
1266 else
1267 m_client.decidePolicyForResponse(toAPI(&page), toAPI(&frame), toAPI(response.ptr()), toAPI(request.ptr()), canShowMIMEType, toAPI(listener.ptr()), toAPI(userData), m_client.base.clientInfo);
1268 }
1269
1270 void unableToImplementPolicy(WebPageProxy& page, WebFrameProxy& frame, const WebCore::ResourceError& error, API::Object* userData) override
1271 {
1272 if (!m_client.unableToImplementPolicy)
1273 return;
1274
1275 m_client.unableToImplementPolicy(toAPI(&page), toAPI(&frame), toAPI(error), toAPI(userData), m_client.base.clientInfo);
1276 }
1277 };
1278
1279 toImpl(pageRef)->setPolicyClient(std::make_unique<PolicyClient>(wkClient));
1280}
1281
1282namespace WebKit {
1283using namespace WebCore;
1284
1285class RunBeforeUnloadConfirmPanelResultListener : public API::ObjectImpl<API::Object::Type::RunBeforeUnloadConfirmPanelResultListener> {
1286public:
1287 static Ref<RunBeforeUnloadConfirmPanelResultListener> create(Function<void(bool)>&& completionHandler)
1288 {
1289 return adoptRef(*new RunBeforeUnloadConfirmPanelResultListener(WTFMove(completionHandler)));
1290 }
1291
1292 virtual ~RunBeforeUnloadConfirmPanelResultListener()
1293 {
1294 }
1295
1296 void call(bool result)
1297 {
1298 m_completionHandler(result);
1299 }
1300
1301private:
1302 explicit RunBeforeUnloadConfirmPanelResultListener(Function<void (bool)>&& completionHandler)
1303 : m_completionHandler(WTFMove(completionHandler))
1304 {
1305 }
1306
1307 Function<void (bool)> m_completionHandler;
1308};
1309
1310class RunJavaScriptAlertResultListener : public API::ObjectImpl<API::Object::Type::RunJavaScriptAlertResultListener> {
1311public:
1312 static Ref<RunJavaScriptAlertResultListener> create(Function<void()>&& completionHandler)
1313 {
1314 return adoptRef(*new RunJavaScriptAlertResultListener(WTFMove(completionHandler)));
1315 }
1316
1317 virtual ~RunJavaScriptAlertResultListener()
1318 {
1319 }
1320
1321 void call()
1322 {
1323 m_completionHandler();
1324 }
1325
1326private:
1327 explicit RunJavaScriptAlertResultListener(Function<void ()>&& completionHandler)
1328 : m_completionHandler(WTFMove(completionHandler))
1329 {
1330 }
1331
1332 Function<void ()> m_completionHandler;
1333};
1334
1335class RunJavaScriptConfirmResultListener : public API::ObjectImpl<API::Object::Type::RunJavaScriptConfirmResultListener> {
1336public:
1337 static Ref<RunJavaScriptConfirmResultListener> create(Function<void(bool)>&& completionHandler)
1338 {
1339 return adoptRef(*new RunJavaScriptConfirmResultListener(WTFMove(completionHandler)));
1340 }
1341
1342 virtual ~RunJavaScriptConfirmResultListener()
1343 {
1344 }
1345
1346 void call(bool result)
1347 {
1348 m_completionHandler(result);
1349 }
1350
1351private:
1352 explicit RunJavaScriptConfirmResultListener(Function<void(bool)>&& completionHandler)
1353 : m_completionHandler(WTFMove(completionHandler))
1354 {
1355 }
1356
1357 Function<void (bool)> m_completionHandler;
1358};
1359
1360class RunJavaScriptPromptResultListener : public API::ObjectImpl<API::Object::Type::RunJavaScriptPromptResultListener> {
1361public:
1362 static Ref<RunJavaScriptPromptResultListener> create(Function<void(const String&)>&& completionHandler)
1363 {
1364 return adoptRef(*new RunJavaScriptPromptResultListener(WTFMove(completionHandler)));
1365 }
1366
1367 virtual ~RunJavaScriptPromptResultListener()
1368 {
1369 }
1370
1371 void call(const String& result)
1372 {
1373 m_completionHandler(result);
1374 }
1375
1376private:
1377 explicit RunJavaScriptPromptResultListener(Function<void(const String&)>&& completionHandler)
1378 : m_completionHandler(WTFMove(completionHandler))
1379 {
1380 }
1381
1382 Function<void (const String&)> m_completionHandler;
1383};
1384
1385class RequestStorageAccessConfirmResultListener : public API::ObjectImpl<API::Object::Type::RequestStorageAccessConfirmResultListener> {
1386public:
1387 static Ref<RequestStorageAccessConfirmResultListener> create(CompletionHandler<void(bool)>&& completionHandler)
1388 {
1389 return adoptRef(*new RequestStorageAccessConfirmResultListener(WTFMove(completionHandler)));
1390 }
1391
1392 virtual ~RequestStorageAccessConfirmResultListener()
1393 {
1394 }
1395
1396 void call(bool result)
1397 {
1398 m_completionHandler(result);
1399 }
1400
1401private:
1402 explicit RequestStorageAccessConfirmResultListener(CompletionHandler<void(bool)>&& completionHandler)
1403 : m_completionHandler(WTFMove(completionHandler))
1404 {
1405 }
1406
1407 CompletionHandler<void(bool)> m_completionHandler;
1408};
1409
1410WK_ADD_API_MAPPING(WKPageRunBeforeUnloadConfirmPanelResultListenerRef, RunBeforeUnloadConfirmPanelResultListener)
1411WK_ADD_API_MAPPING(WKPageRunJavaScriptAlertResultListenerRef, RunJavaScriptAlertResultListener)
1412WK_ADD_API_MAPPING(WKPageRunJavaScriptConfirmResultListenerRef, RunJavaScriptConfirmResultListener)
1413WK_ADD_API_MAPPING(WKPageRunJavaScriptPromptResultListenerRef, RunJavaScriptPromptResultListener)
1414WK_ADD_API_MAPPING(WKPageRequestStorageAccessConfirmResultListenerRef, RequestStorageAccessConfirmResultListener)
1415
1416}
1417
1418WKTypeID WKPageRunBeforeUnloadConfirmPanelResultListenerGetTypeID()
1419{
1420 return toAPI(RunBeforeUnloadConfirmPanelResultListener::APIType);
1421}
1422
1423void WKPageRunBeforeUnloadConfirmPanelResultListenerCall(WKPageRunBeforeUnloadConfirmPanelResultListenerRef listener, bool result)
1424{
1425 toImpl(listener)->call(result);
1426}
1427
1428WKTypeID WKPageRunJavaScriptAlertResultListenerGetTypeID()
1429{
1430 return toAPI(RunJavaScriptAlertResultListener::APIType);
1431}
1432
1433void WKPageRunJavaScriptAlertResultListenerCall(WKPageRunJavaScriptAlertResultListenerRef listener)
1434{
1435 toImpl(listener)->call();
1436}
1437
1438WKTypeID WKPageRunJavaScriptConfirmResultListenerGetTypeID()
1439{
1440 return toAPI(RunJavaScriptConfirmResultListener::APIType);
1441}
1442
1443void WKPageRunJavaScriptConfirmResultListenerCall(WKPageRunJavaScriptConfirmResultListenerRef listener, bool result)
1444{
1445 toImpl(listener)->call(result);
1446}
1447
1448WKTypeID WKPageRunJavaScriptPromptResultListenerGetTypeID()
1449{
1450 return toAPI(RunJavaScriptPromptResultListener::APIType);
1451}
1452
1453void WKPageRunJavaScriptPromptResultListenerCall(WKPageRunJavaScriptPromptResultListenerRef listener, WKStringRef result)
1454{
1455 toImpl(listener)->call(toWTFString(result));
1456}
1457
1458WKTypeID WKPageRequestStorageAccessConfirmResultListenerGetTypeID()
1459{
1460 return toAPI(RequestStorageAccessConfirmResultListener::APIType);
1461}
1462
1463void WKPageRequestStorageAccessConfirmResultListenerCall(WKPageRequestStorageAccessConfirmResultListenerRef listener, bool result)
1464{
1465 toImpl(listener)->call(result);
1466}
1467
1468void WKPageSetPageUIClient(WKPageRef pageRef, const WKPageUIClientBase* wkClient)
1469{
1470 class UIClient : public API::Client<WKPageUIClientBase>, public API::UIClient {
1471 public:
1472 explicit UIClient(const WKPageUIClientBase* client)
1473 {
1474 initialize(client);
1475 }
1476
1477 private:
1478 void createNewPage(WebPageProxy& page, WebCore::WindowFeatures&& windowFeatures, Ref<API::NavigationAction>&& navigationAction, CompletionHandler<void(RefPtr<WebPageProxy>&&)>&& completionHandler) final
1479 {
1480 if (m_client.createNewPage) {
1481 auto configuration = page.configuration().copy();
1482 configuration->setRelatedPage(&page);
1483
1484 auto apiWindowFeatures = API::WindowFeatures::create(windowFeatures);
1485
1486 return completionHandler(adoptRef(toImpl(m_client.createNewPage(toAPI(&page), toAPI(configuration.ptr()), toAPI(navigationAction.ptr()), toAPI(apiWindowFeatures.ptr()), m_client.base.clientInfo))));
1487 }
1488
1489 if (m_client.createNewPage_deprecatedForUseWithV1 || m_client.createNewPage_deprecatedForUseWithV0) {
1490 API::Dictionary::MapType map;
1491 if (windowFeatures.x)
1492 map.set("x", API::Double::create(*windowFeatures.x));
1493 if (windowFeatures.y)
1494 map.set("y", API::Double::create(*windowFeatures.y));
1495 if (windowFeatures.width)
1496 map.set("width", API::Double::create(*windowFeatures.width));
1497 if (windowFeatures.height)
1498 map.set("height", API::Double::create(*windowFeatures.height));
1499 map.set("menuBarVisible", API::Boolean::create(windowFeatures.menuBarVisible));
1500 map.set("statusBarVisible", API::Boolean::create(windowFeatures.statusBarVisible));
1501 map.set("toolBarVisible", API::Boolean::create(windowFeatures.toolBarVisible));
1502 map.set("locationBarVisible", API::Boolean::create(windowFeatures.locationBarVisible));
1503 map.set("scrollbarsVisible", API::Boolean::create(windowFeatures.scrollbarsVisible));
1504 map.set("resizable", API::Boolean::create(windowFeatures.resizable));
1505 map.set("fullscreen", API::Boolean::create(windowFeatures.fullscreen));
1506 map.set("dialog", API::Boolean::create(windowFeatures.dialog));
1507 Ref<API::Dictionary> featuresMap = API::Dictionary::create(WTFMove(map));
1508
1509 if (m_client.createNewPage_deprecatedForUseWithV1) {
1510 Ref<API::URLRequest> request = API::URLRequest::create(navigationAction->request());
1511 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))));
1512 }
1513
1514 ASSERT(m_client.createNewPage_deprecatedForUseWithV0);
1515 return completionHandler(adoptRef(toImpl(m_client.createNewPage_deprecatedForUseWithV0(toAPI(&page), toAPI(featuresMap.ptr()), toAPI(navigationAction->modifiers()), toAPI(navigationAction->mouseButton()), m_client.base.clientInfo))));
1516 }
1517
1518 completionHandler(nullptr);
1519 }
1520
1521 void showPage(WebPageProxy* page) final
1522 {
1523 if (!m_client.showPage)
1524 return;
1525
1526 m_client.showPage(toAPI(page), m_client.base.clientInfo);
1527 }
1528
1529 void fullscreenMayReturnToInline(WebPageProxy* page) final
1530 {
1531 if (!m_client.fullscreenMayReturnToInline)
1532 return;
1533
1534 m_client.fullscreenMayReturnToInline(toAPI(page), m_client.base.clientInfo);
1535 }
1536
1537 void hasVideoInPictureInPictureDidChange(WebPageProxy* page, bool hasVideoInPictureInPicture) final
1538 {
1539 if (!m_client.hasVideoInPictureInPictureDidChange)
1540 return;
1541
1542 m_client.hasVideoInPictureInPictureDidChange(toAPI(page), hasVideoInPictureInPicture, m_client.base.clientInfo);
1543 }
1544
1545 void didExceedBackgroundResourceLimitWhileInForeground(WebPageProxy& page, WKResourceLimit limit) final
1546 {
1547 if (!m_client.didExceedBackgroundResourceLimitWhileInForeground)
1548 return;
1549
1550 m_client.didExceedBackgroundResourceLimitWhileInForeground(toAPI(&page), limit, m_client.base.clientInfo);
1551 }
1552
1553 void close(WebPageProxy* page) final
1554 {
1555 if (!m_client.close)
1556 return;
1557
1558 m_client.close(toAPI(page), m_client.base.clientInfo);
1559 }
1560
1561 bool takeFocus(WebPageProxy* page, WKFocusDirection direction) final
1562 {
1563 if (!m_client.takeFocus)
1564 return false;
1565
1566 m_client.takeFocus(toAPI(page), direction, m_client.base.clientInfo);
1567 return true;
1568 }
1569
1570 void focus(WebPageProxy* page) final
1571 {
1572 if (!m_client.focus)
1573 return;
1574
1575 m_client.focus(toAPI(page), m_client.base.clientInfo);
1576 }
1577
1578 void unfocus(WebPageProxy* page) final
1579 {
1580 if (!m_client.unfocus)
1581 return;
1582
1583 m_client.unfocus(toAPI(page), m_client.base.clientInfo);
1584 }
1585
1586 void runJavaScriptAlert(WebPageProxy* page, const String& message, WebFrameProxy* frame, const SecurityOriginData& securityOriginData, Function<void()>&& completionHandler) final
1587 {
1588 if (m_client.runJavaScriptAlert) {
1589 RefPtr<RunJavaScriptAlertResultListener> listener = RunJavaScriptAlertResultListener::create(WTFMove(completionHandler));
1590 RefPtr<API::SecurityOrigin> securityOrigin = API::SecurityOrigin::create(securityOriginData.protocol, securityOriginData.host, securityOriginData.port);
1591 m_client.runJavaScriptAlert(toAPI(page), toAPI(message.impl()), toAPI(frame), toAPI(securityOrigin.get()), toAPI(listener.get()), m_client.base.clientInfo);
1592 return;
1593 }
1594
1595 if (m_client.runJavaScriptAlert_deprecatedForUseWithV5) {
1596 RefPtr<API::SecurityOrigin> securityOrigin = API::SecurityOrigin::create(securityOriginData.protocol, securityOriginData.host, securityOriginData.port);
1597 m_client.runJavaScriptAlert_deprecatedForUseWithV5(toAPI(page), toAPI(message.impl()), toAPI(frame), toAPI(securityOrigin.get()), m_client.base.clientInfo);
1598 completionHandler();
1599 return;
1600 }
1601
1602 if (m_client.runJavaScriptAlert_deprecatedForUseWithV0) {
1603 m_client.runJavaScriptAlert_deprecatedForUseWithV0(toAPI(page), toAPI(message.impl()), toAPI(frame), m_client.base.clientInfo);
1604 completionHandler();
1605 return;
1606 }
1607
1608
1609 completionHandler();
1610 }
1611
1612 void runJavaScriptConfirm(WebPageProxy* page, const String& message, WebFrameProxy* frame, const SecurityOriginData& securityOriginData, Function<void(bool)>&& completionHandler) final
1613 {
1614 if (m_client.runJavaScriptConfirm) {
1615 RefPtr<RunJavaScriptConfirmResultListener> listener = RunJavaScriptConfirmResultListener::create(WTFMove(completionHandler));
1616 RefPtr<API::SecurityOrigin> securityOrigin = API::SecurityOrigin::create(securityOriginData.protocol, securityOriginData.host, securityOriginData.port);
1617 m_client.runJavaScriptConfirm(toAPI(page), toAPI(message.impl()), toAPI(frame), toAPI(securityOrigin.get()), toAPI(listener.get()), m_client.base.clientInfo);
1618 return;
1619 }
1620
1621 if (m_client.runJavaScriptConfirm_deprecatedForUseWithV5) {
1622 RefPtr<API::SecurityOrigin> securityOrigin = API::SecurityOrigin::create(securityOriginData.protocol, securityOriginData.host, securityOriginData.port);
1623 bool result = m_client.runJavaScriptConfirm_deprecatedForUseWithV5(toAPI(page), toAPI(message.impl()), toAPI(frame), toAPI(securityOrigin.get()), m_client.base.clientInfo);
1624
1625 completionHandler(result);
1626 return;
1627 }
1628
1629 if (m_client.runJavaScriptConfirm_deprecatedForUseWithV0) {
1630 bool result = m_client.runJavaScriptConfirm_deprecatedForUseWithV0(toAPI(page), toAPI(message.impl()), toAPI(frame), m_client.base.clientInfo);
1631
1632 completionHandler(result);
1633 return;
1634 }
1635
1636 completionHandler(false);
1637 }
1638
1639 void runJavaScriptPrompt(WebPageProxy* page, const String& message, const String& defaultValue, WebFrameProxy* frame, const SecurityOriginData& securityOriginData, Function<void(const String&)>&& completionHandler) final
1640 {
1641 if (m_client.runJavaScriptPrompt) {
1642 RefPtr<RunJavaScriptPromptResultListener> listener = RunJavaScriptPromptResultListener::create(WTFMove(completionHandler));
1643 RefPtr<API::SecurityOrigin> securityOrigin = API::SecurityOrigin::create(securityOriginData.protocol, securityOriginData.host, securityOriginData.port);
1644 m_client.runJavaScriptPrompt(toAPI(page), toAPI(message.impl()), toAPI(defaultValue.impl()), toAPI(frame), toAPI(securityOrigin.get()), toAPI(listener.get()), m_client.base.clientInfo);
1645 return;
1646 }
1647
1648 if (m_client.runJavaScriptPrompt_deprecatedForUseWithV5) {
1649 RefPtr<API::SecurityOrigin> securityOrigin = API::SecurityOrigin::create(securityOriginData.protocol, securityOriginData.host, securityOriginData.port);
1650 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)));
1651
1652 if (string)
1653 completionHandler(string->string());
1654 else
1655 completionHandler(String());
1656 return;
1657 }
1658
1659 if (m_client.runJavaScriptPrompt_deprecatedForUseWithV0) {
1660 RefPtr<API::String> string = adoptRef(toImpl(m_client.runJavaScriptPrompt_deprecatedForUseWithV0(toAPI(page), toAPI(message.impl()), toAPI(defaultValue.impl()), toAPI(frame), m_client.base.clientInfo)));
1661
1662 if (string)
1663 completionHandler(string->string());
1664 else
1665 completionHandler(String());
1666 return;
1667 }
1668
1669 completionHandler(String());
1670 }
1671
1672 void setStatusText(WebPageProxy* page, const String& text) final
1673 {
1674 if (!m_client.setStatusText)
1675 return;
1676
1677 m_client.setStatusText(toAPI(page), toAPI(text.impl()), m_client.base.clientInfo);
1678 }
1679
1680 void mouseDidMoveOverElement(WebPageProxy& page, const WebHitTestResultData& data, OptionSet<WebKit::WebEvent::Modifier> modifiers, API::Object* userData) final
1681 {
1682 if (!m_client.mouseDidMoveOverElement && !m_client.mouseDidMoveOverElement_deprecatedForUseWithV0)
1683 return;
1684
1685 if (m_client.base.version > 0 && !m_client.mouseDidMoveOverElement)
1686 return;
1687
1688 if (!m_client.base.version) {
1689 m_client.mouseDidMoveOverElement_deprecatedForUseWithV0(toAPI(&page), toAPI(modifiers), toAPI(userData), m_client.base.clientInfo);
1690 return;
1691 }
1692
1693 auto apiHitTestResult = API::HitTestResult::create(data);
1694 m_client.mouseDidMoveOverElement(toAPI(&page), toAPI(apiHitTestResult.ptr()), toAPI(modifiers), toAPI(userData), m_client.base.clientInfo);
1695 }
1696
1697#if ENABLE(NETSCAPE_PLUGIN_API)
1698 void unavailablePluginButtonClicked(WebPageProxy& page, WKPluginUnavailabilityReason pluginUnavailabilityReason, API::Dictionary& pluginInformation) final
1699 {
1700 if (pluginUnavailabilityReason == kWKPluginUnavailabilityReasonPluginMissing) {
1701 if (m_client.missingPluginButtonClicked_deprecatedForUseWithV0)
1702 m_client.missingPluginButtonClicked_deprecatedForUseWithV0(
1703 toAPI(&page),
1704 toAPI(pluginInformation.get<API::String>(pluginInformationMIMETypeKey())),
1705 toAPI(pluginInformation.get<API::String>(pluginInformationPluginURLKey())),
1706 toAPI(pluginInformation.get<API::String>(pluginInformationPluginspageAttributeURLKey())),
1707 m_client.base.clientInfo);
1708 }
1709
1710 if (m_client.unavailablePluginButtonClicked_deprecatedForUseWithV1)
1711 m_client.unavailablePluginButtonClicked_deprecatedForUseWithV1(
1712 toAPI(&page),
1713 pluginUnavailabilityReason,
1714 toAPI(pluginInformation.get<API::String>(pluginInformationMIMETypeKey())),
1715 toAPI(pluginInformation.get<API::String>(pluginInformationPluginURLKey())),
1716 toAPI(pluginInformation.get<API::String>(pluginInformationPluginspageAttributeURLKey())),
1717 m_client.base.clientInfo);
1718
1719 if (m_client.unavailablePluginButtonClicked)
1720 m_client.unavailablePluginButtonClicked(
1721 toAPI(&page),
1722 pluginUnavailabilityReason,
1723 toAPI(&pluginInformation),
1724 m_client.base.clientInfo);
1725 }
1726#endif // ENABLE(NETSCAPE_PLUGIN_API)
1727
1728 void didNotHandleKeyEvent(WebPageProxy* page, const NativeWebKeyboardEvent& event) final
1729 {
1730 if (!m_client.didNotHandleKeyEvent)
1731 return;
1732 m_client.didNotHandleKeyEvent(toAPI(page), event.nativeEvent(), m_client.base.clientInfo);
1733 }
1734
1735 void didNotHandleWheelEvent(WebPageProxy* page, const NativeWebWheelEvent& event) final
1736 {
1737 if (!m_client.didNotHandleWheelEvent)
1738 return;
1739 m_client.didNotHandleWheelEvent(toAPI(page), event.nativeEvent(), m_client.base.clientInfo);
1740 }
1741
1742 void toolbarsAreVisible(WebPageProxy& page, Function<void(bool)>&& completionHandler) final
1743 {
1744 if (!m_client.toolbarsAreVisible)
1745 return completionHandler(true);
1746 completionHandler(m_client.toolbarsAreVisible(toAPI(&page), m_client.base.clientInfo));
1747 }
1748
1749 void setToolbarsAreVisible(WebPageProxy& page, bool visible) final
1750 {
1751 if (!m_client.setToolbarsAreVisible)
1752 return;
1753 m_client.setToolbarsAreVisible(toAPI(&page), visible, m_client.base.clientInfo);
1754 }
1755
1756 void menuBarIsVisible(WebPageProxy& page, Function<void(bool)>&& completionHandler) final
1757 {
1758 if (!m_client.menuBarIsVisible)
1759 return completionHandler(true);
1760 completionHandler(m_client.menuBarIsVisible(toAPI(&page), m_client.base.clientInfo));
1761 }
1762
1763 void setMenuBarIsVisible(WebPageProxy& page, bool visible) final
1764 {
1765 if (!m_client.setMenuBarIsVisible)
1766 return;
1767 m_client.setMenuBarIsVisible(toAPI(&page), visible, m_client.base.clientInfo);
1768 }
1769
1770 void statusBarIsVisible(WebPageProxy& page, Function<void(bool)>&& completionHandler) final
1771 {
1772 if (!m_client.statusBarIsVisible)
1773 return completionHandler(true);
1774 completionHandler(m_client.statusBarIsVisible(toAPI(&page), m_client.base.clientInfo));
1775 }
1776
1777 void setStatusBarIsVisible(WebPageProxy& page, bool visible) final
1778 {
1779 if (!m_client.setStatusBarIsVisible)
1780 return;
1781 m_client.setStatusBarIsVisible(toAPI(&page), visible, m_client.base.clientInfo);
1782 }
1783
1784 void setIsResizable(WebPageProxy& page, bool resizable) final
1785 {
1786 if (!m_client.setIsResizable)
1787 return;
1788 m_client.setIsResizable(toAPI(&page), resizable, m_client.base.clientInfo);
1789 }
1790
1791 void setWindowFrame(WebPageProxy& page, const FloatRect& frame) final
1792 {
1793 if (!m_client.setWindowFrame)
1794 return;
1795
1796 m_client.setWindowFrame(toAPI(&page), toAPI(frame), m_client.base.clientInfo);
1797 }
1798
1799 void windowFrame(WebPageProxy& page, Function<void(WebCore::FloatRect)>&& completionHandler) final
1800 {
1801 if (!m_client.getWindowFrame)
1802 return completionHandler({ });
1803
1804 completionHandler(toFloatRect(m_client.getWindowFrame(toAPI(&page), m_client.base.clientInfo)));
1805 }
1806
1807 bool canRunBeforeUnloadConfirmPanel() const final
1808 {
1809 return m_client.runBeforeUnloadConfirmPanel_deprecatedForUseWithV6 || m_client.runBeforeUnloadConfirmPanel;
1810 }
1811
1812 void runBeforeUnloadConfirmPanel(WebKit::WebPageProxy* page, const WTF::String& message, WebKit::WebFrameProxy* frame, const SecurityOriginData&, Function<void(bool)>&& completionHandler) final
1813 {
1814 if (m_client.runBeforeUnloadConfirmPanel) {
1815 RefPtr<RunBeforeUnloadConfirmPanelResultListener> listener = RunBeforeUnloadConfirmPanelResultListener::create(WTFMove(completionHandler));
1816 m_client.runBeforeUnloadConfirmPanel(toAPI(page), toAPI(message.impl()), toAPI(frame), toAPI(listener.get()), m_client.base.clientInfo);
1817 return;
1818 }
1819
1820 if (m_client.runBeforeUnloadConfirmPanel_deprecatedForUseWithV6) {
1821 bool result = m_client.runBeforeUnloadConfirmPanel_deprecatedForUseWithV6(toAPI(page), toAPI(message.impl()), toAPI(frame), m_client.base.clientInfo);
1822 completionHandler(result);
1823 return;
1824 }
1825
1826 completionHandler(true);
1827 }
1828
1829 void pageDidScroll(WebPageProxy* page) final
1830 {
1831 if (!m_client.pageDidScroll)
1832 return;
1833
1834 m_client.pageDidScroll(toAPI(page), m_client.base.clientInfo);
1835 }
1836
1837 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
1838 {
1839 if (!m_client.exceededDatabaseQuota) {
1840 completionHandler(currentQuota);
1841 return;
1842 }
1843
1844 completionHandler(m_client.exceededDatabaseQuota(toAPI(page), toAPI(frame), toAPI(origin), toAPI(databaseName.impl()), toAPI(databaseDisplayName.impl()), currentQuota, currentOriginUsage, currentDatabaseUsage, expectedUsage, m_client.base.clientInfo));
1845 }
1846
1847 bool runOpenPanel(WebPageProxy* page, WebFrameProxy* frame, const WebCore::SecurityOriginData&, API::OpenPanelParameters* parameters, WebOpenPanelResultListenerProxy* listener) final
1848 {
1849 if (!m_client.runOpenPanel)
1850 return false;
1851
1852 m_client.runOpenPanel(toAPI(page), toAPI(frame), toAPI(parameters), toAPI(listener), m_client.base.clientInfo);
1853 return true;
1854 }
1855
1856 void decidePolicyForGeolocationPermissionRequest(WebPageProxy& page, WebFrameProxy& frame, API::SecurityOrigin& origin, Function<void(bool)>& completionHandler) final
1857 {
1858 if (!m_client.decidePolicyForGeolocationPermissionRequest)
1859 return;
1860
1861 m_client.decidePolicyForGeolocationPermissionRequest(toAPI(&page), toAPI(&frame), toAPI(&origin), toAPI(GeolocationPermissionRequest::create(std::exchange(completionHandler, nullptr)).ptr()), m_client.base.clientInfo);
1862 }
1863
1864 void decidePolicyForUserMediaPermissionRequest(WebPageProxy& page, WebFrameProxy& frame, API::SecurityOrigin& userMediaDocumentOrigin, API::SecurityOrigin& topLevelDocumentOrigin, UserMediaPermissionRequestProxy& permissionRequest) final
1865 {
1866 if (!m_client.decidePolicyForUserMediaPermissionRequest) {
1867 permissionRequest.deny();
1868 return;
1869 }
1870
1871 m_client.decidePolicyForUserMediaPermissionRequest(toAPI(&page), toAPI(&frame), toAPI(&userMediaDocumentOrigin), toAPI(&topLevelDocumentOrigin), toAPI(&permissionRequest), m_client.base.clientInfo);
1872 }
1873
1874 void checkUserMediaPermissionForOrigin(WebPageProxy& page, WebFrameProxy& frame, API::SecurityOrigin& userMediaDocumentOrigin, API::SecurityOrigin& topLevelDocumentOrigin, UserMediaPermissionCheckProxy& request) final
1875 {
1876 if (!m_client.checkUserMediaPermissionForOrigin) {
1877 request.deny();
1878 return;
1879 }
1880
1881 m_client.checkUserMediaPermissionForOrigin(toAPI(&page), toAPI(&frame), toAPI(&userMediaDocumentOrigin), toAPI(&topLevelDocumentOrigin), toAPI(&request), m_client.base.clientInfo);
1882 }
1883
1884 void decidePolicyForNotificationPermissionRequest(WebPageProxy& page, API::SecurityOrigin& origin, Function<void(bool)>&& completionHandler) final
1885 {
1886 if (!m_client.decidePolicyForNotificationPermissionRequest)
1887 return completionHandler(false);
1888
1889 m_client.decidePolicyForNotificationPermissionRequest(toAPI(&page), toAPI(&origin), toAPI(NotificationPermissionRequest::create(WTFMove(completionHandler)).ptr()), m_client.base.clientInfo);
1890 }
1891
1892 void requestStorageAccessConfirm(WebPageProxy& page, WebFrameProxy* frame, const WebCore::RegistrableDomain& requestingDomain, const WebCore::RegistrableDomain& currentDomain, CompletionHandler<void(bool)>&& completionHandler) final
1893 {
1894 if (!m_client.requestStorageAccessConfirm) {
1895 completionHandler(true);
1896 return;
1897 }
1898
1899 auto listener = RequestStorageAccessConfirmResultListener::create(WTFMove(completionHandler));
1900 m_client.requestStorageAccessConfirm(toAPI(&page), toAPI(frame), toAPI(requestingDomain.string().impl()), toAPI(currentDomain.string().impl()), toAPI(listener.ptr()), m_client.base.clientInfo);
1901 }
1902
1903#if ENABLE(DEVICE_ORIENTATION)
1904 void shouldAllowDeviceOrientationAndMotionAccess(WebPageProxy& page, WebFrameProxy&, const WebCore::SecurityOriginData& originData, CompletionHandler<void(bool)>&& completionHandler) final
1905 {
1906 if (!m_client.shouldAllowDeviceOrientationAndMotionAccess)
1907 return completionHandler(false);
1908
1909 auto origin = API::SecurityOrigin::create(originData.securityOrigin());
1910 completionHandler(m_client.shouldAllowDeviceOrientationAndMotionAccess(toAPI(&page), toAPI(origin.ptr()), m_client.base.clientInfo));
1911 }
1912#endif
1913
1914 // Printing.
1915 float headerHeight(WebPageProxy& page, WebFrameProxy& frame) final
1916 {
1917 if (!m_client.headerHeight)
1918 return 0;
1919
1920 return m_client.headerHeight(toAPI(&page), toAPI(&frame), m_client.base.clientInfo);
1921 }
1922
1923 float footerHeight(WebPageProxy& page, WebFrameProxy& frame) final
1924 {
1925 if (!m_client.footerHeight)
1926 return 0;
1927
1928 return m_client.footerHeight(toAPI(&page), toAPI(&frame), m_client.base.clientInfo);
1929 }
1930
1931 void drawHeader(WebPageProxy& page, WebFrameProxy& frame, WebCore::FloatRect&& rect) final
1932 {
1933 if (!m_client.drawHeader)
1934 return;
1935
1936 m_client.drawHeader(toAPI(&page), toAPI(&frame), toAPI(rect), m_client.base.clientInfo);
1937 }
1938
1939 void drawFooter(WebPageProxy& page, WebFrameProxy& frame, WebCore::FloatRect&& rect) final
1940 {
1941 if (!m_client.drawFooter)
1942 return;
1943
1944 m_client.drawFooter(toAPI(&page), toAPI(&frame), toAPI(rect), m_client.base.clientInfo);
1945 }
1946
1947 void printFrame(WebPageProxy& page, WebFrameProxy& frame) final
1948 {
1949 if (!m_client.printFrame)
1950 return;
1951
1952 m_client.printFrame(toAPI(&page), toAPI(&frame), m_client.base.clientInfo);
1953 }
1954
1955 bool canRunModal() const final
1956 {
1957 return m_client.runModal;
1958 }
1959
1960 void runModal(WebPageProxy& page) final
1961 {
1962 if (!m_client.runModal)
1963 return;
1964
1965 m_client.runModal(toAPI(&page), m_client.base.clientInfo);
1966 }
1967
1968 void saveDataToFileInDownloadsFolder(WebPageProxy* page, const String& suggestedFilename, const String& mimeType, const URL& originatingURL, API::Data& data) final
1969 {
1970 if (!m_client.saveDataToFileInDownloadsFolder)
1971 return;
1972
1973 m_client.saveDataToFileInDownloadsFolder(toAPI(page), toAPI(suggestedFilename.impl()), toAPI(mimeType.impl()), toURLRef(originatingURL.string().impl()), toAPI(&data), m_client.base.clientInfo);
1974 }
1975
1976 void pinnedStateDidChange(WebPageProxy& page) final
1977 {
1978 if (!m_client.pinnedStateDidChange)
1979 return;
1980
1981 m_client.pinnedStateDidChange(toAPI(&page), m_client.base.clientInfo);
1982 }
1983
1984 void isPlayingMediaDidChange(WebPageProxy& page) final
1985 {
1986 if (!m_client.isPlayingAudioDidChange)
1987 return;
1988
1989 m_client.isPlayingAudioDidChange(toAPI(&page), m_client.base.clientInfo);
1990 }
1991
1992 void didClickAutoFillButton(WebPageProxy& page, API::Object* userInfo) final
1993 {
1994 if (!m_client.didClickAutoFillButton)
1995 return;
1996
1997 m_client.didClickAutoFillButton(toAPI(&page), toAPI(userInfo), m_client.base.clientInfo);
1998 }
1999
2000 void didResignInputElementStrongPasswordAppearance(WebPageProxy& page, API::Object* userInfo) final
2001 {
2002 if (!m_client.didResignInputElementStrongPasswordAppearance)
2003 return;
2004
2005 m_client.didResignInputElementStrongPasswordAppearance(toAPI(&page), toAPI(userInfo), m_client.base.clientInfo);
2006 }
2007
2008#if ENABLE(MEDIA_SESSION)
2009 void mediaSessionMetadataDidChange(WebPageProxy& page, WebMediaSessionMetadata* metadata) final
2010 {
2011 if (!m_client.mediaSessionMetadataDidChange)
2012 return;
2013
2014 m_client.mediaSessionMetadataDidChange(toAPI(&page), toAPI(metadata), m_client.base.clientInfo);
2015 }
2016#endif
2017#if ENABLE(POINTER_LOCK)
2018 void requestPointerLock(WebPageProxy* page) final
2019 {
2020 if (!m_client.requestPointerLock)
2021 return;
2022
2023 m_client.requestPointerLock(toAPI(page), m_client.base.clientInfo);
2024 }
2025
2026 void didLosePointerLock(WebPageProxy* page) final
2027 {
2028 if (!m_client.didLosePointerLock)
2029 return;
2030
2031 m_client.didLosePointerLock(toAPI(page), m_client.base.clientInfo);
2032 }
2033#endif
2034
2035 static WKAutoplayEventFlags toWKAutoplayEventFlags(OptionSet<WebCore::AutoplayEventFlags> flags)
2036 {
2037 WKAutoplayEventFlags wkFlags = kWKAutoplayEventFlagsNone;
2038 if (flags.contains(WebCore::AutoplayEventFlags::HasAudio))
2039 wkFlags |= kWKAutoplayEventFlagsHasAudio;
2040 if (flags.contains(WebCore::AutoplayEventFlags::PlaybackWasPrevented))
2041 wkFlags |= kWKAutoplayEventFlagsPlaybackWasPrevented;
2042 if (flags.contains(WebCore::AutoplayEventFlags::MediaIsMainContent))
2043 wkFlags |= kWKAutoplayEventFlagsMediaIsMainContent;
2044
2045 return wkFlags;
2046 }
2047
2048 static WKAutoplayEvent toWKAutoplayEvent(WebCore::AutoplayEvent event)
2049 {
2050 switch (event) {
2051 case WebCore::AutoplayEvent::DidAutoplayMediaPastThresholdWithoutUserInterference:
2052 return kWKAutoplayEventDidAutoplayMediaPastThresholdWithoutUserInterference;
2053 case WebCore::AutoplayEvent::DidPlayMediaWithUserGesture:
2054 return kWKAutoplayEventDidPlayMediaWithUserGesture;
2055 case WebCore::AutoplayEvent::DidPreventMediaFromPlaying:
2056 return kWKAutoplayEventDidPreventFromAutoplaying;
2057 case WebCore::AutoplayEvent::UserDidInterfereWithPlayback:
2058 return kWKAutoplayEventUserDidInterfereWithPlayback;
2059 }
2060
2061 RELEASE_ASSERT_NOT_REACHED();
2062 }
2063
2064 void handleAutoplayEvent(WebPageProxy& page, WebCore::AutoplayEvent event, OptionSet<WebCore::AutoplayEventFlags> flags) final
2065 {
2066 if (!m_client.handleAutoplayEvent)
2067 return;
2068
2069 m_client.handleAutoplayEvent(toAPI(&page), toWKAutoplayEvent(event), toWKAutoplayEventFlags(flags), m_client.base.clientInfo);
2070 }
2071 };
2072
2073 toImpl(pageRef)->setUIClient(std::make_unique<UIClient>(wkClient));
2074}
2075
2076void WKPageSetPageNavigationClient(WKPageRef pageRef, const WKPageNavigationClientBase* wkClient)
2077{
2078 class NavigationClient : public API::Client<WKPageNavigationClientBase>, public API::NavigationClient {
2079 public:
2080 explicit NavigationClient(const WKPageNavigationClientBase* client)
2081 {
2082 initialize(client);
2083 }
2084
2085 private:
2086 void decidePolicyForNavigationAction(WebPageProxy& page, Ref<API::NavigationAction>&& navigationAction, Ref<WebKit::WebFramePolicyListenerProxy>&& listener, API::Object* userData) final
2087 {
2088 if (!m_client.decidePolicyForNavigationAction) {
2089 listener->use();
2090 return;
2091 }
2092 m_client.decidePolicyForNavigationAction(toAPI(&page), toAPI(navigationAction.ptr()), toAPI(listener.ptr()), toAPI(userData), m_client.base.clientInfo);
2093 }
2094
2095 void decidePolicyForNavigationResponse(WebPageProxy& page, Ref<API::NavigationResponse>&& navigationResponse, Ref<WebKit::WebFramePolicyListenerProxy>&& listener, API::Object* userData) override
2096 {
2097 if (!m_client.decidePolicyForNavigationResponse) {
2098 listener->use();
2099 return;
2100 }
2101 m_client.decidePolicyForNavigationResponse(toAPI(&page), toAPI(navigationResponse.ptr()), toAPI(listener.ptr()), toAPI(userData), m_client.base.clientInfo);
2102 }
2103
2104 void didStartProvisionalNavigation(WebPageProxy& page, API::Navigation* navigation, API::Object* userData) override
2105 {
2106 if (!m_client.didStartProvisionalNavigation)
2107 return;
2108 m_client.didStartProvisionalNavigation(toAPI(&page), toAPI(navigation), toAPI(userData), m_client.base.clientInfo);
2109 }
2110
2111 void didReceiveServerRedirectForProvisionalNavigation(WebPageProxy& page, API::Navigation* navigation, API::Object* userData) override
2112 {
2113 if (!m_client.didReceiveServerRedirectForProvisionalNavigation)
2114 return;
2115 m_client.didReceiveServerRedirectForProvisionalNavigation(toAPI(&page), toAPI(navigation), toAPI(userData), m_client.base.clientInfo);
2116 }
2117
2118 void didFailProvisionalNavigationWithError(WebPageProxy& page, WebFrameProxy&, API::Navigation* navigation, const WebCore::ResourceError& error, API::Object* userData) override
2119 {
2120 if (!m_client.didFailProvisionalNavigation)
2121 return;
2122 m_client.didFailProvisionalNavigation(toAPI(&page), toAPI(navigation), toAPI(error), toAPI(userData), m_client.base.clientInfo);
2123 }
2124
2125 void didCommitNavigation(WebPageProxy& page, API::Navigation* navigation, API::Object* userData) override
2126 {
2127 if (!m_client.didCommitNavigation)
2128 return;
2129 m_client.didCommitNavigation(toAPI(&page), toAPI(navigation), toAPI(userData), m_client.base.clientInfo);
2130 }
2131
2132 void didFinishNavigation(WebPageProxy& page, API::Navigation* navigation, API::Object* userData) override
2133 {
2134 if (!m_client.didFinishNavigation)
2135 return;
2136 m_client.didFinishNavigation(toAPI(&page), toAPI(navigation), toAPI(userData), m_client.base.clientInfo);
2137 }
2138
2139 void didFailNavigationWithError(WebPageProxy& page, WebFrameProxy&, API::Navigation* navigation, const WebCore::ResourceError& error, API::Object* userData) override
2140 {
2141 if (!m_client.didFailNavigation)
2142 return;
2143 m_client.didFailNavigation(toAPI(&page), toAPI(navigation), toAPI(error), toAPI(userData), m_client.base.clientInfo);
2144 }
2145
2146 void didFailProvisionalLoadInSubframeWithError(WebPageProxy& page, WebFrameProxy& subframe, const WebCore::SecurityOriginData& securityOriginData, API::Navigation* navigation, const WebCore::ResourceError& error, API::Object* userData) override
2147 {
2148 if (!m_client.didFailProvisionalLoadInSubframe)
2149 return;
2150 m_client.didFailProvisionalLoadInSubframe(toAPI(&page), toAPI(navigation), toAPI(API::FrameInfo::create(subframe, securityOriginData.securityOrigin()).ptr()), toAPI(error), toAPI(userData), m_client.base.clientInfo);
2151 }
2152
2153 void didFinishDocumentLoad(WebPageProxy& page, API::Navigation* navigation, API::Object* userData) override
2154 {
2155 if (!m_client.didFinishDocumentLoad)
2156 return;
2157 m_client.didFinishDocumentLoad(toAPI(&page), toAPI(navigation), toAPI(userData), m_client.base.clientInfo);
2158 }
2159
2160 void didSameDocumentNavigation(WebPageProxy& page, API::Navigation* navigation, WebKit::SameDocumentNavigationType navigationType, API::Object* userData) override
2161 {
2162 if (!m_client.didSameDocumentNavigation)
2163 return;
2164 m_client.didSameDocumentNavigation(toAPI(&page), toAPI(navigation), toAPI(navigationType), toAPI(userData), m_client.base.clientInfo);
2165 }
2166
2167 void renderingProgressDidChange(WebPageProxy& page, OptionSet<WebCore::LayoutMilestone> milestones) override
2168 {
2169 if (!m_client.renderingProgressDidChange)
2170 return;
2171 m_client.renderingProgressDidChange(toAPI(&page), pageRenderingProgressEvents(milestones), nullptr, m_client.base.clientInfo);
2172 }
2173
2174 void didReceiveAuthenticationChallenge(WebPageProxy& page, AuthenticationChallengeProxy& authenticationChallenge) override
2175 {
2176 if (m_client.canAuthenticateAgainstProtectionSpace && !m_client.canAuthenticateAgainstProtectionSpace(toAPI(&page), toAPI(WebProtectionSpace::create(authenticationChallenge.core().protectionSpace()).ptr()), m_client.base.clientInfo))
2177 return authenticationChallenge.listener().completeChallenge(WebKit::AuthenticationChallengeDisposition::RejectProtectionSpaceAndContinue);
2178 if (!m_client.didReceiveAuthenticationChallenge)
2179 return authenticationChallenge.listener().completeChallenge(WebKit::AuthenticationChallengeDisposition::PerformDefaultHandling);
2180 m_client.didReceiveAuthenticationChallenge(toAPI(&page), toAPI(&authenticationChallenge), m_client.base.clientInfo);
2181 }
2182
2183 bool processDidTerminate(WebPageProxy& page, WebKit::ProcessTerminationReason reason) override
2184 {
2185 if (m_client.webProcessDidTerminate) {
2186 m_client.webProcessDidTerminate(toAPI(&page), toAPI(reason), m_client.base.clientInfo);
2187 return true;
2188 }
2189
2190 if (m_client.webProcessDidCrash && reason != WebKit::ProcessTerminationReason::RequestedByClient) {
2191 m_client.webProcessDidCrash(toAPI(&page), m_client.base.clientInfo);
2192 return true;
2193 }
2194
2195 return false;
2196 }
2197
2198 RefPtr<API::Data> webCryptoMasterKey(WebPageProxy& page) override
2199 {
2200 if (m_client.copyWebCryptoMasterKey)
2201 return adoptRef(toImpl(m_client.copyWebCryptoMasterKey(toAPI(&page), m_client.base.clientInfo)));
2202
2203 Vector<uint8_t> masterKey;
2204#if ENABLE(WEB_CRYPTO)
2205 if (!getDefaultWebCryptoMasterKey(masterKey))
2206 return nullptr;
2207#endif
2208
2209 return API::Data::create(masterKey.data(), masterKey.size());
2210 }
2211
2212 RefPtr<API::String> signedPublicKeyAndChallengeString(WebPageProxy& page, unsigned keySizeIndex, const RefPtr<API::String>& challengeString, const URL& url) override
2213 {
2214 if (m_client.copySignedPublicKeyAndChallengeString)
2215 return adoptRef(toImpl(m_client.copySignedPublicKeyAndChallengeString(toAPI(&page), m_client.base.clientInfo)));
2216 return API::String::create(WebCore::signedPublicKeyAndChallengeString(keySizeIndex, challengeString->string(), url));
2217 }
2218
2219 void didBeginNavigationGesture(WebPageProxy& page) override
2220 {
2221 if (!m_client.didBeginNavigationGesture)
2222 return;
2223 m_client.didBeginNavigationGesture(toAPI(&page), m_client.base.clientInfo);
2224 }
2225
2226 void didEndNavigationGesture(WebPageProxy& page, bool willNavigate, WebKit::WebBackForwardListItem& item) override
2227 {
2228 if (!m_client.didEndNavigationGesture)
2229 return;
2230 m_client.didEndNavigationGesture(toAPI(&page), willNavigate ? toAPI(&item) : nullptr, m_client.base.clientInfo);
2231 }
2232
2233 void willEndNavigationGesture(WebPageProxy& page, bool willNavigate, WebKit::WebBackForwardListItem& item) override
2234 {
2235 if (!m_client.willEndNavigationGesture)
2236 return;
2237 m_client.willEndNavigationGesture(toAPI(&page), willNavigate ? toAPI(&item) : nullptr, m_client.base.clientInfo);
2238 }
2239
2240 void didRemoveNavigationGestureSnapshot(WebPageProxy& page) override
2241 {
2242 if (!m_client.didRemoveNavigationGestureSnapshot)
2243 return;
2244 m_client.didRemoveNavigationGestureSnapshot(toAPI(&page), m_client.base.clientInfo);
2245 }
2246
2247 void contentRuleListNotification(WebPageProxy& page, URL&& url, ContentRuleListResults&& results) final
2248 {
2249 if (!m_client.contentRuleListNotification)
2250 return;
2251
2252 Vector<RefPtr<API::Object>> apiListIdentifiers;
2253 Vector<RefPtr<API::Object>> apiNotifications;
2254 for (const auto& pair : results.results) {
2255 const String& listIdentifier = pair.first;
2256 const auto& result = pair.second;
2257 for (const String& notification : result.notifications) {
2258 apiListIdentifiers.append(API::String::create(listIdentifier));
2259 apiNotifications.append(API::String::create(notification));
2260 }
2261 }
2262
2263 if (!apiNotifications.isEmpty())
2264 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);
2265 }
2266#if ENABLE(NETSCAPE_PLUGIN_API)
2267 void decidePolicyForPluginLoad(WebPageProxy& page, PluginModuleLoadPolicy currentPluginLoadPolicy, API::Dictionary& pluginInformation, CompletionHandler<void(PluginModuleLoadPolicy, const String&)>&& completionHandler) override
2268 {
2269 WKStringRef unavailabilityDescriptionOut = 0;
2270 PluginModuleLoadPolicy loadPolicy = currentPluginLoadPolicy;
2271
2272 if (m_client.decidePolicyForPluginLoad)
2273 loadPolicy = toPluginModuleLoadPolicy(m_client.decidePolicyForPluginLoad(toAPI(&page), toWKPluginLoadPolicy(currentPluginLoadPolicy), toAPI(&pluginInformation), &unavailabilityDescriptionOut, m_client.base.clientInfo));
2274
2275 String unavailabilityDescription;
2276 if (unavailabilityDescriptionOut) {
2277 RefPtr<API::String> webUnavailabilityDescription = adoptRef(toImpl(unavailabilityDescriptionOut));
2278 unavailabilityDescription = webUnavailabilityDescription->string();
2279 }
2280
2281 completionHandler(loadPolicy, unavailabilityDescription);
2282 }
2283#endif
2284 };
2285
2286 WebPageProxy* webPageProxy = toImpl(pageRef);
2287
2288 webPageProxy->setNavigationClient(makeUniqueRef<NavigationClient>(wkClient));
2289}
2290
2291void WKPageRunJavaScriptInMainFrame(WKPageRef pageRef, WKStringRef scriptRef, void* context, WKPageRunJavaScriptFunction callback)
2292{
2293 toImpl(pageRef)->runJavaScriptInMainFrame(toImpl(scriptRef)->string(), true, [context, callback](API::SerializedScriptValue* returnValue, bool, const WebCore::ExceptionDetails&, CallbackBase::Error error) {
2294 callback(toAPI(returnValue), (error != CallbackBase::Error::None) ? toAPI(API::Error::create().ptr()) : 0, context);
2295 });
2296}
2297
2298#ifdef __BLOCKS__
2299static void callRunJavaScriptBlockAndRelease(WKSerializedScriptValueRef resultValue, WKErrorRef error, void* context)
2300{
2301 WKPageRunJavaScriptBlock block = (WKPageRunJavaScriptBlock)context;
2302 block(resultValue, error);
2303 Block_release(block);
2304}
2305
2306void WKPageRunJavaScriptInMainFrame_b(WKPageRef pageRef, WKStringRef scriptRef, WKPageRunJavaScriptBlock block)
2307{
2308 WKPageRunJavaScriptInMainFrame(pageRef, scriptRef, Block_copy(block), callRunJavaScriptBlockAndRelease);
2309}
2310#endif
2311
2312static WTF::Function<void (const String&, WebKit::CallbackBase::Error)> toGenericCallbackFunction(void* context, void (*callback)(WKStringRef, WKErrorRef, void*))
2313{
2314 return [context, callback](const String& returnValue, WebKit::CallbackBase::Error error) {
2315 callback(toAPI(API::String::create(returnValue).ptr()), error != WebKit::CallbackBase::Error::None ? toAPI(API::Error::create().ptr()) : 0, context);
2316 };
2317}
2318
2319void WKPageRenderTreeExternalRepresentation(WKPageRef pageRef, void* context, WKPageRenderTreeExternalRepresentationFunction callback)
2320{
2321 toImpl(pageRef)->getRenderTreeExternalRepresentation(toGenericCallbackFunction(context, callback));
2322}
2323
2324void WKPageGetSourceForFrame(WKPageRef pageRef, WKFrameRef frameRef, void* context, WKPageGetSourceForFrameFunction callback)
2325{
2326 toImpl(pageRef)->getSourceForFrame(toImpl(frameRef), toGenericCallbackFunction(context, callback));
2327}
2328
2329void WKPageGetContentsAsString(WKPageRef pageRef, void* context, WKPageGetContentsAsStringFunction callback)
2330{
2331 toImpl(pageRef)->getContentsAsString(toGenericCallbackFunction(context, callback));
2332}
2333
2334void WKPageGetBytecodeProfile(WKPageRef pageRef, void* context, WKPageGetBytecodeProfileFunction callback)
2335{
2336 toImpl(pageRef)->getBytecodeProfile(toGenericCallbackFunction(context, callback));
2337}
2338
2339void WKPageGetSamplingProfilerOutput(WKPageRef pageRef, void* context, WKPageGetSamplingProfilerOutputFunction callback)
2340{
2341 toImpl(pageRef)->getSamplingProfilerOutput(toGenericCallbackFunction(context, callback));
2342}
2343
2344void WKPageGetSelectionAsWebArchiveData(WKPageRef pageRef, void* context, WKPageGetSelectionAsWebArchiveDataFunction callback)
2345{
2346 toImpl(pageRef)->getSelectionAsWebArchiveData(toGenericCallbackFunction(context, callback));
2347}
2348
2349void WKPageGetContentsAsMHTMLData(WKPageRef pageRef, void* context, WKPageGetContentsAsMHTMLDataFunction callback)
2350{
2351#if ENABLE(MHTML)
2352 toImpl(pageRef)->getContentsAsMHTMLData(toGenericCallbackFunction(context, callback));
2353#else
2354 UNUSED_PARAM(pageRef);
2355 UNUSED_PARAM(context);
2356 UNUSED_PARAM(callback);
2357#endif
2358}
2359
2360void WKPageForceRepaint(WKPageRef pageRef, void* context, WKPageForceRepaintFunction callback)
2361{
2362 toImpl(pageRef)->forceRepaint(VoidCallback::create([context, callback](WebKit::CallbackBase::Error error) {
2363 callback(error == WebKit::CallbackBase::Error::None ? nullptr : toAPI(API::Error::create().ptr()), context);
2364 }));
2365}
2366
2367WK_EXPORT WKURLRef WKPageCopyPendingAPIRequestURL(WKPageRef pageRef)
2368{
2369 const String& pendingAPIRequestURL = toImpl(pageRef)->pageLoadState().pendingAPIRequestURL();
2370
2371 if (pendingAPIRequestURL.isNull())
2372 return nullptr;
2373
2374 return toCopiedURLAPI(pendingAPIRequestURL);
2375}
2376
2377WKURLRef WKPageCopyActiveURL(WKPageRef pageRef)
2378{
2379 return toCopiedURLAPI(toImpl(pageRef)->pageLoadState().activeURL());
2380}
2381
2382WKURLRef WKPageCopyProvisionalURL(WKPageRef pageRef)
2383{
2384 return toCopiedURLAPI(toImpl(pageRef)->pageLoadState().provisionalURL());
2385}
2386
2387WKURLRef WKPageCopyCommittedURL(WKPageRef pageRef)
2388{
2389 return toCopiedURLAPI(toImpl(pageRef)->pageLoadState().url());
2390}
2391
2392WKStringRef WKPageCopyStandardUserAgentWithApplicationName(WKStringRef applicationName)
2393{
2394 return toCopiedAPI(WebPageProxy::standardUserAgent(toImpl(applicationName)->string()));
2395}
2396
2397void WKPageValidateCommand(WKPageRef pageRef, WKStringRef command, void* context, WKPageValidateCommandCallback callback)
2398{
2399 toImpl(pageRef)->validateCommand(toImpl(command)->string(), [context, callback](const String& commandName, bool isEnabled, int32_t state, WebKit::CallbackBase::Error error) {
2400 callback(toAPI(API::String::create(commandName).ptr()), isEnabled, state, error != WebKit::CallbackBase::Error::None ? toAPI(API::Error::create().ptr()) : 0, context);
2401 });
2402}
2403
2404void WKPageExecuteCommand(WKPageRef pageRef, WKStringRef command)
2405{
2406 toImpl(pageRef)->executeEditCommand(toImpl(command)->string());
2407}
2408
2409static PrintInfo printInfoFromWKPrintInfo(const WKPrintInfo& printInfo)
2410{
2411 PrintInfo result;
2412 result.pageSetupScaleFactor = printInfo.pageSetupScaleFactor;
2413 result.availablePaperWidth = printInfo.availablePaperWidth;
2414 result.availablePaperHeight = printInfo.availablePaperHeight;
2415 return result;
2416}
2417
2418void WKPageComputePagesForPrinting(WKPageRef page, WKFrameRef frame, WKPrintInfo printInfo, WKPageComputePagesForPrintingFunction callback, void* context)
2419{
2420 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) {
2421 Vector<WKRect> wkRects(rects.size());
2422 for (size_t i = 0; i < rects.size(); ++i)
2423 wkRects[i] = toAPI(rects[i]);
2424 callback(wkRects.data(), wkRects.size(), scaleFactor, error != WebKit::CallbackBase::Error::None ? toAPI(API::Error::create().ptr()) : 0, context);
2425 }));
2426}
2427
2428#if PLATFORM(COCOA)
2429void WKPageDrawPagesToPDF(WKPageRef page, WKFrameRef frame, WKPrintInfo printInfo, uint32_t first, uint32_t count, WKPageDrawToPDFFunction callback, void* context)
2430{
2431 toImpl(page)->drawPagesToPDF(toImpl(frame), printInfoFromWKPrintInfo(printInfo), first, count, DataCallback::create(toGenericCallbackFunction(context, callback)));
2432}
2433#endif
2434
2435void WKPageBeginPrinting(WKPageRef page, WKFrameRef frame, WKPrintInfo printInfo)
2436{
2437 toImpl(page)->beginPrinting(toImpl(frame), printInfoFromWKPrintInfo(printInfo));
2438}
2439
2440void WKPageEndPrinting(WKPageRef page)
2441{
2442 toImpl(page)->endPrinting();
2443}
2444
2445bool WKPageGetIsControlledByAutomation(WKPageRef page)
2446{
2447 return toImpl(page)->isControlledByAutomation();
2448}
2449
2450void WKPageSetControlledByAutomation(WKPageRef page, bool controlled)
2451{
2452 toImpl(page)->setControlledByAutomation(controlled);
2453}
2454
2455bool WKPageGetAllowsRemoteInspection(WKPageRef page)
2456{
2457#if ENABLE(REMOTE_INSPECTOR)
2458 return toImpl(page)->allowsRemoteInspection();
2459#else
2460 UNUSED_PARAM(page);
2461 return false;
2462#endif
2463}
2464
2465void WKPageSetAllowsRemoteInspection(WKPageRef page, bool allow)
2466{
2467#if ENABLE(REMOTE_INSPECTOR)
2468 toImpl(page)->setAllowsRemoteInspection(allow);
2469#else
2470 UNUSED_PARAM(page);
2471 UNUSED_PARAM(allow);
2472#endif
2473}
2474
2475void WKPageSetMediaVolume(WKPageRef page, float volume)
2476{
2477 toImpl(page)->setMediaVolume(volume);
2478}
2479
2480void WKPageSetMuted(WKPageRef page, WKMediaMutedState muted)
2481{
2482 toImpl(page)->setMuted(muted);
2483}
2484
2485void WKPageSetMediaCaptureEnabled(WKPageRef page, bool enabled)
2486{
2487 toImpl(page)->setMediaCaptureEnabled(enabled);
2488}
2489
2490bool WKPageGetMediaCaptureEnabled(WKPageRef page)
2491{
2492 return toImpl(page)->mediaCaptureEnabled();
2493}
2494
2495void WKPageDidAllowPointerLock(WKPageRef page)
2496{
2497#if ENABLE(POINTER_LOCK)
2498 toImpl(page)->didAllowPointerLock();
2499#else
2500 UNUSED_PARAM(page);
2501#endif
2502}
2503
2504void WKPageClearUserMediaState(WKPageRef page)
2505{
2506#if ENABLE(MEDIA_STREAM)
2507 toImpl(page)->clearUserMediaState();
2508#else
2509 UNUSED_PARAM(page);
2510#endif
2511}
2512
2513void WKPageDidDenyPointerLock(WKPageRef page)
2514{
2515#if ENABLE(POINTER_LOCK)
2516 toImpl(page)->didDenyPointerLock();
2517#else
2518 UNUSED_PARAM(page);
2519#endif
2520}
2521
2522bool WKPageHasMediaSessionWithActiveMediaElements(WKPageRef page)
2523{
2524#if ENABLE(MEDIA_SESSION)
2525 return toImpl(page)->hasMediaSessionWithActiveMediaElements();
2526#else
2527 UNUSED_PARAM(page);
2528 return false;
2529#endif
2530}
2531
2532void WKPageHandleMediaEvent(WKPageRef page, WKMediaEventType wkEventType)
2533{
2534#if ENABLE(MEDIA_SESSION)
2535 MediaEventType eventType;
2536
2537 switch (wkEventType) {
2538 case kWKMediaEventTypePlayPause:
2539 eventType = MediaEventType::PlayPause;
2540 break;
2541 case kWKMediaEventTypeTrackNext:
2542 eventType = MediaEventType::TrackNext;
2543 break;
2544 case kWKMediaEventTypeTrackPrevious:
2545 eventType = MediaEventType::TrackPrevious;
2546 break;
2547 default:
2548 ASSERT_NOT_REACHED();
2549 return;
2550 }
2551
2552 toImpl(page)->handleMediaEvent(eventType);
2553#else
2554 UNUSED_PARAM(page);
2555 UNUSED_PARAM(wkEventType);
2556#endif
2557}
2558
2559void WKPagePostMessageToInjectedBundle(WKPageRef pageRef, WKStringRef messageNameRef, WKTypeRef messageBodyRef)
2560{
2561 toImpl(pageRef)->postMessageToInjectedBundle(toImpl(messageNameRef)->string(), toImpl(messageBodyRef));
2562}
2563
2564WKArrayRef WKPageCopyRelatedPages(WKPageRef pageRef)
2565{
2566 Vector<RefPtr<API::Object>> relatedPages;
2567
2568 for (auto& page : toImpl(pageRef)->process().pages()) {
2569 if (page != toImpl(pageRef))
2570 relatedPages.append(page);
2571 }
2572
2573 return toAPI(&API::Array::create(WTFMove(relatedPages)).leakRef());
2574}
2575
2576WKFrameRef WKPageLookUpFrameFromHandle(WKPageRef pageRef, WKFrameHandleRef handleRef)
2577{
2578 auto page = toImpl(pageRef);
2579 auto frame = page->process().webFrame(toImpl(handleRef)->frameID());
2580 if (!frame || frame->page() != page)
2581 return nullptr;
2582
2583 return toAPI(frame);
2584}
2585
2586void WKPageSetMayStartMediaWhenInWindow(WKPageRef pageRef, bool mayStartMedia)
2587{
2588 toImpl(pageRef)->setMayStartMediaWhenInWindow(mayStartMedia);
2589}
2590
2591
2592void WKPageSelectContextMenuItem(WKPageRef page, WKContextMenuItemRef item)
2593{
2594#if ENABLE(CONTEXT_MENUS)
2595 toImpl(page)->contextMenuItemSelected((toImpl(item)->data()));
2596#else
2597 UNUSED_PARAM(page);
2598 UNUSED_PARAM(item);
2599#endif
2600}
2601
2602WKScrollPinningBehavior WKPageGetScrollPinningBehavior(WKPageRef page)
2603{
2604 ScrollPinningBehavior pinning = toImpl(page)->scrollPinningBehavior();
2605
2606 switch (pinning) {
2607 case WebCore::ScrollPinningBehavior::DoNotPin:
2608 return kWKScrollPinningBehaviorDoNotPin;
2609 case WebCore::ScrollPinningBehavior::PinToTop:
2610 return kWKScrollPinningBehaviorPinToTop;
2611 case WebCore::ScrollPinningBehavior::PinToBottom:
2612 return kWKScrollPinningBehaviorPinToBottom;
2613 }
2614
2615 ASSERT_NOT_REACHED();
2616 return kWKScrollPinningBehaviorDoNotPin;
2617}
2618
2619void WKPageSetScrollPinningBehavior(WKPageRef page, WKScrollPinningBehavior pinning)
2620{
2621 ScrollPinningBehavior corePinning = ScrollPinningBehavior::DoNotPin;
2622
2623 switch (pinning) {
2624 case kWKScrollPinningBehaviorDoNotPin:
2625 corePinning = ScrollPinningBehavior::DoNotPin;
2626 break;
2627 case kWKScrollPinningBehaviorPinToTop:
2628 corePinning = ScrollPinningBehavior::PinToTop;
2629 break;
2630 case kWKScrollPinningBehaviorPinToBottom:
2631 corePinning = ScrollPinningBehavior::PinToBottom;
2632 break;
2633 default:
2634 ASSERT_NOT_REACHED();
2635 }
2636
2637 toImpl(page)->setScrollPinningBehavior(corePinning);
2638}
2639
2640bool WKPageGetAddsVisitedLinks(WKPageRef page)
2641{
2642 return toImpl(page)->addsVisitedLinks();
2643}
2644
2645void WKPageSetAddsVisitedLinks(WKPageRef page, bool addsVisitedLinks)
2646{
2647 toImpl(page)->setAddsVisitedLinks(addsVisitedLinks);
2648}
2649
2650bool WKPageIsPlayingAudio(WKPageRef page)
2651{
2652 return toImpl(page)->isPlayingAudio();
2653}
2654
2655WKMediaState WKPageGetMediaState(WKPageRef page)
2656{
2657 WebCore::MediaProducer::MediaStateFlags coreState = toImpl(page)->mediaStateFlags();
2658 WKMediaState state = kWKMediaIsNotPlaying;
2659
2660 if (coreState & WebCore::MediaProducer::IsPlayingAudio)
2661 state |= kWKMediaIsPlayingAudio;
2662 if (coreState & WebCore::MediaProducer::IsPlayingVideo)
2663 state |= kWKMediaIsPlayingVideo;
2664 if (coreState & WebCore::MediaProducer::HasActiveAudioCaptureDevice)
2665 state |= kWKMediaHasActiveAudioCaptureDevice;
2666 if (coreState & WebCore::MediaProducer::HasActiveVideoCaptureDevice)
2667 state |= kWKMediaHasActiveVideoCaptureDevice;
2668 if (coreState & WebCore::MediaProducer::HasMutedAudioCaptureDevice)
2669 state |= kWKMediaHasMutedAudioCaptureDevice;
2670 if (coreState & WebCore::MediaProducer::HasMutedVideoCaptureDevice)
2671 state |= kWKMediaHasMutedVideoCaptureDevice;
2672 if (coreState & WebCore::MediaProducer::HasActiveDisplayCaptureDevice)
2673 state |= kWKMediaHasActiveDisplayCaptureDevice;
2674 if (coreState & WebCore::MediaProducer::HasMutedDisplayCaptureDevice)
2675 state |= kWKMediaHasMutedDisplayCaptureDevice;
2676
2677 return state;
2678}
2679
2680void WKPageClearWheelEventTestTrigger(WKPageRef pageRef)
2681{
2682 toImpl(pageRef)->clearWheelEventTestTrigger();
2683}
2684
2685void WKPageCallAfterNextPresentationUpdate(WKPageRef pageRef, void* context, WKPagePostPresentationUpdateFunction callback)
2686{
2687 toImpl(pageRef)->callAfterNextPresentationUpdate([context, callback](WebKit::CallbackBase::Error error) {
2688 callback(error != WebKit::CallbackBase::Error::None ? toAPI(API::Error::create().ptr()) : 0, context);
2689 });
2690}
2691
2692bool WKPageGetResourceCachingDisabled(WKPageRef page)
2693{
2694 return toImpl(page)->isResourceCachingDisabled();
2695}
2696
2697void WKPageSetResourceCachingDisabled(WKPageRef page, bool disabled)
2698{
2699 toImpl(page)->setResourceCachingDisabled(disabled);
2700}
2701
2702void WKPageSetIgnoresViewportScaleLimits(WKPageRef page, bool ignoresViewportScaleLimits)
2703{
2704#if PLATFORM(IOS_FAMILY)
2705 toImpl(page)->setForceAlwaysUserScalable(ignoresViewportScaleLimits);
2706#endif
2707}
2708
2709ProcessID WKPageGetProcessIdentifier(WKPageRef page)
2710{
2711 return toImpl(page)->processIdentifier();
2712}
2713
2714#ifdef __BLOCKS__
2715void WKPageGetApplicationManifest_b(WKPageRef page, WKPageGetApplicationManifestBlock block)
2716{
2717#if ENABLE(APPLICATION_MANIFEST)
2718 toImpl(page)->getApplicationManifest([block](const Optional<WebCore::ApplicationManifest> &manifest, CallbackBase::Error) {
2719 block();
2720 });
2721#else // ENABLE(APPLICATION_MANIFEST)
2722 UNUSED_PARAM(page);
2723 block();
2724#endif // not ENABLE(APPLICATION_MANIFEST)
2725}
2726#endif
2727
2728void WKPageDumpAdClickAttribution(WKPageRef page, WKPageDumpAdClickAttributionFunction callback, void* callbackContext)
2729{
2730 toImpl(page)->dumpAdClickAttribution([callbackContext, callback] (const String& adClickAttribution) {
2731 callback(WebKit::toAPI(adClickAttribution.impl()), callbackContext);
2732 });
2733}
2734
2735void WKPageClearAdClickAttribution(WKPageRef page, WKPageClearAdClickAttributionFunction callback, void* callbackContext)
2736{
2737 toImpl(page)->clearAdClickAttribution([callbackContext, callback] () {
2738 callback(callbackContext);
2739 });
2740}
2741
2742void WKPageSetAdClickAttributionOverrideTimerForTesting(WKPageRef page, bool value, WKPageSetAdClickAttributionOverrideTimerForTestingFunction callback, void* callbackContext)
2743{
2744 toImpl(page)->setAdClickAttributionOverrideTimerForTesting(value, [callbackContext, callback] () {
2745 callback(callbackContext);
2746 });
2747}
2748
2749void WKPageSetAdClickAttributionConversionURLForTesting(WKPageRef page, WKURLRef URLRef, WKPageSetAdClickAttributionConversionURLForTestingFunction callback, void* callbackContext)
2750{
2751 toImpl(page)->setAdClickAttributionConversionURLForTesting(URL(URL(), toWTFString(URLRef)), [callbackContext, callback] () {
2752 callback(callbackContext);
2753 });
2754}
2755
2756void WKPageMarkAdClickAttributionsAsExpiredForTesting(WKPageRef page, WKPageMarkAdClickAttributionsAsExpiredForTestingFunction callback, void* callbackContext)
2757{
2758 toImpl(page)->markAdClickAttributionsAsExpiredForTesting([callbackContext, callback] () {
2759 callback(callbackContext);
2760 });
2761}
2762