Many modern media control tests leak documents in testing
[WebKit-https.git] / Source / WebKit / WebProcess / InjectedBundle / API / c / WKBundlePage.cpp
1 /*
2  * Copyright (C) 2010, 2011, 2013, 2015 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27 #include "WKBundlePage.h"
28 #include "WKBundlePagePrivate.h"
29
30 #include "APIArray.h"
31 #include "APIFrameHandle.h"
32 #include "APIString.h"
33 #include "APIURL.h"
34 #include "APIURLRequest.h"
35 #include "InjectedBundleBackForwardList.h"
36 #include "InjectedBundleNodeHandle.h"
37 #include "InjectedBundlePageEditorClient.h"
38 #include "InjectedBundlePageFormClient.h"
39 #include "InjectedBundlePageLoaderClient.h"
40 #include "InjectedBundlePageResourceLoadClient.h"
41 #include "InjectedBundlePageUIClient.h"
42 #include "PageBanner.h"
43 #include "WKAPICast.h"
44 #include "WKArray.h"
45 #include "WKBundleAPICast.h"
46 #include "WKRetainPtr.h"
47 #include "WKString.h"
48 #include "WebContextMenu.h"
49 #include "WebContextMenuItem.h"
50 #include "WebFrame.h"
51 #include "WebFullScreenManager.h"
52 #include "WebImage.h"
53 #include "WebInspector.h"
54 #include "WebPage.h"
55 #include "WebPageGroupProxy.h"
56 #include "WebPageOverlay.h"
57 #include "WebRenderLayer.h"
58 #include "WebRenderObject.h"
59 #include <WebCore/AXObjectCache.h>
60 #include <WebCore/AccessibilityObject.h>
61 #include <WebCore/ApplicationCacheStorage.h>
62 #include <WebCore/Frame.h>
63 #include <WebCore/Page.h>
64 #include <WebCore/PageOverlay.h>
65 #include <WebCore/PageOverlayController.h>
66 #include <WebCore/RenderLayerCompositor.h>
67 #include <WebCore/ScriptExecutionContext.h>
68 #include <WebCore/SecurityOriginData.h>
69 #include <WebCore/URL.h>
70 #include <WebCore/WheelEventTestTrigger.h>
71 #include <wtf/StdLibExtras.h>
72
73 using namespace WebKit;
74
75 WKTypeID WKBundlePageGetTypeID()
76 {
77     return toAPI(WebPage::APIType);
78 }
79
80 void WKBundlePageSetContextMenuClient(WKBundlePageRef pageRef, WKBundlePageContextMenuClientBase* wkClient)
81 {
82 #if ENABLE(CONTEXT_MENUS)
83     toImpl(pageRef)->setInjectedBundleContextMenuClient(std::make_unique<InjectedBundlePageContextMenuClient>(wkClient));
84 #else
85     UNUSED_PARAM(pageRef);
86     UNUSED_PARAM(wkClient);
87 #endif
88 }
89
90 void WKBundlePageSetEditorClient(WKBundlePageRef pageRef, WKBundlePageEditorClientBase* wkClient)
91 {
92     toImpl(pageRef)->setInjectedBundleEditorClient(wkClient ? std::make_unique<InjectedBundlePageEditorClient>(*wkClient) : std::make_unique<API::InjectedBundle::EditorClient>());
93 }
94
95 void WKBundlePageSetFormClient(WKBundlePageRef pageRef, WKBundlePageFormClientBase* wkClient)
96 {
97     toImpl(pageRef)->setInjectedBundleFormClient(std::make_unique<InjectedBundlePageFormClient>(wkClient));
98 }
99
100 void WKBundlePageSetPageLoaderClient(WKBundlePageRef pageRef, WKBundlePageLoaderClientBase* wkClient)
101 {
102     toImpl(pageRef)->setInjectedBundlePageLoaderClient(std::make_unique<InjectedBundlePageLoaderClient>(wkClient));
103 }
104
105 void WKBundlePageSetResourceLoadClient(WKBundlePageRef pageRef, WKBundlePageResourceLoadClientBase* wkClient)
106 {
107     toImpl(pageRef)->setInjectedBundleResourceLoadClient(std::make_unique<InjectedBundlePageResourceLoadClient>(wkClient));
108 }
109
110 void WKBundlePageSetPolicyClient(WKBundlePageRef pageRef, WKBundlePagePolicyClientBase* wkClient)
111 {
112     toImpl(pageRef)->initializeInjectedBundlePolicyClient(wkClient);
113 }
114
115 void WKBundlePageSetUIClient(WKBundlePageRef pageRef, WKBundlePageUIClientBase* wkClient)
116 {
117     toImpl(pageRef)->setInjectedBundleUIClient(std::make_unique<InjectedBundlePageUIClient>(wkClient));
118 }
119
120 void WKBundlePageSetFullScreenClient(WKBundlePageRef pageRef, WKBundlePageFullScreenClientBase* wkClient)
121 {
122 #if defined(ENABLE_FULLSCREEN_API) && ENABLE_FULLSCREEN_API
123     toImpl(pageRef)->initializeInjectedBundleFullScreenClient(wkClient);
124 #else
125     UNUSED_PARAM(pageRef);
126     UNUSED_PARAM(wkClient);
127 #endif
128 }
129
130 void WKBundlePageWillEnterFullScreen(WKBundlePageRef pageRef)
131 {
132 #if defined(ENABLE_FULLSCREEN_API) && ENABLE_FULLSCREEN_API
133     toImpl(pageRef)->fullScreenManager()->willEnterFullScreen();
134 #else
135     UNUSED_PARAM(pageRef);
136 #endif
137 }
138
139 void WKBundlePageDidEnterFullScreen(WKBundlePageRef pageRef)
140 {
141 #if defined(ENABLE_FULLSCREEN_API) && ENABLE_FULLSCREEN_API
142     toImpl(pageRef)->fullScreenManager()->didEnterFullScreen();
143 #else
144     UNUSED_PARAM(pageRef);
145 #endif
146 }
147
148 void WKBundlePageWillExitFullScreen(WKBundlePageRef pageRef)
149 {
150 #if defined(ENABLE_FULLSCREEN_API) && ENABLE_FULLSCREEN_API
151     toImpl(pageRef)->fullScreenManager()->willExitFullScreen();
152 #else
153     UNUSED_PARAM(pageRef);
154 #endif
155 }
156
157 void WKBundlePageDidExitFullScreen(WKBundlePageRef pageRef)
158 {
159 #if defined(ENABLE_FULLSCREEN_API) && ENABLE_FULLSCREEN_API
160     toImpl(pageRef)->fullScreenManager()->didExitFullScreen();
161 #else
162     UNUSED_PARAM(pageRef);
163 #endif
164 }
165
166 WKBundlePageGroupRef WKBundlePageGetPageGroup(WKBundlePageRef pageRef)
167 {
168     return toAPI(toImpl(pageRef)->pageGroup());
169 }
170
171 WKBundleFrameRef WKBundlePageGetMainFrame(WKBundlePageRef pageRef)
172 {
173     return toAPI(toImpl(pageRef)->mainWebFrame());
174 }
175
176 WKFrameHandleRef WKBundleFrameCreateFrameHandle(WKBundleFrameRef bundleFrameRef)
177 {
178     return toAPI(&API::FrameHandle::create(toImpl(bundleFrameRef)->frameID()).leakRef());
179 }
180
181 void WKBundlePageClickMenuItem(WKBundlePageRef pageRef, WKContextMenuItemRef item)
182 {
183 #if ENABLE(CONTEXT_MENUS)
184     toImpl(pageRef)->contextMenu()->itemSelected(toImpl(item)->data());
185 #else
186     UNUSED_PARAM(pageRef);
187     UNUSED_PARAM(item);
188 #endif
189 }
190
191 #if ENABLE(CONTEXT_MENUS)
192 static Ref<API::Array> contextMenuItems(const WebContextMenu& contextMenu)
193 {
194     auto items = contextMenu.items();
195
196     Vector<RefPtr<API::Object>> menuItems;
197     menuItems.reserveInitialCapacity(items.size());
198
199     for (const auto& item : items)
200         menuItems.uncheckedAppend(WebContextMenuItem::create(item));
201
202     return API::Array::create(WTFMove(menuItems));
203 }
204 #endif
205
206 WKArrayRef WKBundlePageCopyContextMenuItems(WKBundlePageRef pageRef)
207 {
208 #if ENABLE(CONTEXT_MENUS)
209     WebContextMenu* contextMenu = toImpl(pageRef)->contextMenu();
210
211     return toAPI(&contextMenuItems(*contextMenu).leakRef());
212 #else
213     UNUSED_PARAM(pageRef);
214     return nullptr;
215 #endif
216 }
217
218 WKArrayRef WKBundlePageCopyContextMenuAtPointInWindow(WKBundlePageRef pageRef, WKPoint point)
219 {
220 #if ENABLE(CONTEXT_MENUS)
221     WebContextMenu* contextMenu = toImpl(pageRef)->contextMenuAtPointInWindow(toIntPoint(point));
222     if (!contextMenu)
223         return nullptr;
224
225     return toAPI(&contextMenuItems(*contextMenu).leakRef());
226 #else
227     UNUSED_PARAM(pageRef);
228     UNUSED_PARAM(point);
229     return nullptr;
230 #endif
231 }
232
233 void WKBundlePageInsertNewlineInQuotedContent(WKBundlePageRef pageRef)
234 {
235     toImpl(pageRef)->insertNewlineInQuotedContent();
236 }
237
238 void* WKAccessibilityRootObject(WKBundlePageRef pageRef)
239 {
240 #if HAVE(ACCESSIBILITY)
241     if (!pageRef)
242         return 0;
243     
244     WebCore::Page* page = toImpl(pageRef)->corePage();
245     if (!page)
246         return 0;
247     
248     WebCore::Frame& core = page->mainFrame();
249     if (!core.document())
250         return 0;
251     
252     WebCore::AXObjectCache::enableAccessibility();
253
254     WebCore::AccessibilityObject* root = core.document()->axObjectCache()->rootObject();
255     if (!root)
256         return 0;
257     
258     return root->wrapper();
259 #else
260     UNUSED_PARAM(pageRef);
261     return 0;
262 #endif
263 }
264
265 void* WKAccessibilityFocusedObject(WKBundlePageRef pageRef)
266 {
267 #if HAVE(ACCESSIBILITY)
268     if (!pageRef)
269         return 0;
270     
271     WebCore::Page* page = toImpl(pageRef)->corePage();
272     if (!page)
273         return 0;
274
275     WebCore::AXObjectCache::enableAccessibility();
276
277     WebCore::AccessibilityObject* focusedObject = WebCore::AXObjectCache::focusedUIElementForPage(page);
278     if (!focusedObject)
279         return 0;
280     
281     return focusedObject->wrapper();
282 #else
283     UNUSED_PARAM(pageRef);
284     return 0;
285 #endif
286 }
287
288 void WKAccessibilityEnableEnhancedAccessibility(bool enable)
289 {
290 #if HAVE(ACCESSIBILITY)
291     WebCore::AXObjectCache::setEnhancedUserInterfaceAccessibility(enable);
292 #endif
293 }
294
295 bool WKAccessibilityEnhancedAccessibilityEnabled()
296 {
297 #if HAVE(ACCESSIBILITY)
298     return WebCore::AXObjectCache::accessibilityEnhancedUserInterfaceEnabled();
299 #else
300     return false;
301 #endif
302 }
303
304 void WKBundlePageStopLoading(WKBundlePageRef pageRef)
305 {
306     toImpl(pageRef)->stopLoading();
307 }
308
309 void WKBundlePageSetDefersLoading(WKBundlePageRef pageRef, bool defersLoading)
310 {
311     toImpl(pageRef)->setDefersLoading(defersLoading);
312 }
313
314 WKStringRef WKBundlePageCopyRenderTreeExternalRepresentation(WKBundlePageRef pageRef)
315 {
316     return toCopiedAPI(toImpl(pageRef)->renderTreeExternalRepresentation());
317 }
318
319 WKStringRef WKBundlePageCopyRenderTreeExternalRepresentationForPrinting(WKBundlePageRef pageRef)
320 {
321     return toCopiedAPI(toImpl(pageRef)->renderTreeExternalRepresentationForPrinting());
322 }
323
324 void WKBundlePageExecuteEditingCommand(WKBundlePageRef pageRef, WKStringRef name, WKStringRef argument)
325 {
326     toImpl(pageRef)->executeEditingCommand(toWTFString(name), toWTFString(argument));
327 }
328
329 bool WKBundlePageIsEditingCommandEnabled(WKBundlePageRef pageRef, WKStringRef name)
330 {
331     return toImpl(pageRef)->isEditingCommandEnabled(toWTFString(name));
332 }
333
334 void WKBundlePageClearMainFrameName(WKBundlePageRef pageRef)
335 {
336     toImpl(pageRef)->clearMainFrameName();
337 }
338
339 void WKBundlePageClose(WKBundlePageRef pageRef)
340 {
341     toImpl(pageRef)->sendClose();
342 }
343
344 double WKBundlePageGetTextZoomFactor(WKBundlePageRef pageRef)
345 {
346     return toImpl(pageRef)->textZoomFactor();
347 }
348
349 void WKBundlePageSetTextZoomFactor(WKBundlePageRef pageRef, double zoomFactor)
350 {
351     toImpl(pageRef)->setTextZoomFactor(zoomFactor);
352 }
353
354 double WKBundlePageGetPageZoomFactor(WKBundlePageRef pageRef)
355 {
356     return toImpl(pageRef)->pageZoomFactor();
357 }
358
359 void WKBundlePageSetPageZoomFactor(WKBundlePageRef pageRef, double zoomFactor)
360 {
361     toImpl(pageRef)->setPageZoomFactor(zoomFactor);
362 }
363
364 void WKBundlePageSetScaleAtOrigin(WKBundlePageRef pageRef, double scale, WKPoint origin)
365 {
366     toImpl(pageRef)->scalePage(scale, toIntPoint(origin));
367 }
368
369 WKBundleBackForwardListRef WKBundlePageGetBackForwardList(WKBundlePageRef pageRef)
370 {
371     return toAPI(toImpl(pageRef)->backForwardList());
372 }
373
374 void WKBundlePageInstallPageOverlay(WKBundlePageRef pageRef, WKBundlePageOverlayRef pageOverlayRef)
375 {
376     toImpl(pageRef)->corePage()->pageOverlayController().installPageOverlay(*toImpl(pageOverlayRef)->coreOverlay(), WebCore::PageOverlay::FadeMode::DoNotFade);
377 }
378
379 void WKBundlePageUninstallPageOverlay(WKBundlePageRef pageRef, WKBundlePageOverlayRef pageOverlayRef)
380 {
381     toImpl(pageRef)->corePage()->pageOverlayController().uninstallPageOverlay(*toImpl(pageOverlayRef)->coreOverlay(), WebCore::PageOverlay::FadeMode::DoNotFade);
382 }
383
384 void WKBundlePageInstallPageOverlayWithAnimation(WKBundlePageRef pageRef, WKBundlePageOverlayRef pageOverlayRef)
385 {
386     toImpl(pageRef)->corePage()->pageOverlayController().installPageOverlay(*toImpl(pageOverlayRef)->coreOverlay(), WebCore::PageOverlay::FadeMode::Fade);
387 }
388
389 void WKBundlePageUninstallPageOverlayWithAnimation(WKBundlePageRef pageRef, WKBundlePageOverlayRef pageOverlayRef)
390 {
391     toImpl(pageRef)->corePage()->pageOverlayController().uninstallPageOverlay(*toImpl(pageOverlayRef)->coreOverlay(), WebCore::PageOverlay::FadeMode::Fade);
392 }
393
394 void WKBundlePageSetTopOverhangImage(WKBundlePageRef pageRef, WKImageRef imageRef)
395 {
396 #if PLATFORM(MAC)
397     toImpl(pageRef)->setTopOverhangImage(toImpl(imageRef));
398 #else
399     UNUSED_PARAM(pageRef);
400     UNUSED_PARAM(imageRef);
401 #endif
402 }
403
404 void WKBundlePageSetBottomOverhangImage(WKBundlePageRef pageRef, WKImageRef imageRef)
405 {
406 #if PLATFORM(MAC)
407     toImpl(pageRef)->setBottomOverhangImage(toImpl(imageRef));
408 #else
409     UNUSED_PARAM(pageRef);
410     UNUSED_PARAM(imageRef);
411 #endif
412 }
413
414 #if !PLATFORM(IOS)
415 void WKBundlePageSetHeaderBanner(WKBundlePageRef pageRef, WKBundlePageBannerRef bannerRef)
416 {
417     toImpl(pageRef)->setHeaderPageBanner(toImpl(bannerRef));
418 }
419
420 void WKBundlePageSetFooterBanner(WKBundlePageRef pageRef, WKBundlePageBannerRef bannerRef)
421 {
422     toImpl(pageRef)->setFooterPageBanner(toImpl(bannerRef));
423 }
424 #endif // !PLATFORM(IOS)
425
426 bool WKBundlePageHasLocalDataForURL(WKBundlePageRef pageRef, WKURLRef urlRef)
427 {
428     return toImpl(pageRef)->hasLocalDataForURL(WebCore::URL(WebCore::URL(), toWTFString(urlRef)));
429 }
430
431 bool WKBundlePageCanHandleRequest(WKURLRequestRef requestRef)
432 {
433     if (!requestRef)
434         return false;
435     return WebPage::canHandleRequest(toImpl(requestRef)->resourceRequest());
436 }
437
438 bool WKBundlePageFindString(WKBundlePageRef pageRef, WKStringRef target, WKFindOptions findOptions)
439 {
440     return toImpl(pageRef)->findStringFromInjectedBundle(toWTFString(target), toFindOptions(findOptions));
441 }
442
443 WKImageRef WKBundlePageCreateSnapshotWithOptions(WKBundlePageRef pageRef, WKRect rect, WKSnapshotOptions options)
444 {
445     RefPtr<WebImage> webImage = toImpl(pageRef)->scaledSnapshotWithOptions(toIntRect(rect), 1, toSnapshotOptions(options));
446     return toAPI(webImage.leakRef());
447 }
448
449 WKImageRef WKBundlePageCreateSnapshotInViewCoordinates(WKBundlePageRef pageRef, WKRect rect, WKImageOptions options)
450 {
451     SnapshotOptions snapshotOptions = snapshotOptionsFromImageOptions(options);
452     snapshotOptions |= SnapshotOptionsInViewCoordinates;
453     RefPtr<WebImage> webImage = toImpl(pageRef)->scaledSnapshotWithOptions(toIntRect(rect), 1, snapshotOptions);
454     return toAPI(webImage.leakRef());
455 }
456
457 WKImageRef WKBundlePageCreateSnapshotInDocumentCoordinates(WKBundlePageRef pageRef, WKRect rect, WKImageOptions options)
458 {
459     RefPtr<WebImage> webImage = toImpl(pageRef)->scaledSnapshotWithOptions(toIntRect(rect), 1, snapshotOptionsFromImageOptions(options));
460     return toAPI(webImage.leakRef());
461 }
462
463 WKImageRef WKBundlePageCreateScaledSnapshotInDocumentCoordinates(WKBundlePageRef pageRef, WKRect rect, double scaleFactor, WKImageOptions options)
464 {
465     RefPtr<WebImage> webImage = toImpl(pageRef)->scaledSnapshotWithOptions(toIntRect(rect), scaleFactor, snapshotOptionsFromImageOptions(options));
466     return toAPI(webImage.leakRef());
467 }
468
469 double WKBundlePageGetBackingScaleFactor(WKBundlePageRef pageRef)
470 {
471     return toImpl(pageRef)->deviceScaleFactor();
472 }
473
474 void WKBundlePageListenForLayoutMilestones(WKBundlePageRef pageRef, WKLayoutMilestones milestones)
475 {
476     toImpl(pageRef)->listenForLayoutMilestones(toLayoutMilestones(milestones));
477 }
478
479 WKBundleInspectorRef WKBundlePageGetInspector(WKBundlePageRef pageRef)
480 {
481     return toAPI(toImpl(pageRef)->inspector());
482 }
483
484 void WKBundlePageForceRepaint(WKBundlePageRef page)
485 {
486     toImpl(page)->forceRepaintWithoutCallback();
487 }
488
489 void WKBundlePageSimulateMouseDown(WKBundlePageRef page, int button, WKPoint position, int clickCount, WKEventModifiers modifiers, double time)
490 {
491     toImpl(page)->simulateMouseDown(button, toIntPoint(position), clickCount, modifiers, WallTime::fromRawSeconds(time));
492 }
493
494 void WKBundlePageSimulateMouseUp(WKBundlePageRef page, int button, WKPoint position, int clickCount, WKEventModifiers modifiers, double time)
495 {
496     toImpl(page)->simulateMouseUp(button, toIntPoint(position), clickCount, modifiers, WallTime::fromRawSeconds(time));
497 }
498
499 void WKBundlePageSimulateMouseMotion(WKBundlePageRef page, WKPoint position, double time)
500 {
501     toImpl(page)->simulateMouseMotion(toIntPoint(position), WallTime::fromRawSeconds(time));
502 }
503
504 uint64_t WKBundlePageGetRenderTreeSize(WKBundlePageRef pageRef)
505 {
506     return toImpl(pageRef)->renderTreeSize();
507 }
508
509 WKRenderObjectRef WKBundlePageCopyRenderTree(WKBundlePageRef pageRef)
510 {
511     return toAPI(WebRenderObject::create(toImpl(pageRef)).leakRef());
512 }
513
514 WKRenderLayerRef WKBundlePageCopyRenderLayerTree(WKBundlePageRef pageRef)
515 {
516     return toAPI(WebRenderLayer::create(toImpl(pageRef)).leakRef());
517 }
518
519 void WKBundlePageSetPaintedObjectsCounterThreshold(WKBundlePageRef, uint64_t)
520 {
521     // FIXME: This function is only still here to keep open source Mac builds building.
522     // We should remove it as soon as we can.
523 }
524
525 void WKBundlePageSetTracksRepaints(WKBundlePageRef pageRef, bool trackRepaints)
526 {
527     toImpl(pageRef)->setTracksRepaints(trackRepaints);
528 }
529
530 bool WKBundlePageIsTrackingRepaints(WKBundlePageRef pageRef)
531 {
532     return toImpl(pageRef)->isTrackingRepaints();
533 }
534
535 void WKBundlePageResetTrackedRepaints(WKBundlePageRef pageRef)
536 {
537     toImpl(pageRef)->resetTrackedRepaints();
538 }
539
540 WKArrayRef WKBundlePageCopyTrackedRepaintRects(WKBundlePageRef pageRef)
541 {
542     return toAPI(&toImpl(pageRef)->trackedRepaintRects().leakRef());
543 }
544
545 void WKBundlePageSetComposition(WKBundlePageRef pageRef, WKStringRef text, int from, int length, bool suppressUnderline)
546 {
547     toImpl(pageRef)->setCompositionForTesting(toWTFString(text), from, length, suppressUnderline);
548 }
549
550 bool WKBundlePageHasComposition(WKBundlePageRef pageRef)
551 {
552     return toImpl(pageRef)->hasCompositionForTesting();
553 }
554
555 void WKBundlePageConfirmComposition(WKBundlePageRef pageRef)
556 {
557     toImpl(pageRef)->confirmCompositionForTesting(String());
558 }
559
560 void WKBundlePageConfirmCompositionWithText(WKBundlePageRef pageRef, WKStringRef text)
561 {
562     toImpl(pageRef)->confirmCompositionForTesting(toWTFString(text));
563 }
564
565 bool WKBundlePageCanShowMIMEType(WKBundlePageRef pageRef, WKStringRef mimeTypeRef)
566 {
567     return toImpl(pageRef)->canShowMIMEType(toWTFString(mimeTypeRef));
568 }
569
570 WKRenderingSuppressionToken WKBundlePageExtendIncrementalRenderingSuppression(WKBundlePageRef pageRef)
571 {
572     return toImpl(pageRef)->extendIncrementalRenderingSuppression();
573 }
574
575 void WKBundlePageStopExtendingIncrementalRenderingSuppression(WKBundlePageRef pageRef, WKRenderingSuppressionToken token)
576 {
577     toImpl(pageRef)->stopExtendingIncrementalRenderingSuppression(token);
578 }
579
580 bool WKBundlePageIsUsingEphemeralSession(WKBundlePageRef pageRef)
581 {
582     return toImpl(pageRef)->usesEphemeralSession();
583 }
584
585 bool WKBundlePageIsControlledByAutomation(WKBundlePageRef pageRef)
586 {
587     return toImpl(pageRef)->isControlledByAutomation();
588 }
589
590 #if TARGET_OS_IPHONE
591 void WKBundlePageSetUseTestingViewportConfiguration(WKBundlePageRef pageRef, bool useTestingViewportConfiguration)
592 {
593     toImpl(pageRef)->setUseTestingViewportConfiguration(useTestingViewportConfiguration);
594 }
595 #endif
596
597 void WKBundlePageStartMonitoringScrollOperations(WKBundlePageRef pageRef)
598 {
599     WebKit::WebPage* webPage = toImpl(pageRef);
600     WebCore::Page* page = webPage ? webPage->corePage() : nullptr;
601     
602     if (!page)
603         return;
604
605     page->ensureTestTrigger();
606 }
607
608 void WKBundlePageRegisterScrollOperationCompletionCallback(WKBundlePageRef pageRef, WKBundlePageTestNotificationCallback callback, void* context)
609 {
610     if (!callback)
611         return;
612     
613     WebKit::WebPage* webPage = toImpl(pageRef);
614     WebCore::Page* page = webPage ? webPage->corePage() : nullptr;
615     if (!page || !page->expectsWheelEventTriggers())
616         return;
617     
618     page->ensureTestTrigger().setTestCallbackAndStartNotificationTimer([=]() {
619         callback(context);
620     });
621 }
622
623 void WKBundlePageCallAfterTasksAndTimers(WKBundlePageRef pageRef, WKBundlePageTestNotificationCallback callback, void* context)
624 {
625     if (!callback)
626         return;
627     
628     WebKit::WebPage* webPage = toImpl(pageRef);
629     WebCore::Page* page = webPage ? webPage->corePage() : nullptr;
630     if (!page)
631         return;
632
633     WebCore::Document* document = page->mainFrame().document();
634     if (!document)
635         return;
636
637     class TimerOwner {
638     public:
639         TimerOwner(WTF::Function<void (void*)>&& callback, void* context)
640             : m_timer(*this, &TimerOwner::timerFired)
641             , m_callback(WTFMove(callback))
642             , m_context(context)
643         {
644             m_timer.startOneShot(0_s);
645         }
646         
647         void timerFired()
648         {
649             m_callback(m_context);
650             delete this;
651         }
652         
653         WebCore::Timer m_timer;
654         WTF::Function<void (void*)> m_callback;
655         void* m_context;
656     };
657     
658     document->postTask([=] (WebCore::ScriptExecutionContext&) {
659         new TimerOwner(callback, context); // deletes itself when done.
660     });
661 }
662
663 void WKBundlePagePostMessage(WKBundlePageRef pageRef, WKStringRef messageNameRef, WKTypeRef messageBodyRef)
664 {
665     toImpl(pageRef)->postMessage(toWTFString(messageNameRef), toImpl(messageBodyRef));
666 }
667
668 void WKBundlePagePostSynchronousMessageForTesting(WKBundlePageRef pageRef, WKStringRef messageNameRef, WKTypeRef messageBodyRef, WKTypeRef* returnDataRef)
669 {
670     WebPage* page = toImpl(pageRef);
671     page->layoutIfNeeded();
672
673     RefPtr<API::Object> returnData;
674     page->postSynchronousMessageForTesting(toWTFString(messageNameRef), toImpl(messageBodyRef), returnData);
675     if (returnDataRef)
676         *returnDataRef = toAPI(returnData.leakRef());
677 }
678
679 void WKBundlePageAddUserScript(WKBundlePageRef pageRef, WKStringRef source, _WKUserScriptInjectionTime injectionTime, WKUserContentInjectedFrames injectedFrames)
680 {
681     toImpl(pageRef)->addUserScript(toWTFString(source), toUserContentInjectedFrames(injectedFrames), toUserScriptInjectionTime(injectionTime));
682 }
683
684 void WKBundlePageAddUserStyleSheet(WKBundlePageRef pageRef, WKStringRef source, WKUserContentInjectedFrames injectedFrames)
685 {
686     toImpl(pageRef)->addUserStyleSheet(toWTFString(source), toUserContentInjectedFrames(injectedFrames));
687 }
688
689 void WKBundlePageRemoveAllUserContent(WKBundlePageRef pageRef)
690 {
691     toImpl(pageRef)->removeAllUserContent();
692 }
693
694 WKStringRef WKBundlePageCopyGroupIdentifier(WKBundlePageRef pageRef)
695 {
696     return toCopiedAPI(toImpl(pageRef)->pageGroup()->identifier());
697 }
698
699 void WKBundlePageClearApplicationCache(WKBundlePageRef page)
700 {
701     toImpl(page)->corePage()->applicationCacheStorage().deleteAllEntries();
702 }
703
704 void WKBundlePageClearApplicationCacheForOrigin(WKBundlePageRef page, WKStringRef origin)
705 {
706     toImpl(page)->corePage()->applicationCacheStorage().deleteCacheForOrigin(WebCore::SecurityOrigin::createFromString(toImpl(origin)->string()));
707 }
708
709 void WKBundlePageSetAppCacheMaximumSize(WKBundlePageRef page, uint64_t size)
710 {
711     toImpl(page)->corePage()->applicationCacheStorage().setMaximumSize(size);
712 }
713
714 uint64_t WKBundlePageGetAppCacheUsageForOrigin(WKBundlePageRef page, WKStringRef origin)
715 {
716     return toImpl(page)->corePage()->applicationCacheStorage().diskUsageForOrigin(WebCore::SecurityOrigin::createFromString(toImpl(origin)->string()));
717 }
718
719 void WKBundlePageSetApplicationCacheOriginQuota(WKBundlePageRef page, WKStringRef origin, uint64_t bytes)
720 {
721     toImpl(page)->corePage()->applicationCacheStorage().storeUpdatedQuotaForOrigin(WebCore::SecurityOrigin::createFromString(toImpl(origin)->string()).ptr(), bytes);
722 }
723
724 void WKBundlePageResetApplicationCacheOriginQuota(WKBundlePageRef page, WKStringRef origin)
725 {
726     toImpl(page)->corePage()->applicationCacheStorage().storeUpdatedQuotaForOrigin(WebCore::SecurityOrigin::createFromString(toImpl(origin)->string()).ptr(), toImpl(page)->corePage()->applicationCacheStorage().defaultOriginQuota());
727 }
728
729 WKArrayRef WKBundlePageCopyOriginsWithApplicationCache(WKBundlePageRef page)
730 {
731     auto origins = toImpl(page)->corePage()->applicationCacheStorage().originsWithCache();
732
733     Vector<RefPtr<API::Object>> originIdentifiers;
734     originIdentifiers.reserveInitialCapacity(origins.size());
735
736     for (const auto& origin : origins)
737         originIdentifiers.uncheckedAppend(API::String::create(origin->data().databaseIdentifier()));
738
739     return toAPI(&API::Array::create(WTFMove(originIdentifiers)).leakRef());
740 }
741
742 void WKBundlePageSetEventThrottlingBehaviorOverride(WKBundlePageRef page, WKEventThrottlingBehavior* behavior)
743 {
744     std::optional<WebCore::EventThrottlingBehavior> behaviorValue;
745     if (behavior) {
746         switch (*behavior) {
747         case kWKEventThrottlingBehaviorResponsive:
748             behaviorValue = WebCore::EventThrottlingBehavior::Responsive;
749             break;
750         case kWKEventThrottlingBehaviorUnresponsive:
751             behaviorValue = WebCore::EventThrottlingBehavior::Unresponsive;
752             break;
753         }
754     }
755
756     toImpl(page)->corePage()->setEventThrottlingBehaviorOverride(behaviorValue);
757 }
758
759 void WKBundlePageSetCompositingPolicyOverride(WKBundlePageRef page, WKCompositingPolicy* policy)
760 {
761     std::optional<WebCore::CompositingPolicy> policyValue;
762     if (policy) {
763         switch (*policy) {
764         case kWKCompositingPolicyNormal:
765             policyValue = WebCore::CompositingPolicy::Normal;
766             break;
767         case kWKCompositingPolicyConservative:
768             policyValue = WebCore::CompositingPolicy::Conservative;
769             break;
770         }
771     }
772
773     toImpl(page)->corePage()->setCompositingPolicyOverride(policyValue);
774 }
775