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