Unreviewed, reverting r260769.
[WebKit.git] / Source / WebCore / testing / Internals.cpp
1 /*
2  * Copyright (C) 2012 Google Inc. All rights reserved.
3  * Copyright (C) 2013-2020 Apple Inc. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1.  Redistributions of source code must retain the above copyright
10  *     notice, this list of conditions and the following disclaimer.
11  * 2.  Redistributions in binary form must reproduce the above copyright
12  *     notice, this list of conditions and the following disclaimer in the
13  *     documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
16  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
19  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  */
26
27 #include "config.h"
28 #include "Internals.h"
29
30 #include "AXObjectCache.h"
31 #include "ActivityState.h"
32 #include "AnimationTimeline.h"
33 #include "ApplicationCacheStorage.h"
34 #include "AudioSession.h"
35 #include "AudioTrackPrivateMediaStream.h"
36 #include "Autofill.h"
37 #include "BackForwardCache.h"
38 #include "BackForwardController.h"
39 #include "BitmapImage.h"
40 #include "CSSAnimationController.h"
41 #include "CSSKeyframesRule.h"
42 #include "CSSMediaRule.h"
43 #include "CSSPropertyParser.h"
44 #include "CSSStyleRule.h"
45 #include "CSSSupportsRule.h"
46 #include "CacheStorageConnection.h"
47 #include "CacheStorageProvider.h"
48 #include "CachedImage.h"
49 #include "CachedResourceLoader.h"
50 #include "CertificateInfo.h"
51 #include "Chrome.h"
52 #include "ChromeClient.h"
53 #include "ClientOrigin.h"
54 #include "ComposedTreeIterator.h"
55 #include "CookieJar.h"
56 #include "Cursor.h"
57 #include "CustomHeaderFields.h"
58 #include "DOMRect.h"
59 #include "DOMRectList.h"
60 #include "DOMStringList.h"
61 #include "DOMURL.h"
62 #include "DOMWindow.h"
63 #include "DeprecatedGlobalSettings.h"
64 #include "DiagnosticLoggingClient.h"
65 #include "DisabledAdaptations.h"
66 #include "DisplayList.h"
67 #include "Document.h"
68 #include "DocumentLoader.h"
69 #include "DocumentMarkerController.h"
70 #include "DocumentTimeline.h"
71 #include "Editor.h"
72 #include "Element.h"
73 #include "EventHandler.h"
74 #include "EventListener.h"
75 #include "EventLoop.h"
76 #include "EventNames.h"
77 #include "ExtendableEvent.h"
78 #include "ExtensionStyleSheets.h"
79 #include "FetchResponse.h"
80 #include "File.h"
81 #include "FontCache.h"
82 #include "FormController.h"
83 #include "Frame.h"
84 #include "FrameLoader.h"
85 #include "FrameView.h"
86 #include "FullscreenManager.h"
87 #include "GCObservation.h"
88 #include "GridPosition.h"
89 #include "HEVCUtilities.h"
90 #include "HTMLAnchorElement.h"
91 #include "HTMLCanvasElement.h"
92 #include "HTMLIFrameElement.h"
93 #include "HTMLImageElement.h"
94 #include "HTMLInputElement.h"
95 #include "HTMLLinkElement.h"
96 #include "HTMLNames.h"
97 #include "HTMLPictureElement.h"
98 #include "HTMLPlugInElement.h"
99 #include "HTMLPreloadScanner.h"
100 #include "HTMLSelectElement.h"
101 #include "HTMLTextAreaElement.h"
102 #include "HTMLVideoElement.h"
103 #include "HistoryController.h"
104 #include "HistoryItem.h"
105 #include "HitTestResult.h"
106 #include "InspectorClient.h"
107 #include "InspectorController.h"
108 #include "InspectorDebuggableType.h"
109 #include "InspectorFrontendClientLocal.h"
110 #include "InspectorOverlay.h"
111 #include "InstrumentingAgents.h"
112 #include "IntRect.h"
113 #include "InternalSettings.h"
114 #include "InternalsMapLike.h"
115 #include "InternalsSetLike.h"
116 #include "JSDOMPromiseDeferred.h"
117 #include "JSImageData.h"
118 #include "LegacySchemeRegistry.h"
119 #include "LibWebRTCProvider.h"
120 #include "LoaderStrategy.h"
121 #include "Location.h"
122 #include "MIMETypeRegistry.h"
123 #include "MallocStatistics.h"
124 #include "MediaDevices.h"
125 #include "MediaEngineConfigurationFactory.h"
126 #include "MediaPlayer.h"
127 #include "MediaProducer.h"
128 #include "MediaRecorderProvider.h"
129 #include "MediaResourceLoader.h"
130 #include "MediaStreamTrack.h"
131 #include "MediaUsageInfo.h"
132 #include "MemoryCache.h"
133 #include "MemoryInfo.h"
134 #include "MockAudioDestinationCocoa.h"
135 #include "MockLibWebRTCPeerConnection.h"
136 #include "MockPageOverlay.h"
137 #include "MockPageOverlayClient.h"
138 #include "NavigatorBeacon.h"
139 #include "NavigatorMediaDevices.h"
140 #include "NetworkLoadInformation.h"
141 #include "Page.h"
142 #include "PageOverlay.h"
143 #include "PathUtilities.h"
144 #include "PictureInPictureSupport.h"
145 #include "PlatformKeyboardEvent.h"
146 #include "PlatformMediaSessionManager.h"
147 #include "PlatformScreen.h"
148 #include "PlatformStrategies.h"
149 #include "PluginData.h"
150 #include "PrintContext.h"
151 #include "PseudoElement.h"
152 #include "Range.h"
153 #include "ReadableStream.h"
154 #include "RenderEmbeddedObject.h"
155 #include "RenderLayerBacking.h"
156 #include "RenderLayerCompositor.h"
157 #include "RenderMenuList.h"
158 #include "RenderTheme.h"
159 #include "RenderTreeAsText.h"
160 #include "RenderView.h"
161 #include "RenderedDocumentMarker.h"
162 #include "ResourceLoadObserver.h"
163 #include "RuntimeEnabledFeatures.h"
164 #include "SMILTimeContainer.h"
165 #include "SVGDocumentExtensions.h"
166 #include "SVGPathStringBuilder.h"
167 #include "SVGSVGElement.h"
168 #include "SWClientConnection.h"
169 #include "ScriptController.h"
170 #include "ScriptedAnimationController.h"
171 #include "ScrollingCoordinator.h"
172 #include "ScrollingMomentumCalculator.h"
173 #include "SecurityOrigin.h"
174 #include "SerializedScriptValue.h"
175 #include "ServiceWorker.h"
176 #include "ServiceWorkerProvider.h"
177 #include "ServiceWorkerRegistrationData.h"
178 #include "Settings.h"
179 #include "ShadowRoot.h"
180 #include "SourceBuffer.h"
181 #include "SpellChecker.h"
182 #include "StaticNodeList.h"
183 #include "StorageNamespace.h"
184 #include "StorageNamespaceProvider.h"
185 #include "StringCallback.h"
186 #include "StyleResolver.h"
187 #include "StyleRule.h"
188 #include "StyleScope.h"
189 #include "StyleSheetContents.h"
190 #include "TextIterator.h"
191 #include "TextPlaceholderElement.h"
192 #include "TreeScope.h"
193 #include "TypeConversions.h"
194 #include "UserGestureIndicator.h"
195 #include "UserMediaController.h"
196 #include "ViewportArguments.h"
197 #include "VoidCallback.h"
198 #include "WebAnimation.h"
199 #include "WebCoreJSClientData.h"
200 #include "WindowProxy.h"
201 #include "WorkerThread.h"
202 #include "WorkletGlobalScope.h"
203 #include "WritingDirection.h"
204 #include "XMLHttpRequest.h"
205 #include <JavaScriptCore/CodeBlock.h>
206 #include <JavaScriptCore/InspectorAgentBase.h>
207 #include <JavaScriptCore/InspectorFrontendChannel.h>
208 #include <JavaScriptCore/JSCInlines.h>
209 #include <JavaScriptCore/JSCJSValue.h>
210 #include <wtf/HexNumber.h>
211 #include <wtf/JSONValues.h>
212 #include <wtf/Language.h>
213 #include <wtf/MemoryPressureHandler.h>
214 #include <wtf/MonotonicTime.h>
215 #include <wtf/ProcessID.h>
216 #include <wtf/URLHelpers.h>
217 #include <wtf/text/StringBuilder.h>
218 #include <wtf/text/StringConcatenateNumbers.h>
219
220 #if USE(CG)
221 #include "PDFDocumentImage.h"
222 #endif
223
224 #if ENABLE(INPUT_TYPE_COLOR)
225 #include "ColorChooser.h"
226 #endif
227
228 #if ENABLE(MOUSE_CURSOR_SCALE)
229 #include <wtf/dtoa.h>
230 #endif
231
232 #if ENABLE(LEGACY_ENCRYPTED_MEDIA)
233 #include "LegacyCDM.h"
234 #include "LegacyMockCDM.h"
235 #endif
236
237 #if ENABLE(ENCRYPTED_MEDIA)
238 #include "MockCDMFactory.h"
239 #endif
240
241 #if ENABLE(VIDEO_TRACK)
242 #include "CaptionUserPreferences.h"
243 #include "PageGroup.h"
244 #include "TextTrack.h"
245 #include "TextTrackCueGeneric.h"
246 #endif
247
248 #if ENABLE(VIDEO)
249 #include "HTMLMediaElement.h"
250 #include "TimeRanges.h"
251 #endif
252
253 #if ENABLE(WEBGL)
254 #include "WebGLRenderingContext.h"
255 #endif
256
257 #if ENABLE(SPEECH_SYNTHESIS)
258 #include "DOMWindowSpeechSynthesis.h"
259 #include "PlatformSpeechSynthesizerMock.h"
260 #include "SpeechSynthesis.h"
261 #endif
262
263 #if ENABLE(MEDIA_STREAM)
264 #include "MediaRecorder.h"
265 #include "MediaRecorderPrivateMock.h"
266 #include "MediaStream.h"
267 #include "MockRealtimeMediaSourceCenter.h"
268 #endif
269
270 #if ENABLE(WEB_RTC)
271 #include "RTCPeerConnection.h"
272 #endif
273
274 #if ENABLE(MEDIA_SOURCE)
275 #include "MockMediaPlayerMediaSource.h"
276 #endif
277
278 #if ENABLE(CONTENT_FILTERING)
279 #include "MockContentFilterSettings.h"
280 #endif
281
282 #if ENABLE(WEB_AUDIO)
283 #include "AudioContext.h"
284 #endif
285
286 #if ENABLE(MEDIA_SESSION)
287 #include "MediaSession.h"
288 #include "MediaSessionManager.h"
289 #endif
290
291 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
292 #include "MediaPlaybackTargetContext.h"
293 #endif
294
295 #if ENABLE(POINTER_LOCK)
296 #include "PointerLockController.h"
297 #endif
298
299 #if ENABLE(INDEXED_DATABASE)
300 #include "IDBRequest.h"
301 #include "IDBTransaction.h"
302 #endif
303
304 #if USE(QUICK_LOOK)
305 #include "LegacyPreviewLoader.h"
306 #include "MockPreviewLoaderClient.h"
307 #endif
308
309 #if ENABLE(APPLE_PAY)
310 #include "MockPaymentCoordinator.h"
311 #include "PaymentCoordinator.h"
312 #endif
313
314 #if ENABLE(WEBXR)
315 #include "NavigatorWebXR.h"
316 #include "WebXRSystem.h"
317 #include "WebXRTest.h"
318 #endif
319
320 #if PLATFORM(MAC) && USE(LIBWEBRTC)
321 #include <webrtc/sdk/WebKit/VideoProcessingSoftLink.h>
322 #endif
323
324 #if PLATFORM(MAC)
325 #include "GraphicsContextGLOpenGLManager.h"
326 #include "NSScrollerImpDetails.h"
327 #include "ScrollbarThemeMac.h"
328 #endif
329
330 #if PLATFORM(COCOA)
331 #include "SystemBattery.h"
332 #include <wtf/spi/darwin/SandboxSPI.h>
333 #endif
334
335 using JSC::CallData;
336 using JSC::CodeBlock;
337 using JSC::FunctionExecutable;
338 using JSC::Identifier;
339 using JSC::JSFunction;
340 using JSC::JSGlobalObject;
341 using JSC::JSObject;
342 using JSC::JSValue;
343 using JSC::MarkedArgumentBuffer;
344 using JSC::PropertySlot;
345 using JSC::ScriptExecutable;
346 using JSC::StackVisitor;
347
348
349 namespace WebCore {
350 using namespace Inspector;
351
352 using namespace HTMLNames;
353
354 class InspectorStubFrontend final : public InspectorFrontendClientLocal, public FrontendChannel {
355 public:
356     InspectorStubFrontend(Page& inspectedPage, RefPtr<DOMWindow>&& frontendWindow);
357     virtual ~InspectorStubFrontend();
358
359 private:
360     bool supportsDockSide(DockSide) final { return false; }
361     void attachWindow(DockSide) final { }
362     void detachWindow() final { }
363     void closeWindow() final;
364     void reopen() final { }
365     void bringToFront() final { }
366     void setForcedAppearance(InspectorFrontendClient::Appearance) final { }
367     String localizedStringsURL() const final { return String(); }
368     DebuggableType debuggableType() const final { return DebuggableType::Page; }
369     String targetPlatformName() const { return "Unknown"_s; }
370     String targetBuildVersion() const { return "Unknown"_s; }
371     String targetProductVersion() const { return "Unknown"_s; }
372     bool targetIsSimulator() const { return false; }
373     void inspectedURLChanged(const String&) final { }
374     void showCertificate(const CertificateInfo&) final { }
375     void setAttachedWindowHeight(unsigned) final { }
376     void setAttachedWindowWidth(unsigned) final { }
377     void setSheetRect(const FloatRect&) final { }
378
379     void sendMessageToFrontend(const String& message) final;
380     ConnectionType connectionType() const final { return ConnectionType::Local; }
381
382     RefPtr<DOMWindow> m_frontendWindow;
383 };
384
385 InspectorStubFrontend::InspectorStubFrontend(Page& inspectedPage, RefPtr<DOMWindow>&& frontendWindow)
386     : InspectorFrontendClientLocal(&inspectedPage.inspectorController(), frontendWindow->document()->page(), makeUnique<InspectorFrontendClientLocal::Settings>())
387     , m_frontendWindow(frontendWindow.copyRef())
388 {
389     ASSERT_ARG(frontendWindow, frontendWindow);
390
391     frontendPage()->inspectorController().setInspectorFrontendClient(this);
392     inspectedPage.inspectorController().connectFrontend(*this);
393 }
394
395 InspectorStubFrontend::~InspectorStubFrontend()
396 {
397     closeWindow();
398 }
399
400 void InspectorStubFrontend::closeWindow()
401 {
402     if (!m_frontendWindow)
403         return;
404
405     frontendPage()->inspectorController().setInspectorFrontendClient(nullptr);
406     inspectedPage()->inspectorController().disconnectFrontend(*this);
407
408     m_frontendWindow->close();
409     m_frontendWindow = nullptr;
410 }
411
412 void InspectorStubFrontend::sendMessageToFrontend(const String& message)
413 {
414     dispatchMessageAsync(message);
415 }
416
417 static bool markerTypeFrom(const String& markerType, DocumentMarker::MarkerType& result)
418 {
419     if (equalLettersIgnoringASCIICase(markerType, "spelling"))
420         result = DocumentMarker::Spelling;
421     else if (equalLettersIgnoringASCIICase(markerType, "grammar"))
422         result = DocumentMarker::Grammar;
423     else if (equalLettersIgnoringASCIICase(markerType, "textmatch"))
424         result = DocumentMarker::TextMatch;
425     else if (equalLettersIgnoringASCIICase(markerType, "replacement"))
426         result = DocumentMarker::Replacement;
427     else if (equalLettersIgnoringASCIICase(markerType, "correctionindicator"))
428         result = DocumentMarker::CorrectionIndicator;
429     else if (equalLettersIgnoringASCIICase(markerType, "rejectedcorrection"))
430         result = DocumentMarker::RejectedCorrection;
431     else if (equalLettersIgnoringASCIICase(markerType, "autocorrected"))
432         result = DocumentMarker::Autocorrected;
433     else if (equalLettersIgnoringASCIICase(markerType, "spellcheckingexemption"))
434         result = DocumentMarker::SpellCheckingExemption;
435     else if (equalLettersIgnoringASCIICase(markerType, "deletedautocorrection"))
436         result = DocumentMarker::DeletedAutocorrection;
437     else if (equalLettersIgnoringASCIICase(markerType, "dictationalternatives"))
438         result = DocumentMarker::DictationAlternatives;
439 #if ENABLE(TELEPHONE_NUMBER_DETECTION)
440     else if (equalLettersIgnoringASCIICase(markerType, "telephonenumber"))
441         result = DocumentMarker::TelephoneNumber;
442 #endif
443     else
444         return false;
445
446     return true;
447 }
448
449 static bool markerTypesFrom(const String& markerType, OptionSet<DocumentMarker::MarkerType>& result)
450 {
451     DocumentMarker::MarkerType singularResult;
452
453     if (markerType.isEmpty() || equalLettersIgnoringASCIICase(markerType, "all"))
454         result = DocumentMarker::allMarkers();
455     else if (markerTypeFrom(markerType, singularResult))
456         result = singularResult;
457     else
458         return false;
459
460     return true;
461 }
462
463 static std::unique_ptr<PrintContext>& printContextForTesting()
464 {
465     static NeverDestroyed<std::unique_ptr<PrintContext>> context;
466     return context;
467 }
468
469 const char* Internals::internalsId = "internals";
470
471 Ref<Internals> Internals::create(Document& document)
472 {
473     return adoptRef(*new Internals(document));
474 }
475
476 Internals::~Internals()
477 {
478 #if ENABLE(MEDIA_STREAM)
479     if (m_trackSource) {
480         m_trackSource->removeObserver(*this);
481         m_trackSource->removeAudioSampleObserver(*this);
482     }
483 #endif
484 }
485
486 void Internals::resetToConsistentState(Page& page)
487 {
488     page.setPageScaleFactor(1, IntPoint(0, 0));
489     page.setPagination(Pagination());
490     page.setPaginationLineGridEnabled(false);
491
492     page.setDefersLoading(false);
493
494     page.mainFrame().setTextZoomFactor(1.0f);
495
496     page.setCompositingPolicyOverride(WebCore::CompositingPolicy::Normal);
497
498     FrameView* mainFrameView = page.mainFrame().view();
499     if (mainFrameView) {
500         page.setHeaderHeight(0);
501         page.setFooterHeight(0);
502         page.setTopContentInset(0);
503         mainFrameView->setUseFixedLayout(false);
504         mainFrameView->setFixedLayoutSize(IntSize());
505         mainFrameView->enableFixedWidthAutoSizeMode(false, { });
506 #if USE(COORDINATED_GRAPHICS)
507         mainFrameView->setFixedVisibleContentRect(IntRect());
508 #endif
509         if (auto* backing = mainFrameView->tiledBacking())
510             backing->setTileSizeUpdateDelayDisabledForTesting(false);
511     }
512
513     WTF::clearDefaultPortForProtocolMapForTesting();
514     overrideUserPreferredLanguages(Vector<String>());
515     WebCore::DeprecatedGlobalSettings::setUsesOverlayScrollbars(false);
516     WebCore::DeprecatedGlobalSettings::setUsesMockScrollAnimator(false);
517 #if ENABLE(VIDEO_TRACK)
518     page.group().captionPreferences().setTestingMode(true);
519     page.group().captionPreferences().setCaptionDisplayMode(CaptionUserPreferences::ForcedOnly);
520     page.group().captionPreferences().setCaptionsStyleSheetOverride(emptyString());
521     page.group().captionPreferences().setTestingMode(false);
522 #endif
523     if (!page.mainFrame().editor().isContinuousSpellCheckingEnabled())
524         page.mainFrame().editor().toggleContinuousSpellChecking();
525     if (page.mainFrame().editor().isOverwriteModeEnabled())
526         page.mainFrame().editor().toggleOverwriteModeEnabled();
527     page.mainFrame().loader().clearTestingOverrides();
528     page.applicationCacheStorage().setDefaultOriginQuota(ApplicationCacheStorage::noQuota());
529 #if ENABLE(VIDEO)
530     PlatformMediaSessionManager::sharedManager().resetRestrictions();
531     PlatformMediaSessionManager::sharedManager().setWillIgnoreSystemInterruptions(true);
532 #endif
533 #if ENABLE(VIDEO) || ENABLE(WEB_AUDIO)
534     PlatformMediaSessionManager::sharedManager().setIsPlayingToAutomotiveHeadUnit(false);
535 #endif
536 #if ENABLE(ACCESSIBILITY)
537     AXObjectCache::setEnhancedUserInterfaceAccessibility(false);
538     AXObjectCache::disableAccessibility();
539 #endif
540
541     MockPageOverlayClient::singleton().uninstallAllOverlays();
542
543 #if ENABLE(CONTENT_FILTERING)
544     MockContentFilterSettings::reset();
545 #endif
546
547 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
548     page.setMockMediaPlaybackTargetPickerEnabled(true);
549     page.setMockMediaPlaybackTargetPickerState(emptyString(), MediaPlaybackTargetContext::Unknown);
550 #endif
551
552     MediaResourceLoader::recordResponsesForTesting();
553
554     page.setShowAllPlugins(false);
555     page.setLowPowerModeEnabledOverrideForTesting(WTF::nullopt);
556
557 #if USE(QUICK_LOOK)
558     MockPreviewLoaderClient::singleton().setPassword("");
559     LegacyPreviewLoader::setClientForTesting(nullptr);
560 #endif
561
562     printContextForTesting() = nullptr;
563
564 #if USE(LIBWEBRTC)
565     auto& rtcProvider = page.libWebRTCProvider();
566     WebCore::useRealRTCPeerConnectionFactory(rtcProvider);
567     rtcProvider.disableNonLocalhostConnections();
568     RuntimeEnabledFeatures::sharedFeatures().setWebRTCH265CodecEnabled(true);
569     page.settings().setWebRTCEncryptionEnabled(true);
570 #endif
571
572     page.setFullscreenAutoHideDuration(0_s);
573     page.setFullscreenInsets({ });
574     page.setFullscreenControlsHidden(false);
575
576     MediaEngineConfigurationFactory::disableMock();
577
578 #if ENABLE(MEDIA_STREAM)
579     RuntimeEnabledFeatures::sharedFeatures().setInterruptAudioOnPageVisibilityChangeEnabled(false);
580     WebCore::MediaRecorder::setCustomPrivateRecorderCreator(nullptr);
581     page.mediaRecorderProvider().setUseGPUProcess(true);
582 #endif
583
584     HTMLCanvasElement::setMaxPixelMemoryForTesting(0); // This means use the default value.
585     DOMWindow::overrideTransientActivationDurationForTesting(WTF::nullopt);
586 }
587
588 Internals::Internals(Document& document)
589     : ContextDestructionObserver(&document)
590 #if ENABLE(MEDIA_STREAM)
591     , m_orientationNotifier(0)
592 #endif
593 {
594 #if ENABLE(VIDEO_TRACK)
595     if (document.page())
596         document.page()->group().captionPreferences().setTestingMode(true);
597 #endif
598
599 #if ENABLE(MEDIA_STREAM)
600     setMediaCaptureRequiresSecureConnection(false);
601 #endif
602
603 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
604     if (document.page())
605         document.page()->setMockMediaPlaybackTargetPickerEnabled(true);
606 #endif
607
608     if (contextDocument() && contextDocument()->frame()) {
609         setAutomaticSpellingCorrectionEnabled(true);
610         setAutomaticQuoteSubstitutionEnabled(false);
611         setAutomaticDashSubstitutionEnabled(false);
612         setAutomaticLinkDetectionEnabled(false);
613         setAutomaticTextReplacementEnabled(true);
614     }
615
616     setConsoleMessageListener(nullptr);
617
618 #if ENABLE(APPLE_PAY)
619     auto* frame = document.frame();
620     if (frame && frame->page() && frame->isMainFrame()) {
621         auto mockPaymentCoordinator = new MockPaymentCoordinator(*frame->page());
622         frame->page()->setPaymentCoordinator(makeUnique<PaymentCoordinator>(*mockPaymentCoordinator));
623     }
624 #endif
625
626 #if PLATFORM(COCOA) &&  ENABLE(WEB_AUDIO)
627     AudioDestinationCocoa::createOverride = nullptr;
628 #endif
629 }
630
631 Document* Internals::contextDocument() const
632 {
633     return downcast<Document>(scriptExecutionContext());
634 }
635
636 Frame* Internals::frame() const
637 {
638     if (!contextDocument())
639         return nullptr;
640     return contextDocument()->frame();
641 }
642
643 InternalSettings* Internals::settings() const
644 {
645     Document* document = contextDocument();
646     if (!document)
647         return nullptr;
648     Page* page = document->page();
649     if (!page)
650         return nullptr;
651     return InternalSettings::from(page);
652 }
653
654 unsigned Internals::inflightBeaconsCount() const
655 {
656     auto* document = contextDocument();
657     if (!document)
658         return 0;
659
660     auto* window = document->domWindow();
661     if (!window)
662         return 0;
663
664     auto* navigator = window->optionalNavigator();
665     if (!navigator)
666         return 0;
667
668     return NavigatorBeacon::from(*navigator)->inflightBeaconsCount();
669 }
670
671 unsigned Internals::workerThreadCount() const
672 {
673     return WorkerThread::workerThreadCount();
674 }
675
676 ExceptionOr<bool> Internals::areSVGAnimationsPaused() const
677 {
678     auto* document = contextDocument();
679     if (!document)
680         return Exception { InvalidAccessError, "No context document"_s };
681
682     if (!document->svgExtensions())
683         return Exception { NotFoundError, "No SVG animations"_s };
684
685     return document->accessSVGExtensions().areAnimationsPaused();
686 }
687
688 ExceptionOr<double> Internals::svgAnimationsInterval(SVGSVGElement& element) const
689 {
690     auto* document = contextDocument();
691     if (!document)
692         return 0;
693
694     if (!document->svgExtensions())
695         return 0;
696
697     if (document->accessSVGExtensions().areAnimationsPaused())
698         return 0;
699
700     return element.timeContainer().animationFrameDelay().value();
701 }
702
703 String Internals::address(Node& node)
704 {
705     return makeString("0x", hex(reinterpret_cast<uintptr_t>(&node)));
706 }
707
708 bool Internals::nodeNeedsStyleRecalc(Node& node)
709 {
710     return node.needsStyleRecalc();
711 }
712
713 static String styleValidityToToString(Style::Validity validity)
714 {
715     switch (validity) {
716     case Style::Validity::Valid:
717         return "NoStyleChange";
718     case Style::Validity::ElementInvalid:
719         return "InlineStyleChange";
720     case Style::Validity::SubtreeInvalid:
721         return "FullStyleChange";
722     case Style::Validity::SubtreeAndRenderersInvalid:
723         return "ReconstructRenderTree";
724     }
725     ASSERT_NOT_REACHED();
726     return "";
727 }
728
729 String Internals::styleChangeType(Node& node)
730 {
731     node.document().styleScope().flushPendingUpdate();
732
733     return styleValidityToToString(node.styleValidity());
734 }
735
736 String Internals::description(JSC::JSValue value)
737 {
738     return toString(value);
739 }
740
741 bool Internals::isPreloaded(const String& url)
742 {
743     Document* document = contextDocument();
744     return document->cachedResourceLoader().isPreloaded(url);
745 }
746
747 bool Internals::isLoadingFromMemoryCache(const String& url)
748 {
749     if (!contextDocument() || !contextDocument()->page())
750         return false;
751
752     ResourceRequest request(contextDocument()->completeURL(url));
753     request.setDomainForCachePartition(contextDocument()->domainForCachePartition());
754
755     CachedResource* resource = MemoryCache::singleton().resourceForRequest(request, contextDocument()->page()->sessionID());
756     return resource && resource->status() == CachedResource::Cached;
757 }
758
759 static String responseSourceToString(const ResourceResponse& response)
760 {
761     if (response.isNull())
762         return "Null response";
763     switch (response.source()) {
764     case ResourceResponse::Source::Unknown:
765         return "Unknown";
766     case ResourceResponse::Source::Network:
767         return "Network";
768     case ResourceResponse::Source::ServiceWorker:
769         return "Service worker";
770     case ResourceResponse::Source::DiskCache:
771         return "Disk cache";
772     case ResourceResponse::Source::DiskCacheAfterValidation:
773         return "Disk cache after validation";
774     case ResourceResponse::Source::MemoryCache:
775         return "Memory cache";
776     case ResourceResponse::Source::MemoryCacheAfterValidation:
777         return "Memory cache after validation";
778     case ResourceResponse::Source::ApplicationCache:
779         return "Application cache";
780     case ResourceResponse::Source::DOMCache:
781         return "DOM cache";
782     case ResourceResponse::Source::InspectorOverride:
783         return "Inspector override";
784     }
785     ASSERT_NOT_REACHED();
786     return "Error";
787 }
788
789 String Internals::xhrResponseSource(XMLHttpRequest& request)
790 {
791     return responseSourceToString(request.resourceResponse());
792 }
793
794 String Internals::fetchResponseSource(FetchResponse& response)
795 {
796     return responseSourceToString(response.resourceResponse());
797 }
798
799 bool Internals::isSharingStyleSheetContents(HTMLLinkElement& a, HTMLLinkElement& b)
800 {
801     if (!a.sheet() || !b.sheet())
802         return false;
803     return &a.sheet()->contents() == &b.sheet()->contents();
804 }
805
806 bool Internals::isStyleSheetLoadingSubresources(HTMLLinkElement& link)
807 {
808     return link.sheet() && link.sheet()->contents().isLoadingSubresources();
809 }
810
811 static ResourceRequestCachePolicy toResourceRequestCachePolicy(Internals::CachePolicy policy)
812 {
813     switch (policy) {
814     case Internals::CachePolicy::UseProtocolCachePolicy:
815         return ResourceRequestCachePolicy::UseProtocolCachePolicy;
816     case Internals::CachePolicy::ReloadIgnoringCacheData:
817         return ResourceRequestCachePolicy::ReloadIgnoringCacheData;
818     case Internals::CachePolicy::ReturnCacheDataElseLoad:
819         return ResourceRequestCachePolicy::ReturnCacheDataElseLoad;
820     case Internals::CachePolicy::ReturnCacheDataDontLoad:
821         return ResourceRequestCachePolicy::ReturnCacheDataDontLoad;
822     }
823     ASSERT_NOT_REACHED();
824     return ResourceRequestCachePolicy::UseProtocolCachePolicy;
825 }
826
827 void Internals::setOverrideCachePolicy(CachePolicy policy)
828 {
829     frame()->loader().setOverrideCachePolicyForTesting(toResourceRequestCachePolicy(policy));
830 }
831
832 ExceptionOr<void> Internals::setCanShowModalDialogOverride(bool allow)
833 {
834     if (!contextDocument() || !contextDocument()->domWindow())
835         return Exception { InvalidAccessError };
836
837     contextDocument()->domWindow()->setCanShowModalDialogOverride(allow);
838     return { };
839 }
840
841 static ResourceLoadPriority toResourceLoadPriority(Internals::ResourceLoadPriority priority)
842 {
843     switch (priority) {
844     case Internals::ResourceLoadPriority::ResourceLoadPriorityVeryLow:
845         return ResourceLoadPriority::VeryLow;
846     case Internals::ResourceLoadPriority::ResourceLoadPriorityLow:
847         return ResourceLoadPriority::Low;
848     case Internals::ResourceLoadPriority::ResourceLoadPriorityMedium:
849         return ResourceLoadPriority::Medium;
850     case Internals::ResourceLoadPriority::ResourceLoadPriorityHigh:
851         return ResourceLoadPriority::High;
852     case Internals::ResourceLoadPriority::ResourceLoadPriorityVeryHigh:
853         return ResourceLoadPriority::VeryHigh;
854     }
855     ASSERT_NOT_REACHED();
856     return ResourceLoadPriority::Low;
857 }
858
859 void Internals::setOverrideResourceLoadPriority(ResourceLoadPriority priority)
860 {
861     frame()->loader().setOverrideResourceLoadPriorityForTesting(toResourceLoadPriority(priority));
862 }
863
864 void Internals::setStrictRawResourceValidationPolicyDisabled(bool disabled)
865 {
866     frame()->loader().setStrictRawResourceValidationPolicyDisabledForTesting(disabled);
867 }
868
869 void Internals::clearMemoryCache()
870 {
871     MemoryCache::singleton().evictResources();
872 }
873
874 void Internals::pruneMemoryCacheToSize(unsigned size)
875 {
876     MemoryCache::singleton().pruneDeadResourcesToSize(size);
877     MemoryCache::singleton().pruneLiveResourcesToSize(size, true);
878 }
879     
880 void Internals::destroyDecodedDataForAllImages()
881 {
882     MemoryCache::singleton().destroyDecodedDataForAllImages();
883 }
884
885 unsigned Internals::memoryCacheSize() const
886 {
887     return MemoryCache::singleton().size();
888 }
889
890 static Image* imageFromImageElement(HTMLImageElement& element)
891 {
892     auto* cachedImage = element.cachedImage();
893     return cachedImage ? cachedImage->image() : nullptr;
894 }
895
896 static BitmapImage* bitmapImageFromImageElement(HTMLImageElement& element)
897 {
898     auto* image = imageFromImageElement(element);
899     return image && is<BitmapImage>(image) ? &downcast<BitmapImage>(*image) : nullptr;
900 }
901
902 #if USE(CG)
903 static PDFDocumentImage* pdfDocumentImageFromImageElement(HTMLImageElement& element)
904 {
905     auto* image = imageFromImageElement(element);
906     return image && is<PDFDocumentImage>(image) ? &downcast<PDFDocumentImage>(*image) : nullptr;
907 }
908 #endif
909
910 unsigned Internals::imageFrameIndex(HTMLImageElement& element)
911 {
912     auto* bitmapImage = bitmapImageFromImageElement(element);
913     return bitmapImage ? bitmapImage->currentFrame() : 0;
914 }
915
916 unsigned Internals::imageFrameCount(HTMLImageElement& element)
917 {
918     auto* bitmapImage = bitmapImageFromImageElement(element);
919     return bitmapImage ? bitmapImage->frameCount() : 0;
920 }
921
922 float Internals::imageFrameDurationAtIndex(HTMLImageElement& element, unsigned index)
923 {
924     auto* bitmapImage = bitmapImageFromImageElement(element);
925     return bitmapImage ? bitmapImage->frameDurationAtIndex(index).value() : 0;
926 }
927     
928 void Internals::setImageFrameDecodingDuration(HTMLImageElement& element, float duration)
929 {
930     if (auto* bitmapImage = bitmapImageFromImageElement(element))
931         bitmapImage->setFrameDecodingDurationForTesting(Seconds { duration });
932 }
933
934 void Internals::resetImageAnimation(HTMLImageElement& element)
935 {
936     if (auto* image = imageFromImageElement(element))
937         image->resetAnimation();
938 }
939
940 bool Internals::isImageAnimating(HTMLImageElement& element)
941 {
942     auto* image = imageFromImageElement(element);
943     return image && (image->isAnimating() || image->animationPending());
944 }
945
946 unsigned Internals::imagePendingDecodePromisesCountForTesting(HTMLImageElement& element)
947 {
948     return element.pendingDecodePromisesCountForTesting();
949 }
950
951 void Internals::setClearDecoderAfterAsyncFrameRequestForTesting(HTMLImageElement& element, bool enabled)
952 {
953     if (auto* bitmapImage = bitmapImageFromImageElement(element))
954         bitmapImage->setClearDecoderAfterAsyncFrameRequestForTesting(enabled);
955 }
956
957 unsigned Internals::imageDecodeCount(HTMLImageElement& element)
958 {
959     auto* bitmapImage = bitmapImageFromImageElement(element);
960     return bitmapImage ? bitmapImage->decodeCountForTesting() : 0;
961 }
962
963 unsigned Internals::pdfDocumentCachingCount(HTMLImageElement& element)
964 {
965 #if USE(CG)
966     auto* pdfDocumentImage = pdfDocumentImageFromImageElement(element);
967     return pdfDocumentImage ? pdfDocumentImage->cachingCountForTesting() : 0;
968 #else
969     UNUSED_PARAM(element);
970     return 0;
971 #endif
972 }
973
974 void Internals::setLargeImageAsyncDecodingEnabledForTesting(HTMLImageElement& element, bool enabled)
975 {
976     if (auto* bitmapImage = bitmapImageFromImageElement(element))
977         bitmapImage->setLargeImageAsyncDecodingEnabledForTesting(enabled);
978 }
979     
980 void Internals::setForceUpdateImageDataEnabledForTesting(HTMLImageElement& element, bool enabled)
981 {
982     if (auto* cachedImage = element.cachedImage())
983         cachedImage->setForceUpdateImageDataEnabledForTesting(enabled);
984 }
985
986 void Internals::setGridMaxTracksLimit(unsigned maxTrackLimit)
987 {
988     GridPosition::setMaxPositionForTesting(maxTrackLimit);
989 }
990
991 void Internals::clearBackForwardCache()
992 {
993     BackForwardCache::singleton().pruneToSizeNow(0, PruningReason::None);
994 }
995
996 unsigned Internals::backForwardCacheSize() const
997 {
998     return BackForwardCache::singleton().pageCount();
999 }
1000
1001 void Internals::preventDocumentFromEnteringBackForwardCache()
1002 {
1003     if (auto* document = contextDocument())
1004         document->preventEnteringBackForwardCacheForTesting();
1005 }
1006
1007 void Internals::disableTileSizeUpdateDelay()
1008 {
1009     Document* document = contextDocument();
1010     if (!document || !document->frame())
1011         return;
1012
1013     auto* view = document->frame()->view();
1014     if (!view)
1015         return;
1016
1017     if (auto* backing = view->tiledBacking())
1018         backing->setTileSizeUpdateDelayDisabledForTesting(true);
1019 }
1020
1021 void Internals::setSpeculativeTilingDelayDisabledForTesting(bool disabled)
1022 {
1023     Document* document = contextDocument();
1024     if (!document || !document->frame())
1025         return;
1026
1027     if (auto* frameView = document->frame()->view())
1028         frameView->setSpeculativeTilingDelayDisabledForTesting(disabled);
1029 }
1030
1031
1032 Node* Internals::treeScopeRootNode(Node& node)
1033 {
1034     return &node.treeScope().rootNode();
1035 }
1036
1037 Node* Internals::parentTreeScope(Node& node)
1038 {
1039     const TreeScope* parentTreeScope = node.treeScope().parentTreeScope();
1040     return parentTreeScope ? &parentTreeScope->rootNode() : nullptr;
1041 }
1042
1043 ExceptionOr<unsigned> Internals::lastSpatialNavigationCandidateCount() const
1044 {
1045     if (!contextDocument() || !contextDocument()->page())
1046         return Exception { InvalidAccessError };
1047
1048     return contextDocument()->page()->lastSpatialNavigationCandidateCount();
1049 }
1050
1051 bool Internals::animationWithIdExists(const String& id) const
1052 {
1053     for (auto* animation : WebAnimation::instances()) {
1054         if (animation->id() == id)
1055             return true;
1056     }
1057     return false;
1058 }
1059
1060 unsigned Internals::numberOfActiveAnimations() const
1061 {
1062     if (RuntimeEnabledFeatures::sharedFeatures().webAnimationsCSSIntegrationEnabled())
1063         return frame()->document()->timeline().numberOfActiveAnimationsForTesting();
1064     return frame()->legacyAnimation().numberOfActiveAnimations(frame()->document());
1065 }
1066
1067 ExceptionOr<bool> Internals::animationsAreSuspended() const
1068 {
1069     Document* document = contextDocument();
1070     if (!document || !document->frame())
1071         return Exception { InvalidAccessError };
1072
1073     if (RuntimeEnabledFeatures::sharedFeatures().webAnimationsCSSIntegrationEnabled())
1074         return document->timeline().animationsAreSuspended();
1075     return document->frame()->legacyAnimation().animationsAreSuspendedForDocument(document);
1076 }
1077
1078 double Internals::animationsInterval() const
1079 {
1080     Document* document = contextDocument();
1081     if (!document)
1082         return INFINITY;
1083
1084     if (RuntimeEnabledFeatures::sharedFeatures().webAnimationsCSSIntegrationEnabled()) {
1085         if (auto timeline = document->existingTimeline())
1086             return timeline->animationInterval().seconds();
1087         return INFINITY;
1088     }
1089
1090     if (!document->frame())
1091         return INFINITY;
1092     return document->frame()->legacyAnimation().animationInterval().value();
1093 }
1094
1095 ExceptionOr<void> Internals::suspendAnimations() const
1096 {
1097     Document* document = contextDocument();
1098     if (!document || !document->frame())
1099         return Exception { InvalidAccessError };
1100
1101     if (RuntimeEnabledFeatures::sharedFeatures().webAnimationsCSSIntegrationEnabled()) {
1102         document->timeline().suspendAnimations();
1103         for (Frame* frame = document->frame(); frame; frame = frame->tree().traverseNext()) {
1104             if (Document* document = frame->document())
1105                 document->timeline().suspendAnimations();
1106         }
1107     } else {
1108         document->frame()->legacyAnimation().suspendAnimationsForDocument(document);
1109
1110         for (Frame* frame = document->frame(); frame; frame = frame->tree().traverseNext()) {
1111             if (Document* document = frame->document())
1112                 frame->legacyAnimation().suspendAnimationsForDocument(document);
1113         }
1114     }
1115
1116     return { };
1117 }
1118
1119 ExceptionOr<void> Internals::resumeAnimations() const
1120 {
1121     Document* document = contextDocument();
1122     if (!document || !document->frame())
1123         return Exception { InvalidAccessError };
1124
1125     if (RuntimeEnabledFeatures::sharedFeatures().webAnimationsCSSIntegrationEnabled()) {
1126         document->timeline().resumeAnimations();
1127         for (Frame* frame = document->frame(); frame; frame = frame->tree().traverseNext()) {
1128             if (Document* document = frame->document())
1129                 document->timeline().resumeAnimations();
1130         }
1131     } else {
1132         document->frame()->legacyAnimation().resumeAnimationsForDocument(document);
1133
1134         for (Frame* frame = document->frame(); frame; frame = frame->tree().traverseNext()) {
1135             if (Document* document = frame->document())
1136                 frame->legacyAnimation().resumeAnimationsForDocument(document);
1137         }
1138     }
1139
1140     return { };
1141 }
1142
1143 ExceptionOr<bool> Internals::pauseAnimationAtTimeOnElement(const String& animationName, double pauseTime, Element& element)
1144 {
1145     if (pauseTime < 0)
1146         return Exception { InvalidAccessError };
1147     return frame()->legacyAnimation().pauseAnimationAtTime(element, AtomString(animationName), pauseTime);
1148 }
1149
1150 ExceptionOr<bool> Internals::pauseAnimationAtTimeOnPseudoElement(const String& animationName, double pauseTime, Element& element, const String& pseudoId)
1151 {
1152     if (pauseTime < 0)
1153         return Exception { InvalidAccessError };
1154
1155     if (pseudoId != "before" && pseudoId != "after")
1156         return Exception { InvalidAccessError };
1157
1158     PseudoElement* pseudoElement = pseudoId == "before" ? element.beforePseudoElement() : element.afterPseudoElement();
1159     if (!pseudoElement)
1160         return Exception { InvalidAccessError };
1161
1162     return frame()->legacyAnimation().pauseAnimationAtTime(*pseudoElement, AtomString(animationName), pauseTime);
1163 }
1164
1165 ExceptionOr<bool> Internals::pauseTransitionAtTimeOnElement(const String& propertyName, double pauseTime, Element& element)
1166 {
1167     if (pauseTime < 0)
1168         return Exception { InvalidAccessError };
1169     return frame()->legacyAnimation().pauseTransitionAtTime(element, propertyName, pauseTime);
1170 }
1171
1172 ExceptionOr<bool> Internals::pauseTransitionAtTimeOnPseudoElement(const String& property, double pauseTime, Element& element, const String& pseudoId)
1173 {
1174     if (pauseTime < 0)
1175         return Exception { InvalidAccessError };
1176
1177     if (pseudoId != "before" && pseudoId != "after")
1178         return Exception { InvalidAccessError };
1179
1180     PseudoElement* pseudoElement = pseudoId == "before" ? element.beforePseudoElement() : element.afterPseudoElement();
1181     if (!pseudoElement)
1182         return Exception { InvalidAccessError };
1183
1184     return frame()->legacyAnimation().pauseTransitionAtTime(*pseudoElement, property, pauseTime);
1185 }
1186
1187 Vector<Internals::AcceleratedAnimation> Internals::acceleratedAnimationsForElement(Element& element)
1188 {
1189     if (!RuntimeEnabledFeatures::sharedFeatures().webAnimationsCSSIntegrationEnabled())
1190         return { };
1191
1192     Vector<Internals::AcceleratedAnimation> animations;
1193     for (const auto& animationAsPair : element.document().timeline().acceleratedAnimationsForElement(element))
1194         animations.append({ animationAsPair.first, animationAsPair.second });
1195     return animations;
1196 }
1197
1198 unsigned Internals::numberOfAnimationTimelineInvalidations() const
1199 {
1200     if (RuntimeEnabledFeatures::sharedFeatures().webAnimationsCSSIntegrationEnabled())
1201         return frame()->document()->timeline().numberOfAnimationTimelineInvalidationsForTesting();
1202     return 0;
1203 }
1204
1205 ExceptionOr<RefPtr<Element>> Internals::pseudoElement(Element& element, const String& pseudoId)
1206 {
1207     if (pseudoId != "before" && pseudoId != "after")
1208         return Exception { InvalidAccessError };
1209
1210     return pseudoId == "before" ? element.beforePseudoElement() : element.afterPseudoElement();
1211 }
1212
1213 ExceptionOr<String> Internals::elementRenderTreeAsText(Element& element)
1214 {
1215     element.document().updateStyleIfNeeded();
1216
1217     String representation = externalRepresentation(&element);
1218     if (representation.isEmpty())
1219         return Exception { InvalidAccessError };
1220
1221     return representation;
1222 }
1223
1224 bool Internals::hasPausedImageAnimations(Element& element)
1225 {
1226     return element.renderer() && element.renderer()->hasPausedImageAnimations();
1227 }
1228     
1229 bool Internals::isPaintingFrequently(Element& element)
1230 {
1231     return element.renderer() && element.renderer()->enclosingLayer() && element.renderer()->enclosingLayer()->paintingFrequently();
1232 }
1233
1234 void Internals::incrementFrequentPaintCounter(Element& element)
1235 {
1236     if (element.renderer() && element.renderer()->enclosingLayer())
1237         element.renderer()->enclosingLayer()->simulateFrequentPaint();
1238 }
1239
1240 Ref<CSSComputedStyleDeclaration> Internals::computedStyleIncludingVisitedInfo(Element& element) const
1241 {
1242     bool allowVisitedStyle = true;
1243     return CSSComputedStyleDeclaration::create(element, allowVisitedStyle);
1244 }
1245
1246 Node* Internals::ensureUserAgentShadowRoot(Element& host)
1247 {
1248     return &host.ensureUserAgentShadowRoot();
1249 }
1250
1251 Node* Internals::shadowRoot(Element& host)
1252 {
1253     return host.shadowRoot();
1254 }
1255
1256 ExceptionOr<String> Internals::shadowRootType(const Node& root) const
1257 {
1258     if (!is<ShadowRoot>(root))
1259         return Exception { InvalidAccessError };
1260
1261     switch (downcast<ShadowRoot>(root).mode()) {
1262     case ShadowRootMode::UserAgent:
1263         return "UserAgentShadowRoot"_str;
1264     case ShadowRootMode::Closed:
1265         return "ClosedShadowRoot"_str;
1266     case ShadowRootMode::Open:
1267         return "OpenShadowRoot"_str;
1268     default:
1269         ASSERT_NOT_REACHED();
1270         return "Unknown"_str;
1271     }
1272 }
1273
1274 String Internals::shadowPseudoId(Element& element)
1275 {
1276     return element.shadowPseudoId().string();
1277 }
1278
1279 void Internals::setShadowPseudoId(Element& element, const String& id)
1280 {
1281     return element.setPseudo(id);
1282 }
1283
1284 static unsigned deferredStyleRulesCountForList(const Vector<RefPtr<StyleRuleBase>>& childRules)
1285 {
1286     unsigned count = 0;
1287     for (auto rule : childRules) {
1288         if (is<StyleRule>(rule)) {
1289             auto* cssRule = downcast<StyleRule>(rule.get());
1290             if (!cssRule->propertiesWithoutDeferredParsing())
1291                 count++;
1292             continue;
1293         }
1294
1295         StyleRuleGroup* groupRule = nullptr;
1296         if (is<StyleRuleMedia>(rule))
1297             groupRule = downcast<StyleRuleMedia>(rule.get());
1298         else if (is<StyleRuleSupports>(rule))
1299             groupRule = downcast<StyleRuleSupports>(rule.get());
1300         if (!groupRule)
1301             continue;
1302
1303         auto* groupChildRules = groupRule->childRulesWithoutDeferredParsing();
1304         if (!groupChildRules)
1305             continue;
1306
1307         count += deferredStyleRulesCountForList(*groupChildRules);
1308     }
1309
1310     return count;
1311 }
1312
1313 unsigned Internals::deferredStyleRulesCount(StyleSheet& styleSheet)
1314 {
1315     return deferredStyleRulesCountForList(downcast<CSSStyleSheet>(styleSheet).contents().childRules());
1316 }
1317
1318 static unsigned deferredGroupRulesCountForList(const Vector<RefPtr<StyleRuleBase>>& childRules)
1319 {
1320     unsigned count = 0;
1321     for (auto rule : childRules) {
1322         StyleRuleGroup* groupRule = nullptr;
1323         if (is<StyleRuleMedia>(rule))
1324             groupRule = downcast<StyleRuleMedia>(rule.get());
1325         else if (is<StyleRuleSupports>(rule))
1326             groupRule = downcast<StyleRuleSupports>(rule.get());
1327         if (!groupRule)
1328             continue;
1329
1330         auto* groupChildRules = groupRule->childRulesWithoutDeferredParsing();
1331         if (!groupChildRules)
1332             count++;
1333         else
1334             count += deferredGroupRulesCountForList(*groupChildRules);
1335     }
1336     return count;
1337 }
1338
1339 unsigned Internals::deferredGroupRulesCount(StyleSheet& styleSheet)
1340 {
1341     return deferredGroupRulesCountForList(downcast<CSSStyleSheet>(styleSheet).contents().childRules());
1342 }
1343
1344 static unsigned deferredKeyframesRulesCountForList(const Vector<RefPtr<StyleRuleBase>>& childRules)
1345 {
1346     unsigned count = 0;
1347     for (auto rule : childRules) {
1348         if (is<StyleRuleKeyframes>(rule)) {
1349             auto* cssRule = downcast<StyleRuleKeyframes>(rule.get());
1350             if (!cssRule->keyframesWithoutDeferredParsing())
1351                 count++;
1352             continue;
1353         }
1354
1355         StyleRuleGroup* groupRule = nullptr;
1356         if (is<StyleRuleMedia>(rule))
1357             groupRule = downcast<StyleRuleMedia>(rule.get());
1358         else if (is<StyleRuleSupports>(rule))
1359             groupRule = downcast<StyleRuleSupports>(rule.get());
1360         if (!groupRule)
1361             continue;
1362
1363         auto* groupChildRules = groupRule->childRulesWithoutDeferredParsing();
1364         if (!groupChildRules)
1365             continue;
1366
1367         count += deferredKeyframesRulesCountForList(*groupChildRules);
1368     }
1369
1370     return count;
1371 }
1372
1373 unsigned Internals::deferredKeyframesRulesCount(StyleSheet& styleSheet)
1374 {
1375     StyleSheetContents& contents = downcast<CSSStyleSheet>(styleSheet).contents();
1376     return deferredKeyframesRulesCountForList(contents.childRules());
1377 }
1378
1379 ExceptionOr<bool> Internals::isTimerThrottled(int timeoutId)
1380 {
1381     auto* timer = scriptExecutionContext()->findTimeout(timeoutId);
1382     if (!timer)
1383         return Exception { NotFoundError };
1384
1385     if (timer->intervalClampedToMinimum() > timer->m_originalInterval)
1386         return true;
1387
1388     return !!timer->alignedFireTime(MonotonicTime { });
1389 }
1390
1391 String Internals::requestAnimationFrameThrottlingReasons() const
1392 {
1393     auto* scriptedAnimationController = contextDocument()->scriptedAnimationController();
1394     if (!scriptedAnimationController)
1395         return String();
1396         
1397     TextStream ts;
1398     ts << scriptedAnimationController->throttlingReasons();
1399     return ts.release();
1400 }
1401
1402 double Internals::requestAnimationFrameInterval() const
1403 {
1404     auto* scriptedAnimationController = contextDocument()->scriptedAnimationController();
1405     if (!scriptedAnimationController)
1406         return INFINITY;
1407     return scriptedAnimationController->interval().value();
1408 }
1409
1410 bool Internals::scriptedAnimationsAreSuspended() const
1411 {
1412     Document* document = contextDocument();
1413     if (!document || !document->page())
1414         return true;
1415
1416     return document->page()->scriptedAnimationsSuspended();
1417 }
1418
1419 bool Internals::areTimersThrottled() const
1420 {
1421     return contextDocument()->isTimerThrottlingEnabled();
1422 }
1423
1424 void Internals::setEventThrottlingBehaviorOverride(Optional<EventThrottlingBehavior> value)
1425 {
1426     Document* document = contextDocument();
1427     if (!document || !document->page())
1428         return;
1429
1430     if (!value) {
1431         document->page()->setEventThrottlingBehaviorOverride(WTF::nullopt);
1432         return;
1433     }
1434
1435     switch (value.value()) {
1436     case Internals::EventThrottlingBehavior::Responsive:
1437         document->page()->setEventThrottlingBehaviorOverride(WebCore::EventThrottlingBehavior::Responsive);
1438         break;
1439     case Internals::EventThrottlingBehavior::Unresponsive:
1440         document->page()->setEventThrottlingBehaviorOverride(WebCore::EventThrottlingBehavior::Unresponsive);
1441         break;
1442     }
1443 }
1444
1445 Optional<Internals::EventThrottlingBehavior> Internals::eventThrottlingBehaviorOverride() const
1446 {
1447     Document* document = contextDocument();
1448     if (!document || !document->page())
1449         return WTF::nullopt;
1450
1451     auto behavior = document->page()->eventThrottlingBehaviorOverride();
1452     if (!behavior)
1453         return WTF::nullopt;
1454
1455     switch (behavior.value()) {
1456     case WebCore::EventThrottlingBehavior::Responsive:
1457         return Internals::EventThrottlingBehavior::Responsive;
1458     case WebCore::EventThrottlingBehavior::Unresponsive:
1459         return Internals::EventThrottlingBehavior::Unresponsive;
1460     }
1461
1462     return WTF::nullopt;
1463 }
1464
1465 String Internals::visiblePlaceholder(Element& element)
1466 {
1467     if (is<HTMLTextFormControlElement>(element)) {
1468         const HTMLTextFormControlElement& textFormControlElement = downcast<HTMLTextFormControlElement>(element);
1469         if (!textFormControlElement.isPlaceholderVisible())
1470             return String();
1471         if (HTMLElement* placeholderElement = textFormControlElement.placeholderElement())
1472             return placeholderElement->textContent();
1473     }
1474
1475     return String();
1476 }
1477
1478 void Internals::setCanShowPlaceholder(Element& element, bool canShowPlaceholder)
1479 {
1480     if (is<HTMLTextFormControlElement>(element))
1481         downcast<HTMLTextFormControlElement>(element).setCanShowPlaceholder(canShowPlaceholder);
1482 }
1483
1484 Element* Internals::insertTextPlaceholder(int width, int height)
1485 {
1486     return frame()->editor().insertTextPlaceholder(IntSize { width, height }).get();
1487 }
1488
1489 void Internals::removeTextPlaceholder(Element& element)
1490 {
1491     if (is<TextPlaceholderElement>(element))
1492         frame()->editor().removeTextPlaceholder(downcast<TextPlaceholderElement>(element));
1493 }
1494
1495 void Internals::selectColorInColorChooser(HTMLInputElement& element, const String& colorValue)
1496 {
1497     element.selectColor(colorValue);
1498 }
1499
1500 ExceptionOr<Vector<String>> Internals::formControlStateOfPreviousHistoryItem()
1501 {
1502     HistoryItem* mainItem = frame()->loader().history().previousItem();
1503     if (!mainItem)
1504         return Exception { InvalidAccessError };
1505     String uniqueName = frame()->tree().uniqueName();
1506     if (mainItem->target() != uniqueName && !mainItem->childItemWithTarget(uniqueName))
1507         return Exception { InvalidAccessError };
1508     return Vector<String> { mainItem->target() == uniqueName ? mainItem->documentState() : mainItem->childItemWithTarget(uniqueName)->documentState() };
1509 }
1510
1511 ExceptionOr<void> Internals::setFormControlStateOfPreviousHistoryItem(const Vector<String>& state)
1512 {
1513     HistoryItem* mainItem = frame()->loader().history().previousItem();
1514     if (!mainItem)
1515         return Exception { InvalidAccessError };
1516     String uniqueName = frame()->tree().uniqueName();
1517     if (mainItem->target() == uniqueName)
1518         mainItem->setDocumentState(state);
1519     else if (HistoryItem* subItem = mainItem->childItemWithTarget(uniqueName))
1520         subItem->setDocumentState(state);
1521     else
1522         return Exception { InvalidAccessError };
1523     return { };
1524 }
1525
1526 #if ENABLE(SPEECH_SYNTHESIS)
1527
1528 void Internals::enableMockSpeechSynthesizer()
1529 {
1530     Document* document = contextDocument();
1531     if (!document || !document->domWindow())
1532         return;
1533     SpeechSynthesis* synthesis = DOMWindowSpeechSynthesis::speechSynthesis(*document->domWindow());
1534     if (!synthesis)
1535         return;
1536
1537     synthesis->setPlatformSynthesizer(makeUnique<PlatformSpeechSynthesizerMock>(synthesis));
1538 }
1539
1540 #endif
1541
1542 #if ENABLE(WEB_RTC)
1543
1544 void Internals::emulateRTCPeerConnectionPlatformEvent(RTCPeerConnection& connection, const String& action)
1545 {
1546     if (!LibWebRTCProvider::webRTCAvailable())
1547         return;
1548
1549     connection.emulatePlatformEvent(action);
1550 }
1551
1552 void Internals::useMockRTCPeerConnectionFactory(const String& testCase)
1553 {
1554     if (!LibWebRTCProvider::webRTCAvailable())
1555         return;
1556
1557 #if USE(LIBWEBRTC)
1558     Document* document = contextDocument();
1559     LibWebRTCProvider* provider = (document && document->page()) ? &document->page()->libWebRTCProvider() : nullptr;
1560     WebCore::useMockRTCPeerConnectionFactory(provider, testCase);
1561 #else
1562     UNUSED_PARAM(testCase);
1563 #endif
1564 }
1565
1566 void Internals::setICECandidateFiltering(bool enabled)
1567 {
1568     auto* page = contextDocument()->page();
1569     if (!page)
1570         return;
1571
1572     auto& rtcController = page->rtcController();
1573     if (enabled)
1574         rtcController.enableICECandidateFiltering();
1575     else
1576         rtcController.disableICECandidateFilteringForAllOrigins();
1577 }
1578
1579 void Internals::setEnumeratingAllNetworkInterfacesEnabled(bool enabled)
1580 {
1581 #if USE(LIBWEBRTC)
1582     Document* document = contextDocument();
1583     auto* page = document->page();
1584     if (!page)
1585         return;
1586     auto& rtcProvider = page->libWebRTCProvider();
1587     if (enabled)
1588         rtcProvider.enableEnumeratingAllNetworkInterfaces();
1589     else
1590         rtcProvider.disableEnumeratingAllNetworkInterfaces();
1591 #else
1592     UNUSED_PARAM(enabled);
1593 #endif
1594 }
1595
1596 void Internals::stopPeerConnection(RTCPeerConnection& connection)
1597 {
1598     ActiveDOMObject& object = connection;
1599     object.stop();
1600 }
1601
1602 void Internals::clearPeerConnectionFactory()
1603 {
1604 #if USE(LIBWEBRTC)
1605     if (auto* page = contextDocument()->page())
1606         page->libWebRTCProvider().clearFactory();
1607 #endif
1608 }
1609
1610 void Internals::applyRotationForOutgoingVideoSources(RTCPeerConnection& connection)
1611 {
1612     connection.applyRotationForOutgoingVideoSources();
1613 }
1614
1615 void Internals::setEnableWebRTCEncryption(bool value)
1616 {
1617 #if USE(LIBWEBRTC)
1618     if (auto* page = contextDocument()->page())
1619         page->settings().setWebRTCEncryptionEnabled(value);
1620 #endif
1621 }
1622
1623 void Internals::setUseDTLS10(bool useDTLS10)
1624 {
1625 #if USE(LIBWEBRTC)
1626     auto* document = contextDocument();
1627     if (!document || !document->page())
1628         return;
1629     document->page()->libWebRTCProvider().setUseDTLS10(useDTLS10);
1630 #endif
1631 }
1632
1633 void Internals::setUseGPUProcessForWebRTC(bool useGPUProcess)
1634 {
1635 #if USE(LIBWEBRTC)
1636     auto* document = contextDocument();
1637     if (!document || !document->page())
1638         return;
1639
1640     document->page()->mediaRecorderProvider().setUseGPUProcess(useGPUProcess);
1641 #endif
1642 }
1643 #endif
1644
1645 #if ENABLE(MEDIA_STREAM)
1646 void Internals::setShouldInterruptAudioOnPageVisibilityChange(bool shouldInterrupt)
1647 {
1648     RuntimeEnabledFeatures::sharedFeatures().setInterruptAudioOnPageVisibilityChangeEnabled(shouldInterrupt);
1649 }
1650
1651 void Internals::setMediaCaptureRequiresSecureConnection(bool enabled)
1652 {
1653     Document* document = contextDocument();
1654     if (auto* page = document->page())
1655         page->settings().setMediaCaptureRequiresSecureConnection(enabled);
1656 }
1657
1658 static std::unique_ptr<MediaRecorderPrivate> createRecorderMockSource(MediaStreamPrivate& stream)
1659 {
1660     return std::unique_ptr<MediaRecorderPrivateMock>(new MediaRecorderPrivateMock(stream));
1661 }
1662
1663 void Internals::setCustomPrivateRecorderCreator()
1664 {
1665     WebCore::MediaRecorder::setCustomPrivateRecorderCreator(createRecorderMockSource);
1666 }
1667
1668 #endif
1669
1670 ExceptionOr<Ref<DOMRect>> Internals::absoluteCaretBounds()
1671 {
1672     Document* document = contextDocument();
1673     if (!document || !document->frame())
1674         return Exception { InvalidAccessError };
1675
1676     return DOMRect::create(document->frame()->selection().absoluteCaretBounds());
1677 }
1678     
1679 ExceptionOr<bool> Internals::isCaretBlinkingSuspended()
1680 {
1681     Document* document = contextDocument();
1682     if (!document || !document->frame())
1683         return Exception { InvalidAccessError };
1684     
1685     return document->frame()->selection().isCaretBlinkingSuspended();
1686 }
1687
1688 Ref<DOMRect> Internals::boundingBox(Element& element)
1689 {
1690     element.document().updateLayoutIgnorePendingStylesheets();
1691     auto renderer = element.renderer();
1692     if (!renderer)
1693         return DOMRect::create();
1694     return DOMRect::create(renderer->absoluteBoundingBoxRectIgnoringTransforms());
1695 }
1696
1697 ExceptionOr<Ref<DOMRectList>> Internals::inspectorHighlightRects()
1698 {
1699     Document* document = contextDocument();
1700     if (!document || !document->page())
1701         return Exception { InvalidAccessError };
1702
1703     Highlight highlight;
1704     document->page()->inspectorController().getHighlight(highlight, InspectorOverlay::CoordinateSystem::View);
1705     return DOMRectList::create(highlight.quads);
1706 }
1707
1708 ExceptionOr<unsigned> Internals::markerCountForNode(Node& node, const String& markerType)
1709 {
1710     OptionSet<DocumentMarker::MarkerType> markerTypes;
1711     if (!markerTypesFrom(markerType, markerTypes))
1712         return Exception { SyntaxError };
1713
1714     node.document().frame()->editor().updateEditorUINowIfScheduled();
1715     return node.document().markers().markersFor(node, markerTypes).size();
1716 }
1717
1718 ExceptionOr<RenderedDocumentMarker*> Internals::markerAt(Node& node, const String& markerType, unsigned index)
1719 {
1720     node.document().updateLayoutIgnorePendingStylesheets();
1721
1722     OptionSet<DocumentMarker::MarkerType> markerTypes;
1723     if (!markerTypesFrom(markerType, markerTypes))
1724         return Exception { SyntaxError };
1725
1726     node.document().frame()->editor().updateEditorUINowIfScheduled();
1727
1728     Vector<RenderedDocumentMarker*> markers = node.document().markers().markersFor(node, markerTypes);
1729     if (markers.size() <= index)
1730         return nullptr;
1731     return markers[index];
1732 }
1733
1734 ExceptionOr<RefPtr<Range>> Internals::markerRangeForNode(Node& node, const String& markerType, unsigned index)
1735 {
1736     auto result = markerAt(node, markerType, index);
1737     if (result.hasException())
1738         return result.releaseException();
1739     auto marker = result.releaseReturnValue();
1740     if (!marker)
1741         return nullptr;
1742     return RefPtr<Range> { Range::create(node.document(), &node, marker->startOffset(), &node, marker->endOffset()) };
1743 }
1744
1745 ExceptionOr<String> Internals::markerDescriptionForNode(Node& node, const String& markerType, unsigned index)
1746 {
1747     auto result = markerAt(node, markerType, index);
1748     if (result.hasException())
1749         return result.releaseException();
1750     auto marker = result.releaseReturnValue();
1751     if (!marker)
1752         return String();
1753     return String { marker->description() };
1754 }
1755
1756 ExceptionOr<String> Internals::dumpMarkerRects(const String& markerTypeString)
1757 {
1758     DocumentMarker::MarkerType markerType;
1759     if (!markerTypeFrom(markerTypeString, markerType))
1760         return Exception { SyntaxError };
1761
1762     contextDocument()->markers().updateRectsForInvalidatedMarkersOfType(markerType);
1763     auto rects = contextDocument()->markers().renderedRectsForMarkers(markerType);
1764
1765     // FIXME: Using fixed precision here for width because of test results that contain numbers with specific precision. Would be nice to update the test results and move to default formatting.
1766     StringBuilder rectString;
1767     rectString.appendLiteral("marker rects: ");
1768     for (const auto& rect : rects)
1769         rectString.append('(', rect.x(), ", ", rect.y(), ", ", FormattedNumber::fixedPrecision(rect.width()), ", ", rect.height(), ") ");
1770     return rectString.toString();
1771 }
1772
1773 ExceptionOr<void> Internals::setMarkedTextMatchesAreHighlighted(bool flag)
1774 {
1775     Document* document = contextDocument();
1776     if (!document || !document->frame())
1777         return Exception { InvalidAccessError };
1778     document->frame()->editor().setMarkedTextMatchesAreHighlighted(flag);
1779     return { };
1780 }
1781
1782 void Internals::invalidateFontCache()
1783 {
1784     FontCache::singleton().invalidate();
1785 }
1786
1787 void Internals::setFontSmoothingEnabled(bool enabled)
1788 {
1789     FontCascade::setShouldUseSmoothing(enabled);
1790 }
1791
1792 ExceptionOr<void> Internals::setLowPowerModeEnabled(bool isEnabled)
1793 {
1794     auto* document = contextDocument();
1795     if (!document)
1796         return Exception { InvalidAccessError };
1797     auto* page = document->page();
1798     if (!page)
1799         return Exception { InvalidAccessError };
1800
1801     page->setLowPowerModeEnabledOverrideForTesting(isEnabled);
1802     return { };
1803 }
1804
1805 ExceptionOr<void> Internals::setScrollViewPosition(int x, int y)
1806 {
1807     Document* document = contextDocument();
1808     if (!document || !document->view())
1809         return Exception { InvalidAccessError };
1810
1811     auto& frameView = *document->view();
1812     bool constrainsScrollingToContentEdgeOldValue = frameView.constrainsScrollingToContentEdge();
1813     bool scrollbarsSuppressedOldValue = frameView.scrollbarsSuppressed();
1814
1815     frameView.setConstrainsScrollingToContentEdge(false);
1816     frameView.setScrollbarsSuppressed(false);
1817     frameView.setScrollOffsetFromInternals({ x, y });
1818     frameView.setScrollbarsSuppressed(scrollbarsSuppressedOldValue);
1819     frameView.setConstrainsScrollingToContentEdge(constrainsScrollingToContentEdgeOldValue);
1820
1821     return { };
1822 }
1823
1824 ExceptionOr<void> Internals::unconstrainedScrollTo(Element& element, double x, double y)
1825 {
1826     Document* document = contextDocument();
1827     if (!document || !document->view())
1828         return Exception { InvalidAccessError };
1829
1830     element.scrollTo(ScrollToOptions(x, y), ScrollClamping::Unclamped);
1831
1832     auto& frameView = *document->view();
1833     frameView.setViewportConstrainedObjectsNeedLayout();
1834
1835     return { };
1836 }
1837
1838 ExceptionOr<Ref<DOMRect>> Internals::layoutViewportRect()
1839 {
1840     Document* document = contextDocument();
1841     if (!document || !document->frame())
1842         return Exception { InvalidAccessError };
1843
1844     document->updateLayoutIgnorePendingStylesheets();
1845
1846     auto& frameView = *document->view();
1847     return DOMRect::create(frameView.layoutViewportRect());
1848 }
1849
1850 ExceptionOr<Ref<DOMRect>> Internals::visualViewportRect()
1851 {
1852     Document* document = contextDocument();
1853     if (!document || !document->frame())
1854         return Exception { InvalidAccessError };
1855
1856     document->updateLayoutIgnorePendingStylesheets();
1857
1858     auto& frameView = *document->view();
1859     return DOMRect::create(frameView.visualViewportRect());
1860 }
1861
1862 ExceptionOr<void> Internals::setViewIsTransparent(bool transparent)
1863 {
1864     Document* document = contextDocument();
1865     if (!document || !document->view())
1866         return Exception { InvalidAccessError };
1867     Optional<Color> backgroundColor;
1868     if (transparent)
1869         backgroundColor = Color(Color::transparent);
1870     document->view()->updateBackgroundRecursively(backgroundColor);
1871     return { };
1872 }
1873
1874 ExceptionOr<String> Internals::viewBaseBackgroundColor()
1875 {
1876     Document* document = contextDocument();
1877     if (!document || !document->view())
1878         return Exception { InvalidAccessError };
1879     return document->view()->baseBackgroundColor().cssText();
1880 }
1881
1882 ExceptionOr<void> Internals::setViewBaseBackgroundColor(const String& colorValue)
1883 {
1884     Document* document = contextDocument();
1885     if (!document || !document->view())
1886         return Exception { InvalidAccessError };
1887
1888     if (colorValue == "transparent") {
1889         document->view()->setBaseBackgroundColor(Color::transparent);
1890         return { };
1891     }
1892     if (colorValue == "white") {
1893         document->view()->setBaseBackgroundColor(Color::white);
1894         return { };
1895     }
1896     return Exception { SyntaxError };
1897 }
1898
1899 ExceptionOr<void> Internals::setPagination(const String& mode, int gap, int pageLength)
1900 {
1901     Document* document = contextDocument();
1902     if (!document || !document->page())
1903         return Exception { InvalidAccessError };
1904
1905     Pagination pagination;
1906     if (mode == "Unpaginated")
1907         pagination.mode = Pagination::Unpaginated;
1908     else if (mode == "LeftToRightPaginated")
1909         pagination.mode = Pagination::LeftToRightPaginated;
1910     else if (mode == "RightToLeftPaginated")
1911         pagination.mode = Pagination::RightToLeftPaginated;
1912     else if (mode == "TopToBottomPaginated")
1913         pagination.mode = Pagination::TopToBottomPaginated;
1914     else if (mode == "BottomToTopPaginated")
1915         pagination.mode = Pagination::BottomToTopPaginated;
1916     else
1917         return Exception { SyntaxError };
1918
1919     pagination.gap = gap;
1920     pagination.pageLength = pageLength;
1921     document->page()->setPagination(pagination);
1922
1923     return { };
1924 }
1925
1926 ExceptionOr<void> Internals::setPaginationLineGridEnabled(bool enabled)
1927 {
1928     Document* document = contextDocument();
1929     if (!document || !document->page())
1930         return Exception { InvalidAccessError };
1931     document->page()->setPaginationLineGridEnabled(enabled);
1932     return { };
1933 }
1934
1935 ExceptionOr<String> Internals::configurationForViewport(float devicePixelRatio, int deviceWidth, int deviceHeight, int availableWidth, int availableHeight)
1936 {
1937     Document* document = contextDocument();
1938     if (!document || !document->page())
1939         return Exception { InvalidAccessError };
1940
1941     const int defaultLayoutWidthForNonMobilePages = 980;
1942
1943     ViewportArguments arguments = document->page()->viewportArguments();
1944     ViewportAttributes attributes = computeViewportAttributes(arguments, defaultLayoutWidthForNonMobilePages, deviceWidth, deviceHeight, devicePixelRatio, IntSize(availableWidth, availableHeight));
1945     restrictMinimumScaleFactorToViewportSize(attributes, IntSize(availableWidth, availableHeight), devicePixelRatio);
1946     restrictScaleFactorToInitialScaleIfNotUserScalable(attributes);
1947
1948     // FIXME: Using fixed precision here because of test results that contain numbers with specific precision. Would be nice to update the test results and move to default formatting.
1949     return makeString("viewport size ", FormattedNumber::fixedPrecision(attributes.layoutSize.width()), 'x', FormattedNumber::fixedPrecision(attributes.layoutSize.height()), " scale ", FormattedNumber::fixedPrecision(attributes.initialScale), " with limits [", FormattedNumber::fixedPrecision(attributes.minimumScale), ", ", FormattedNumber::fixedPrecision(attributes.maximumScale), "] and userScalable ", (attributes.userScalable ? "true" : "false"));
1950 }
1951
1952 ExceptionOr<bool> Internals::wasLastChangeUserEdit(Element& textField)
1953 {
1954     if (is<HTMLInputElement>(textField))
1955         return downcast<HTMLInputElement>(textField).lastChangeWasUserEdit();
1956
1957     if (is<HTMLTextAreaElement>(textField))
1958         return downcast<HTMLTextAreaElement>(textField).lastChangeWasUserEdit();
1959
1960     return Exception { InvalidNodeTypeError };
1961 }
1962
1963 bool Internals::elementShouldAutoComplete(HTMLInputElement& element)
1964 {
1965     return element.shouldAutocomplete();
1966 }
1967
1968 void Internals::setAutofilled(HTMLInputElement& element, bool enabled)
1969 {
1970     element.setAutoFilled(enabled);
1971 }
1972
1973 void Internals::setAutoFilledAndViewable(HTMLInputElement& element, bool enabled)
1974 {
1975     element.setAutoFilledAndViewable(enabled);
1976 }
1977
1978 static AutoFillButtonType toAutoFillButtonType(Internals::AutoFillButtonType type)
1979 {
1980     switch (type) {
1981     case Internals::AutoFillButtonType::None:
1982         return AutoFillButtonType::None;
1983     case Internals::AutoFillButtonType::Credentials:
1984         return AutoFillButtonType::Credentials;
1985     case Internals::AutoFillButtonType::Contacts:
1986         return AutoFillButtonType::Contacts;
1987     case Internals::AutoFillButtonType::StrongPassword:
1988         return AutoFillButtonType::StrongPassword;
1989     case Internals::AutoFillButtonType::CreditCard:
1990         return AutoFillButtonType::CreditCard;
1991     }
1992     ASSERT_NOT_REACHED();
1993     return AutoFillButtonType::None;
1994 }
1995
1996 static Internals::AutoFillButtonType toInternalsAutoFillButtonType(AutoFillButtonType type)
1997 {
1998     switch (type) {
1999     case AutoFillButtonType::None:
2000         return Internals::AutoFillButtonType::None;
2001     case AutoFillButtonType::Credentials:
2002         return Internals::AutoFillButtonType::Credentials;
2003     case AutoFillButtonType::Contacts:
2004         return Internals::AutoFillButtonType::Contacts;
2005     case AutoFillButtonType::StrongPassword:
2006         return Internals::AutoFillButtonType::StrongPassword;
2007     case AutoFillButtonType::CreditCard:
2008         return Internals::AutoFillButtonType::CreditCard;
2009     }
2010     ASSERT_NOT_REACHED();
2011     return Internals::AutoFillButtonType::None;
2012 }
2013
2014 void Internals::setShowAutoFillButton(HTMLInputElement& element, AutoFillButtonType type)
2015 {
2016     element.setShowAutoFillButton(toAutoFillButtonType(type));
2017 }
2018
2019 auto Internals::autoFillButtonType(const HTMLInputElement& element) -> AutoFillButtonType
2020 {
2021     return toInternalsAutoFillButtonType(element.autoFillButtonType());
2022 }
2023
2024 auto Internals::lastAutoFillButtonType(const HTMLInputElement& element) -> AutoFillButtonType
2025 {
2026     return toInternalsAutoFillButtonType(element.lastAutoFillButtonType());
2027 }
2028
2029 ExceptionOr<void> Internals::scrollElementToRect(Element& element, int x, int y, int w, int h)
2030 {
2031     FrameView* frameView = element.document().view();
2032     if (!frameView)
2033         return Exception { InvalidAccessError };
2034     frameView->scrollElementToRect(element, { x, y, w, h });
2035     return { };
2036 }
2037
2038 ExceptionOr<String> Internals::autofillFieldName(Element& element)
2039 {
2040     if (!is<HTMLFormControlElement>(element))
2041         return Exception { InvalidNodeTypeError };
2042
2043     return String { downcast<HTMLFormControlElement>(element).autofillData().fieldName };
2044 }
2045
2046 ExceptionOr<void> Internals::invalidateControlTints()
2047 {
2048     Document* document = contextDocument();
2049     if (!document || !document->view())
2050         return Exception { InvalidAccessError };
2051
2052     document->view()->invalidateControlTints();
2053     return { };
2054 }
2055
2056 RefPtr<Range> Internals::rangeFromLocationAndLength(Element& scope, unsigned rangeLocation, unsigned rangeLength)
2057 {
2058     return createLiveRange(resolveCharacterRange(makeRangeSelectingNodeContents(scope), { rangeLocation, rangeLength }));
2059 }
2060
2061 unsigned Internals::locationFromRange(Element& scope, const Range& range)
2062 {
2063     return clampTo<unsigned>(characterRange(makeBoundaryPointBeforeNodeContents(scope), range).location);
2064 }
2065
2066 unsigned Internals::lengthFromRange(Element& scope, const Range& range)
2067 {
2068     return clampTo<unsigned>(characterRange(makeBoundaryPointBeforeNodeContents(scope), range).length);
2069 }
2070
2071 String Internals::rangeAsText(const Range& range)
2072 {
2073     return range.text();
2074 }
2075
2076 String Internals::rangeAsTextUsingBackwardsTextIterator(const Range& range)
2077 {
2078     String result;
2079     for (SimplifiedBackwardsTextIterator backwardsIterator(range); !backwardsIterator.atEnd(); backwardsIterator.advance())
2080         result.insert(backwardsIterator.text().toString(), 0);
2081     return result;
2082 }
2083
2084 Ref<Range> Internals::subrange(Range& range, unsigned rangeLocation, unsigned rangeLength)
2085 {
2086     return createLiveRange(resolveCharacterRange(range, { rangeLocation, rangeLength }));
2087 }
2088
2089 RefPtr<Range> Internals::rangeOfStringNearLocation(const Range& searchRange, const String& text, unsigned targetOffset)
2090 {
2091     return createLiveRange(findClosestPlainText(searchRange, text, { }, targetOffset));
2092 }
2093
2094 #if !PLATFORM(MAC)
2095 ExceptionOr<RefPtr<Range>> Internals::rangeForDictionaryLookupAtLocation(int, int)
2096 {
2097     return Exception { InvalidAccessError };
2098 }
2099 #endif
2100
2101 ExceptionOr<void> Internals::setDelegatesScrolling(bool enabled)
2102 {
2103     Document* document = contextDocument();
2104     // Delegate scrolling is valid only on mainframe's view.
2105     if (!document || !document->view() || !document->page() || &document->page()->mainFrame() != document->frame())
2106         return Exception { InvalidAccessError };
2107
2108     document->view()->setDelegatesScrolling(enabled);
2109     return { };
2110 }
2111
2112 ExceptionOr<uint64_t> Internals::lastSpellCheckRequestSequence()
2113 {
2114     Document* document = contextDocument();
2115     if (!document || !document->frame())
2116         return Exception { InvalidAccessError };
2117
2118     return document->frame()->editor().spellChecker().lastRequestIdentifier().toUInt64();
2119 }
2120
2121 ExceptionOr<uint64_t> Internals::lastSpellCheckProcessedSequence()
2122 {
2123     Document* document = contextDocument();
2124     if (!document || !document->frame())
2125         return Exception { InvalidAccessError };
2126
2127     return document->frame()->editor().spellChecker().lastProcessedIdentifier().toUInt64();
2128 }
2129
2130 Vector<String> Internals::userPreferredLanguages() const
2131 {
2132     return WTF::userPreferredLanguages();
2133 }
2134
2135 void Internals::setUserPreferredLanguages(const Vector<String>& languages)
2136 {
2137     overrideUserPreferredLanguages(languages);
2138 }
2139
2140 Vector<String> Internals::userPreferredAudioCharacteristics() const
2141 {
2142     Document* document = contextDocument();
2143     if (!document || !document->page())
2144         return Vector<String>();
2145 #if ENABLE(VIDEO_TRACK)
2146     return document->page()->group().captionPreferences().preferredAudioCharacteristics();
2147 #else
2148     return Vector<String>();
2149 #endif
2150 }
2151
2152 void Internals::setUserPreferredAudioCharacteristic(const String& characteristic)
2153 {
2154     Document* document = contextDocument();
2155     if (!document || !document->page())
2156         return;
2157 #if ENABLE(VIDEO_TRACK)
2158     document->page()->group().captionPreferences().setPreferredAudioCharacteristic(characteristic);
2159 #else
2160     UNUSED_PARAM(characteristic);
2161 #endif
2162 }
2163
2164 ExceptionOr<unsigned> Internals::wheelEventHandlerCount()
2165 {
2166     Document* document = contextDocument();
2167     if (!document)
2168         return Exception { InvalidAccessError };
2169
2170     return document->wheelEventHandlerCount();
2171 }
2172
2173 ExceptionOr<unsigned> Internals::touchEventHandlerCount()
2174 {
2175     Document* document = contextDocument();
2176     if (!document)
2177         return Exception { InvalidAccessError };
2178
2179     return document->touchEventHandlerCount();
2180 }
2181
2182 ExceptionOr<Ref<DOMRectList>> Internals::touchEventRectsForEvent(const String& eventName)
2183 {
2184     Document* document = contextDocument();
2185     if (!document || !document->page())
2186         return Exception { InvalidAccessError };
2187
2188     return document->page()->touchEventRectsForEventForTesting(eventName);
2189 }
2190
2191 ExceptionOr<Ref<DOMRectList>> Internals::passiveTouchEventListenerRects()
2192 {
2193     Document* document = contextDocument();
2194     if (!document || !document->page())
2195         return Exception { InvalidAccessError };
2196
2197     return document->page()->passiveTouchEventListenerRectsForTesting();
2198 }
2199
2200 // FIXME: Remove the document argument. It is almost always the same as
2201 // contextDocument(), with the exception of a few tests that pass a
2202 // different document, and could just make the call through another Internals
2203 // instance instead.
2204 ExceptionOr<RefPtr<NodeList>> Internals::nodesFromRect(Document& document, int centerX, int centerY, unsigned topPadding, unsigned rightPadding, unsigned bottomPadding, unsigned leftPadding, bool ignoreClipping, bool allowUserAgentShadowContent, bool allowChildFrameContent) const
2205 {
2206     if (!document.frame() || !document.frame()->view())
2207         return Exception { InvalidAccessError };
2208
2209     Frame* frame = document.frame();
2210     FrameView* frameView = document.view();
2211     RenderView* renderView = document.renderView();
2212     if (!renderView)
2213         return nullptr;
2214
2215     document.updateLayoutIgnorePendingStylesheets();
2216
2217     float zoomFactor = frame->pageZoomFactor();
2218     LayoutPoint point(centerX * zoomFactor + frameView->scrollX(), centerY * zoomFactor + frameView->scrollY());
2219
2220     OptionSet<HitTestRequest::RequestType> hitType { HitTestRequest::ReadOnly, HitTestRequest::Active, HitTestRequest::CollectMultipleElements };
2221     if (ignoreClipping)
2222         hitType.add(HitTestRequest::IgnoreClipping);
2223     if (!allowUserAgentShadowContent)
2224         hitType.add(HitTestRequest::DisallowUserAgentShadowContent);
2225     if (allowChildFrameContent)
2226         hitType.add(HitTestRequest::AllowChildFrameContent);
2227
2228     HitTestRequest request(hitType);
2229
2230     // When ignoreClipping is false, this method returns null for coordinates outside of the viewport.
2231     if (!request.ignoreClipping() && !frameView->visibleContentRect().intersects(HitTestLocation::rectForPoint(point, topPadding, rightPadding, bottomPadding, leftPadding)))
2232         return nullptr;
2233
2234     HitTestResult result(point, topPadding, rightPadding, bottomPadding, leftPadding);
2235     document.hitTest(request, result);
2236     auto matches = WTF::map(result.listBasedTestResult(), [](const auto& node) { return node.copyRef(); });
2237     return RefPtr<NodeList> { StaticNodeList::create(WTFMove(matches)) };
2238 }
2239
2240 class GetCallerCodeBlockFunctor {
2241 public:
2242     GetCallerCodeBlockFunctor()
2243         : m_iterations(0)
2244         , m_codeBlock(0)
2245     {
2246     }
2247
2248     StackVisitor::Status operator()(StackVisitor& visitor) const
2249     {
2250         ++m_iterations;
2251         if (m_iterations < 2)
2252             return StackVisitor::Continue;
2253
2254         m_codeBlock = visitor->codeBlock();
2255         return StackVisitor::Done;
2256     }
2257
2258     CodeBlock* codeBlock() const { return m_codeBlock; }
2259
2260 private:
2261     mutable int m_iterations;
2262     mutable CodeBlock* m_codeBlock;
2263 };
2264
2265 String Internals::parserMetaData(JSC::JSValue code)
2266 {
2267     JSC::VM& vm = contextDocument()->vm();
2268     JSC::CallFrame* callFrame = vm.topCallFrame;
2269     JSC::JSGlobalObject* globalObject = callFrame->lexicalGlobalObject(vm);
2270     ScriptExecutable* executable;
2271
2272     if (!code || code.isNull() || code.isUndefined()) {
2273         GetCallerCodeBlockFunctor iter;
2274         callFrame->iterate(vm, iter);
2275         CodeBlock* codeBlock = iter.codeBlock();
2276         executable = codeBlock->ownerExecutable();
2277     } else if (code.isCallable(vm)) {
2278         JSFunction* funcObj = JSC::jsCast<JSFunction*>(code.toObject(globalObject));
2279         executable = funcObj->jsExecutable();
2280     } else
2281         return String();
2282
2283     unsigned startLine = executable->firstLine();
2284     unsigned startColumn = executable->startColumn();
2285     unsigned endLine = executable->lastLine();
2286     unsigned endColumn = executable->endColumn();
2287
2288     StringBuilder result;
2289
2290     if (executable->isFunctionExecutable()) {
2291         FunctionExecutable* funcExecutable = reinterpret_cast<FunctionExecutable*>(executable);
2292         String inferredName = funcExecutable->ecmaName().string();
2293         result.appendLiteral("function \"");
2294         result.append(inferredName);
2295         result.append('"');
2296     } else if (executable->isEvalExecutable())
2297         result.appendLiteral("eval");
2298     else if (executable->isModuleProgramExecutable())
2299         result.appendLiteral("module");
2300     else if (executable->isProgramExecutable())
2301         result.appendLiteral("program");
2302     else
2303         ASSERT_NOT_REACHED();
2304
2305     result.appendLiteral(" { ");
2306     result.appendNumber(startLine);
2307     result.append(':');
2308     result.appendNumber(startColumn);
2309     result.appendLiteral(" - ");
2310     result.appendNumber(endLine);
2311     result.append(':');
2312     result.appendNumber(endColumn);
2313     result.appendLiteral(" }");
2314
2315     return result.toString();
2316 }
2317
2318 void Internals::updateEditorUINowIfScheduled()
2319 {
2320     if (Document* document = contextDocument()) {
2321         if (Frame* frame = document->frame())
2322             frame->editor().updateEditorUINowIfScheduled();
2323     }
2324 }
2325
2326 bool Internals::hasSpellingMarker(int from, int length)
2327 {
2328     Document* document = contextDocument();
2329     if (!document || !document->frame())
2330         return false;
2331
2332     updateEditorUINowIfScheduled();
2333
2334     return document->frame()->editor().selectionStartHasMarkerFor(DocumentMarker::Spelling, from, length);
2335 }
2336
2337 bool Internals::hasAutocorrectedMarker(int from, int length)
2338 {
2339     Document* document = contextDocument();
2340     if (!document || !document->frame())
2341         return false;
2342
2343     updateEditorUINowIfScheduled();
2344
2345     return document->frame()->editor().selectionStartHasMarkerFor(DocumentMarker::Autocorrected, from, length);
2346 }
2347
2348 void Internals::setContinuousSpellCheckingEnabled(bool enabled)
2349 {
2350     if (!contextDocument() || !contextDocument()->frame())
2351         return;
2352
2353     if (enabled != contextDocument()->frame()->editor().isContinuousSpellCheckingEnabled())
2354         contextDocument()->frame()->editor().toggleContinuousSpellChecking();
2355 }
2356
2357 void Internals::setAutomaticQuoteSubstitutionEnabled(bool enabled)
2358 {
2359     if (!contextDocument() || !contextDocument()->frame())
2360         return;
2361
2362 #if USE(AUTOMATIC_TEXT_REPLACEMENT)
2363     if (enabled != contextDocument()->frame()->editor().isAutomaticQuoteSubstitutionEnabled())
2364         contextDocument()->frame()->editor().toggleAutomaticQuoteSubstitution();
2365 #else
2366     UNUSED_PARAM(enabled);
2367 #endif
2368 }
2369
2370 void Internals::setAutomaticLinkDetectionEnabled(bool enabled)
2371 {
2372     if (!contextDocument() || !contextDocument()->frame())
2373         return;
2374
2375 #if USE(AUTOMATIC_TEXT_REPLACEMENT)
2376     if (enabled != contextDocument()->frame()->editor().isAutomaticLinkDetectionEnabled())
2377         contextDocument()->frame()->editor().toggleAutomaticLinkDetection();
2378 #else
2379     UNUSED_PARAM(enabled);
2380 #endif
2381 }
2382
2383 bool Internals::testProcessIncomingSyncMessagesWhenWaitingForSyncReply()
2384 {
2385     ASSERT(contextDocument());
2386     ASSERT(contextDocument()->page());
2387     return contextDocument()->page()->chrome().client().testProcessIncomingSyncMessagesWhenWaitingForSyncReply();
2388 }
2389
2390 void Internals::setAutomaticDashSubstitutionEnabled(bool enabled)
2391 {
2392     if (!contextDocument() || !contextDocument()->frame())
2393         return;
2394
2395 #if USE(AUTOMATIC_TEXT_REPLACEMENT)
2396     if (enabled != contextDocument()->frame()->editor().isAutomaticDashSubstitutionEnabled())
2397         contextDocument()->frame()->editor().toggleAutomaticDashSubstitution();
2398 #else
2399     UNUSED_PARAM(enabled);
2400 #endif
2401 }
2402
2403 void Internals::setAutomaticTextReplacementEnabled(bool enabled)
2404 {
2405     if (!contextDocument() || !contextDocument()->frame())
2406         return;
2407
2408 #if USE(AUTOMATIC_TEXT_REPLACEMENT)
2409     if (enabled != contextDocument()->frame()->editor().isAutomaticTextReplacementEnabled())
2410         contextDocument()->frame()->editor().toggleAutomaticTextReplacement();
2411 #else
2412     UNUSED_PARAM(enabled);
2413 #endif
2414 }
2415
2416 void Internals::setAutomaticSpellingCorrectionEnabled(bool enabled)
2417 {
2418     if (!contextDocument() || !contextDocument()->frame())
2419         return;
2420
2421 #if USE(AUTOMATIC_TEXT_REPLACEMENT)
2422     if (enabled != contextDocument()->frame()->editor().isAutomaticSpellingCorrectionEnabled())
2423         contextDocument()->frame()->editor().toggleAutomaticSpellingCorrection();
2424 #else
2425     UNUSED_PARAM(enabled);
2426 #endif
2427 }
2428
2429 void Internals::handleAcceptedCandidate(const String& candidate, unsigned location, unsigned length)
2430 {
2431     if (!contextDocument() || !contextDocument()->frame())
2432         return;
2433
2434     TextCheckingResult result;
2435     result.type = TextCheckingType::None;
2436     result.range = { location, length };
2437     result.replacement = candidate;
2438     contextDocument()->frame()->editor().handleAcceptedCandidate(result);
2439 }
2440
2441 void Internals::changeSelectionListType()
2442 {
2443     if (auto frame = makeRefPtr(this->frame()))
2444         frame->editor().changeSelectionListType();
2445 }
2446
2447 bool Internals::isOverwriteModeEnabled()
2448 {
2449     Document* document = contextDocument();
2450     if (!document || !document->frame())
2451         return false;
2452
2453     return document->frame()->editor().isOverwriteModeEnabled();
2454 }
2455
2456 void Internals::toggleOverwriteModeEnabled()
2457 {
2458     Document* document = contextDocument();
2459     if (!document || !document->frame())
2460         return;
2461
2462     document->frame()->editor().toggleOverwriteModeEnabled();
2463 }
2464
2465 static ExceptionOr<FindOptions> parseFindOptions(const Vector<String>& optionList)
2466 {
2467     const struct {
2468         const char* name;
2469         FindOptionFlag value;
2470     } flagList[] = {
2471         {"CaseInsensitive", CaseInsensitive},
2472         {"AtWordStarts", AtWordStarts},
2473         {"TreatMedialCapitalAsWordStart", TreatMedialCapitalAsWordStart},
2474         {"Backwards", Backwards},
2475         {"WrapAround", WrapAround},
2476         {"StartInSelection", StartInSelection},
2477         {"DoNotRevealSelection", DoNotRevealSelection},
2478         {"AtWordEnds", AtWordEnds},
2479         {"DoNotTraverseFlatTree", DoNotTraverseFlatTree},
2480     };
2481     FindOptions result;
2482     for (auto& option : optionList) {
2483         bool found = false;
2484         for (auto& flag : flagList) {
2485             if (flag.name == option) {
2486                 result.add(flag.value);
2487                 found = true;
2488                 break;
2489             }
2490         }
2491         if (!found)
2492             return Exception { SyntaxError };
2493     }
2494     return result;
2495 }
2496
2497 ExceptionOr<RefPtr<Range>> Internals::rangeOfString(const String& text, RefPtr<Range>&& referenceRange, const Vector<String>& findOptions)
2498 {
2499     Document* document = contextDocument();
2500     if (!document || !document->frame())
2501         return Exception { InvalidAccessError };
2502
2503     auto parsedOptions = parseFindOptions(findOptions);
2504     if (parsedOptions.hasException())
2505         return parsedOptions.releaseException();
2506
2507     return document->frame()->editor().rangeOfString(text, referenceRange.get(), parsedOptions.releaseReturnValue());
2508 }
2509
2510 ExceptionOr<unsigned> Internals::countMatchesForText(const String& text, const Vector<String>& findOptions, const String& markMatches)
2511 {
2512     Document* document = contextDocument();
2513     if (!document || !document->frame())
2514         return Exception { InvalidAccessError };
2515
2516     auto parsedOptions = parseFindOptions(findOptions);
2517     if (parsedOptions.hasException())
2518         return parsedOptions.releaseException();
2519
2520     bool mark = markMatches == "mark";
2521     return document->frame()->editor().countMatchesForText(text, nullptr, parsedOptions.releaseReturnValue(), 1000, mark, nullptr);
2522 }
2523
2524 ExceptionOr<unsigned> Internals::countFindMatches(const String& text, const Vector<String>& findOptions)
2525 {
2526     Document* document = contextDocument();
2527     if (!document || !document->page())
2528         return Exception { InvalidAccessError };
2529
2530     auto parsedOptions = parseFindOptions(findOptions);
2531     if (parsedOptions.hasException())
2532         return parsedOptions.releaseException();
2533
2534     return document->page()->countFindMatches(text, parsedOptions.releaseReturnValue(), 1000);
2535 }
2536
2537 #if ENABLE(INDEXED_DATABASE)
2538 unsigned Internals::numberOfIDBTransactions() const
2539 {
2540     return IDBTransaction::numberOfIDBTransactions;
2541 }
2542 #endif
2543
2544 unsigned Internals::numberOfLiveNodes() const
2545 {
2546     unsigned nodeCount = 0;
2547     for (auto* document : Document::allDocuments())
2548         nodeCount += document->referencingNodeCount();
2549     return nodeCount;
2550 }
2551
2552 unsigned Internals::numberOfLiveDocuments() const
2553 {
2554     return Document::allDocuments().size();
2555 }
2556
2557 unsigned Internals::referencingNodeCount(const Document& document) const
2558 {
2559     return document.referencingNodeCount();
2560 }
2561
2562 #if ENABLE(INTERSECTION_OBSERVER)
2563 unsigned Internals::numberOfIntersectionObservers(const Document& document) const
2564 {
2565     return document.numberOfIntersectionObservers();
2566 }
2567 #endif
2568
2569 uint64_t Internals::documentIdentifier(const Document& document) const
2570 {
2571     return document.identifier().toUInt64();
2572 }
2573
2574 bool Internals::isDocumentAlive(uint64_t documentIdentifier) const
2575 {
2576     return Document::allDocumentsMap().contains(makeObjectIdentifier<DocumentIdentifierType>(documentIdentifier));
2577 }
2578
2579 uint64_t Internals::storageAreaMapCount() const
2580 {
2581     auto* page = contextDocument() ? contextDocument()->page() : nullptr;
2582     if (!page)
2583         return 0;
2584
2585     return page->storageNamespaceProvider().localStorageNamespace(page->sessionID()).storageAreaMapCountForTesting();
2586 }
2587
2588 uint64_t Internals::elementIdentifier(Element& element) const
2589 {
2590     return element.document().identifierForElement(element).toUInt64();
2591 }
2592
2593 uint64_t Internals::frameIdentifier(const Document& document) const
2594 {
2595     if (auto* page = document.page())
2596         return page->mainFrame().loader().frameID().valueOr(FrameIdentifier { }).toUInt64();
2597     return 0;
2598 }
2599
2600 uint64_t Internals::pageIdentifier(const Document& document) const
2601 {
2602     return document.pageID().valueOr(PageIdentifier { }).toUInt64();
2603 }
2604
2605 bool Internals::isAnyWorkletGlobalScopeAlive() const
2606 {
2607 #if ENABLE(CSS_PAINTING_API)
2608     return !WorkletGlobalScope::allWorkletGlobalScopesSet().isEmpty();
2609 #else
2610     return false;
2611 #endif
2612 }
2613
2614 String Internals::serviceWorkerClientIdentifier(const Document& document) const
2615 {
2616 #if ENABLE(SERVICE_WORKER)
2617     return ServiceWorkerClientIdentifier { ServiceWorkerProvider::singleton().serviceWorkerConnection().serverConnectionIdentifier(), document.identifier() }.toString();
2618 #else
2619     UNUSED_PARAM(document);
2620     return String();
2621 #endif
2622 }
2623
2624 RefPtr<WindowProxy> Internals::openDummyInspectorFrontend(const String& url)
2625 {
2626     auto* inspectedPage = contextDocument()->frame()->page();
2627     auto* window = inspectedPage->mainFrame().document()->domWindow();
2628     auto frontendWindowProxy = window->open(*window, *window, url, "", "").releaseReturnValue();
2629     m_inspectorFrontend = makeUnique<InspectorStubFrontend>(*inspectedPage, downcast<DOMWindow>(frontendWindowProxy->window()));
2630     return frontendWindowProxy;
2631 }
2632
2633 void Internals::closeDummyInspectorFrontend()
2634 {
2635     m_inspectorFrontend = nullptr;
2636 }
2637
2638 ExceptionOr<void> Internals::setInspectorIsUnderTest(bool isUnderTest)
2639 {
2640     Page* page = contextDocument()->frame()->page();
2641     if (!page)
2642         return Exception { InvalidAccessError };
2643
2644     page->inspectorController().setIsUnderTest(isUnderTest);
2645     return { };
2646 }
2647
2648 bool Internals::hasGrammarMarker(int from, int length)
2649 {
2650     Document* document = contextDocument();
2651     if (!document || !document->frame())
2652         return false;
2653
2654     return document->frame()->editor().selectionStartHasMarkerFor(DocumentMarker::Grammar, from, length);
2655 }
2656
2657 unsigned Internals::numberOfScrollableAreas()
2658 {
2659     Document* document = contextDocument();
2660     if (!document || !document->frame())
2661         return 0;
2662
2663     unsigned count = 0;
2664     Frame* frame = document->frame();
2665     if (frame->view()->scrollableAreas())
2666         count += frame->view()->scrollableAreas()->size();
2667
2668     for (Frame* child = frame->tree().firstChild(); child; child = child->tree().nextSibling()) {
2669         if (child->view() && child->view()->scrollableAreas())
2670             count += child->view()->scrollableAreas()->size();
2671     }
2672
2673     return count;
2674 }
2675
2676 ExceptionOr<bool> Internals::isPageBoxVisible(int pageNumber)
2677 {
2678     Document* document = contextDocument();
2679     if (!document)
2680         return Exception { InvalidAccessError };
2681
2682     return document->isPageBoxVisible(pageNumber);
2683 }
2684
2685 static LayerTreeFlags toLayerTreeFlags(unsigned short flags)
2686 {
2687     LayerTreeFlags layerTreeFlags = 0;
2688     if (flags & Internals::LAYER_TREE_INCLUDES_VISIBLE_RECTS)
2689         layerTreeFlags |= LayerTreeFlagsIncludeVisibleRects;
2690     if (flags & Internals::LAYER_TREE_INCLUDES_TILE_CACHES)
2691         layerTreeFlags |= LayerTreeFlagsIncludeTileCaches;
2692     if (flags & Internals::LAYER_TREE_INCLUDES_REPAINT_RECTS)
2693         layerTreeFlags |= LayerTreeFlagsIncludeRepaintRects;
2694     if (flags & Internals::LAYER_TREE_INCLUDES_PAINTING_PHASES)
2695         layerTreeFlags |= LayerTreeFlagsIncludePaintingPhases;
2696     if (flags & Internals::LAYER_TREE_INCLUDES_CONTENT_LAYERS)
2697         layerTreeFlags |= LayerTreeFlagsIncludeContentLayers;
2698     if (flags & Internals::LAYER_TREE_INCLUDES_ACCELERATES_DRAWING)
2699         layerTreeFlags |= LayerTreeFlagsIncludeAcceleratesDrawing;
2700     if (flags & Internals::LAYER_TREE_INCLUDES_CLIPPING)
2701         layerTreeFlags |= LayerTreeFlagsIncludeClipping;
2702     if (flags & Internals::LAYER_TREE_INCLUDES_BACKING_STORE_ATTACHED)
2703         layerTreeFlags |= LayerTreeFlagsIncludeBackingStoreAttached;
2704     if (flags & Internals::LAYER_TREE_INCLUDES_ROOT_LAYER_PROPERTIES)
2705         layerTreeFlags |= LayerTreeFlagsIncludeRootLayerProperties;
2706     if (flags & Internals::LAYER_TREE_INCLUDES_EVENT_REGION)
2707         layerTreeFlags |= LayerTreeFlagsIncludeEventRegion;
2708     if (flags & Internals::LAYER_TREE_INCLUDES_DEEP_COLOR)
2709         layerTreeFlags |= LayerTreeFlagsIncludeDeepColor;
2710
2711     return layerTreeFlags;
2712 }
2713
2714 // FIXME: Remove the document argument. It is almost always the same as
2715 // contextDocument(), with the exception of a few tests that pass a
2716 // different document, and could just make the call through another Internals
2717 // instance instead.
2718 ExceptionOr<String> Internals::layerTreeAsText(Document& document, unsigned short flags) const
2719 {
2720     if (!document.frame())
2721         return Exception { InvalidAccessError };
2722
2723     document.updateLayoutIgnorePendingStylesheets();
2724     return document.frame()->layerTreeAsText(toLayerTreeFlags(flags));
2725 }
2726
2727 ExceptionOr<uint64_t> Internals::layerIDForElement(Element& element)
2728 {
2729     Document* document = contextDocument();
2730     if (!document || !document->frame())
2731         return Exception { InvalidAccessError };
2732
2733     element.document().updateLayoutIgnorePendingStylesheets();
2734
2735     if (!element.renderer() || !element.renderer()->hasLayer())
2736         return Exception { NotFoundError };
2737
2738     auto& layerModelObject = downcast<RenderLayerModelObject>(*element.renderer());
2739     if (!layerModelObject.layer()->isComposited())
2740         return Exception { NotFoundError };
2741
2742     auto* backing = layerModelObject.layer()->backing();
2743     return backing->graphicsLayer()->primaryLayerID();
2744 }
2745
2746 ExceptionOr<String> Internals::repaintRectsAsText() const
2747 {
2748     Document* document = contextDocument();
2749     if (!document || !document->frame())
2750         return Exception { InvalidAccessError };
2751
2752     return document->frame()->trackedRepaintRectsAsText();
2753 }
2754
2755 ExceptionOr<ScrollableArea*> Internals::scrollableAreaForNode(Node* node) const
2756 {
2757     if (!node)
2758         node = contextDocument();
2759
2760     if (!node)
2761         return Exception { InvalidAccessError };
2762
2763     auto nodeRef = makeRef(*node);
2764     nodeRef->document().updateLayoutIgnorePendingStylesheets();
2765
2766     ScrollableArea* scrollableArea = nullptr;
2767     if (is<Document>(nodeRef)) {
2768         auto* frameView = downcast<Document>(nodeRef.get()).view();
2769         if (!frameView)
2770             return Exception { InvalidAccessError };
2771
2772         scrollableArea = frameView;
2773     } else if (is<Element>(nodeRef)) {
2774         auto& element = downcast<Element>(nodeRef.get());
2775         if (!element.renderBox())
2776             return Exception { InvalidAccessError };
2777
2778         scrollableArea = element.renderBox()->layer();
2779     } else
2780         return Exception { InvalidNodeTypeError };
2781
2782     if (!scrollableArea)
2783         return Exception { InvalidNodeTypeError };
2784
2785     return scrollableArea;
2786 }
2787
2788 ExceptionOr<String> Internals::scrollbarOverlayStyle(Node* node) const
2789 {
2790     auto areaOrException = scrollableAreaForNode(node);
2791     if (areaOrException.hasException())
2792         return areaOrException.releaseException();
2793
2794     auto* scrollableArea = areaOrException.releaseReturnValue();
2795     switch (scrollableArea->scrollbarOverlayStyle()) {
2796     case ScrollbarOverlayStyleDefault:
2797         return "default"_str;
2798     case ScrollbarOverlayStyleDark:
2799         return "dark"_str;
2800     case ScrollbarOverlayStyleLight:
2801         return "light"_str;
2802     }
2803
2804     ASSERT_NOT_REACHED();
2805     return "unknown"_str;
2806 }
2807
2808 ExceptionOr<bool> Internals::scrollbarUsingDarkAppearance(Node* node) const
2809 {
2810     auto areaOrException = scrollableAreaForNode(node);
2811     if (areaOrException.hasException())
2812         return areaOrException.releaseException();
2813
2814     auto* scrollableArea = areaOrException.releaseReturnValue();
2815     return scrollableArea->useDarkAppearance();
2816 }
2817
2818 ExceptionOr<String> Internals::horizontalScrollbarState(Node* node) const
2819 {
2820     auto areaOrException = scrollableAreaForNode(node);
2821     if (areaOrException.hasException())
2822         return areaOrException.releaseException();
2823
2824     auto* scrollableArea = areaOrException.releaseReturnValue();
2825     return scrollableArea->horizontalScrollbarStateForTesting();
2826 }
2827
2828 ExceptionOr<String> Internals::verticalScrollbarState(Node* node) const
2829 {
2830     auto areaOrException = scrollableAreaForNode(node);
2831     if (areaOrException.hasException())
2832         return areaOrException.releaseException();
2833
2834     auto* scrollableArea = areaOrException.releaseReturnValue();
2835     return scrollableArea->verticalScrollbarStateForTesting();
2836 }
2837
2838 ExceptionOr<String> Internals::scrollingStateTreeAsText() const
2839 {
2840     Document* document = contextDocument();
2841     if (!document || !document->frame())
2842         return Exception { InvalidAccessError };
2843
2844     document->updateLayoutIgnorePendingStylesheets();
2845
2846     Page* page = document->page();
2847     if (!page)
2848         return String();
2849
2850     return page->scrollingStateTreeAsText();
2851 }
2852
2853 ExceptionOr<String> Internals::scrollingTreeAsText() const
2854 {
2855     Document* document = contextDocument();
2856     if (!document || !document->frame())
2857         return Exception { InvalidAccessError };
2858
2859     document->updateLayoutIgnorePendingStylesheets();
2860
2861     auto page = document->page();
2862     if (!page)
2863         return String();
2864
2865     auto scrollingCoordinator = page->scrollingCoordinator();
2866     if (!scrollingCoordinator)
2867         return String();
2868
2869     scrollingCoordinator->commitTreeStateIfNeeded();
2870     return scrollingCoordinator->scrollingTreeAsText();
2871 }
2872
2873 ExceptionOr<String> Internals::mainThreadScrollingReasons() const
2874 {
2875     Document* document = contextDocument();
2876     if (!document || !document->frame())
2877         return Exception { InvalidAccessError };
2878
2879     Page* page = document->page();
2880     if (!page)
2881         return String();
2882
2883     return page->synchronousScrollingReasonsAsText();
2884 }
2885
2886 ExceptionOr<Ref<DOMRectList>> Internals::nonFastScrollableRects() const
2887 {
2888     Document* document = contextDocument();
2889     if (!document || !document->frame())
2890         return Exception { InvalidAccessError };
2891
2892     Page* page = document->page();
2893     if (!page)
2894         return DOMRectList::create();
2895
2896     return page->nonFastScrollableRectsForTesting();
2897 }
2898
2899 ExceptionOr<void> Internals::setElementUsesDisplayListDrawing(Element& element, bool usesDisplayListDrawing)
2900 {
2901     Document* document = contextDocument();
2902     if (!document || !document->renderView())
2903         return Exception { InvalidAccessError };
2904
2905     element.document().updateLayoutIgnorePendingStylesheets();
2906
2907     if (!element.renderer())
2908         return Exception { InvalidAccessError };
2909
2910     if (is<HTMLCanvasElement>(element)) {
2911         downcast<HTMLCanvasElement>(element).setUsesDisplayListDrawing(usesDisplayListDrawing);
2912         return { };
2913     }
2914
2915     if (!element.renderer()->hasLayer())
2916         return Exception { InvalidAccessError };
2917
2918     RenderLayer* layer = downcast<RenderLayerModelObject>(element.renderer())->layer();
2919     if (!layer->isComposited())
2920         return Exception { InvalidAccessError };
2921
2922     layer->backing()->setUsesDisplayListDrawing(usesDisplayListDrawing);
2923     return { };
2924 }
2925
2926 ExceptionOr<void> Internals::setElementTracksDisplayListReplay(Element& element, bool isTrackingReplay)
2927 {
2928     Document* document = contextDocument();
2929     if (!document || !document->renderView())
2930         return Exception { InvalidAccessError };
2931
2932     element.document().updateLayoutIgnorePendingStylesheets();
2933
2934     if (!element.renderer())
2935         return Exception { InvalidAccessError };
2936
2937     if (is<HTMLCanvasElement>(element)) {
2938         downcast<HTMLCanvasElement>(element).setTracksDisplayListReplay(isTrackingReplay);
2939         return { };
2940     }
2941
2942     if (!element.renderer()->hasLayer())
2943         return Exception { InvalidAccessError };
2944
2945     RenderLayer* layer = downcast<RenderLayerModelObject>(element.renderer())->layer();
2946     if (!layer->isComposited())
2947         return Exception { InvalidAccessError };
2948
2949     layer->backing()->setIsTrackingDisplayListReplay(isTrackingReplay);
2950     return { };
2951 }
2952
2953 ExceptionOr<String> Internals::displayListForElement(Element& element, unsigned short flags)
2954 {
2955     Document* document = contextDocument();
2956     if (!document || !document->renderView())
2957         return Exception { InvalidAccessError };
2958
2959     element.document().updateLayoutIgnorePendingStylesheets();
2960
2961     if (!element.renderer())
2962         return Exception { InvalidAccessError };
2963
2964     DisplayList::AsTextFlags displayListFlags = 0;
2965     if (flags & DISPLAY_LIST_INCLUDES_PLATFORM_OPERATIONS)
2966         displayListFlags |= DisplayList::AsTextFlag::IncludesPlatformOperations;
2967
2968     if (is<HTMLCanvasElement>(element))
2969         return downcast<HTMLCanvasElement>(element).displayListAsText(displayListFlags);
2970
2971     if (!element.renderer()->hasLayer())
2972         return Exception { InvalidAccessError };
2973
2974     RenderLayer* layer = downcast<RenderLayerModelObject>(element.renderer())->layer();
2975     if (!layer->isComposited())
2976         return Exception { InvalidAccessError };
2977
2978     return layer->backing()->displayListAsText(displayListFlags);
2979 }
2980
2981 ExceptionOr<String> Internals::replayDisplayListForElement(Element& element, unsigned short flags)
2982 {
2983     Document* document = contextDocument();
2984     if (!document || !document->renderView())
2985         return Exception { InvalidAccessError };
2986
2987     element.document().updateLayoutIgnorePendingStylesheets();
2988
2989     if (!element.renderer())
2990         return Exception { InvalidAccessError };
2991
2992     DisplayList::AsTextFlags displayListFlags = 0;
2993     if (flags & DISPLAY_LIST_INCLUDES_PLATFORM_OPERATIONS)
2994         displayListFlags |= DisplayList::AsTextFlag::IncludesPlatformOperations;
2995
2996     if (is<HTMLCanvasElement>(element))
2997         return downcast<HTMLCanvasElement>(element).replayDisplayListAsText(displayListFlags);
2998
2999     if (!element.renderer()->hasLayer())
3000         return Exception { InvalidAccessError };
3001
3002     RenderLayer* layer = downcast<RenderLayerModelObject>(element.renderer())->layer();
3003     if (!layer->isComposited())
3004         return Exception { InvalidAccessError };
3005
3006     return layer->backing()->replayDisplayListAsText(displayListFlags);
3007 }
3008
3009 ExceptionOr<void> Internals::garbageCollectDocumentResources() const
3010 {
3011     Document* document = contextDocument();
3012     if (!document)
3013         return Exception { InvalidAccessError };
3014     document->cachedResourceLoader().garbageCollectDocumentResources();
3015     return { };
3016 }
3017
3018 bool Internals::isUnderMemoryPressure()
3019 {
3020     return MemoryPressureHandler::singleton().isUnderMemoryPressure();
3021 }
3022
3023 void Internals::beginSimulatedMemoryPressure()
3024 {
3025     MemoryPressureHandler::singleton().beginSimulatedMemoryPressure();
3026 }
3027
3028 void Internals::endSimulatedMemoryPressure()
3029 {
3030     MemoryPressureHandler::singleton().endSimulatedMemoryPressure();
3031 }
3032
3033 ExceptionOr<void> Internals::insertAuthorCSS(const String& css) const
3034 {
3035     Document* document = contextDocument();
3036     if (!document)
3037         return Exception { InvalidAccessError };
3038
3039     auto parsedSheet = StyleSheetContents::create(*document);
3040     parsedSheet.get().setIsUserStyleSheet(false);
3041     parsedSheet.get().parseString(css);
3042     document->extensionStyleSheets().addAuthorStyleSheetForTesting(WTFMove(parsedSheet));
3043     return { };
3044 }
3045
3046 ExceptionOr<void> Internals::insertUserCSS(const String& css) const
3047 {
3048     Document* document = contextDocument();
3049     if (!document)
3050         return Exception { InvalidAccessError };
3051
3052     auto parsedSheet = StyleSheetContents::create(*document);
3053     parsedSheet.get().setIsUserStyleSheet(true);
3054     parsedSheet.get().parseString(css);
3055     document->extensionStyleSheets().addUserStyleSheet(WTFMove(parsedSheet));
3056     return { };
3057 }
3058
3059 String Internals::counterValue(Element& element)
3060 {
3061     return counterValueForElement(&element);
3062 }
3063
3064 int Internals::pageNumber(Element& element, float pageWidth, float pageHeight)
3065 {
3066     return PrintContext::pageNumberForElement(&element, { pageWidth, pageHeight });
3067 }
3068
3069 Vector<String> Internals::shortcutIconURLs() const
3070 {
3071     if (!frame())
3072         return { };
3073     
3074     auto* documentLoader = frame()->loader().documentLoader();
3075     if (!documentLoader)
3076         return { };
3077
3078     Vector<String> result;
3079     for (auto& linkIcon : documentLoader->linkIcons())
3080         result.append(linkIcon.url.string());
3081     
3082     return result;
3083 }
3084
3085 int Internals::numberOfPages(float pageWidth, float pageHeight)
3086 {
3087     if (!frame())
3088         return -1;
3089
3090     return PrintContext::numberOfPages(*frame(), FloatSize(pageWidth, pageHeight));
3091 }
3092
3093 ExceptionOr<String> Internals::pageProperty(const String& propertyName, int pageNumber) const
3094 {
3095     if (!frame())
3096         return Exception { InvalidAccessError };
3097
3098     return PrintContext::pageProperty(frame(), propertyName.utf8().data(), pageNumber);
3099 }
3100
3101 ExceptionOr<String> Internals::pageSizeAndMarginsInPixels(int pageNumber, int width, int height, int marginTop, int marginRight, int marginBottom, int marginLeft) const
3102 {
3103     if (!frame())
3104         return Exception { InvalidAccessError };
3105
3106     return PrintContext::pageSizeAndMarginsInPixels(frame(), pageNumber, width, height, marginTop, marginRight, marginBottom, marginLeft);
3107 }
3108
3109 ExceptionOr<float> Internals::pageScaleFactor() const
3110 {
3111     Document* document = contextDocument();
3112     if (!document || !document->page())
3113         return Exception { InvalidAccessError };
3114
3115     return document->page()->pageScaleFactor();
3116 }
3117
3118 ExceptionOr<void> Internals::setPageScaleFactor(float scaleFactor, int x, int y)
3119 {
3120     Document* document = contextDocument();
3121     if (!document || !document->page())
3122         return Exception { InvalidAccessError };
3123
3124     document->page()->setPageScaleFactor(scaleFactor, IntPoint(x, y));
3125     return { };
3126 }
3127
3128 ExceptionOr<void> Internals::setPageZoomFactor(float zoomFactor)
3129 {
3130     Document* document = contextDocument();
3131     if (!document || !document->frame())
3132         return Exception { InvalidAccessError };
3133
3134     document->frame()->setPageZoomFactor(zoomFactor);
3135     return { };
3136 }
3137
3138 ExceptionOr<void> Internals::setTextZoomFactor(float zoomFactor)
3139 {
3140     Document* document = contextDocument();
3141     if (!document || !document->frame())
3142         return Exception { InvalidAccessError };
3143
3144     document->frame()->setTextZoomFactor(zoomFactor);
3145     return { };
3146 }
3147
3148 ExceptionOr<void> Internals::setUseFixedLayout(bool useFixedLayout)
3149 {
3150     Document* document = contextDocument();
3151     if (!document || !document->view())
3152         return Exception { InvalidAccessError };
3153
3154     document->view()->setUseFixedLayout(useFixedLayout);
3155     return { };
3156 }
3157
3158 ExceptionOr<void> Internals::setFixedLayoutSize(int width, int height)
3159 {
3160     Document* document = contextDocument();
3161     if (!document || !document->view())
3162         return Exception { InvalidAccessError };
3163
3164     document->view()->setFixedLayoutSize(IntSize(width, height));
3165     return { };
3166 }
3167
3168 ExceptionOr<void> Internals::setViewExposedRect(float x, float y, float width, float height)
3169 {
3170     Document* document = contextDocument();
3171     if (!document || !document->view())
3172         return Exception { InvalidAccessError };
3173
3174     document->view()->setViewExposedRect(FloatRect(x, y, width, height));
3175     return { };
3176 }
3177
3178 void Internals::setPrinting(int width, int height)
3179 {
3180     printContextForTesting() = makeUnique<PrintContext>(frame());
3181     printContextForTesting()->begin(width, height);
3182 }
3183
3184 void Internals::setHeaderHeight(float height)
3185 {
3186     Document* document = contextDocument();
3187     if (!document || !document->view())
3188         return;
3189
3190     document->page()->setHeaderHeight(height);
3191 }
3192
3193 void Internals::setFooterHeight(float height)
3194 {
3195     Document* document = contextDocument();
3196     if (!document || !document->view())
3197         return;
3198
3199     document->page()->setFooterHeight(height);
3200 }
3201
3202 void Internals::setTopContentInset(float contentInset)
3203 {
3204     Document* document = contextDocument();
3205     if (!document || !document->page())
3206         return;
3207
3208     document->page()->setTopContentInset(contentInset);
3209 }
3210
3211 #if ENABLE(FULLSCREEN_API)
3212
3213 void Internals::webkitWillEnterFullScreenForElement(Element& element)
3214 {
3215     Document* document = contextDocument();
3216     if (!document)
3217         return;
3218     document->fullscreenManager().willEnterFullscreen(element);
3219 }
3220
3221 void Internals::webkitDidEnterFullScreenForElement(Element&)
3222 {
3223     Document* document = contextDocument();
3224     if (!document)
3225         return;
3226     document->fullscreenManager().didEnterFullscreen();
3227 }
3228
3229 void Internals::webkitWillExitFullScreenForElement(Element&)
3230 {
3231     Document* document = contextDocument();
3232     if (!document)
3233         return;
3234     document->fullscreenManager().willExitFullscreen();
3235 }
3236
3237 void Internals::webkitDidExitFullScreenForElement(Element&)
3238 {
3239     Document* document = contextDocument();
3240     if (!document)
3241         return;
3242     document->fullscreenManager().didExitFullscreen();
3243 }
3244
3245 bool Internals::isAnimatingFullScreen() const
3246 {
3247     Document* document = contextDocument();
3248     if (!document)
3249         return false;
3250     return document->fullscreenManager().isAnimatingFullscreen();
3251 }
3252
3253 #endif
3254
3255 void Internals::setFullscreenInsets(FullscreenInsets insets)
3256 {
3257     Page* page = contextDocument()->frame()->page();
3258     ASSERT(page);
3259
3260     page->setFullscreenInsets(FloatBoxExtent(insets.top, insets.right, insets.bottom, insets.left));
3261 }
3262
3263 void Internals::setFullscreenAutoHideDuration(double duration)
3264 {
3265     Page* page = contextDocument()->frame()->page();
3266     ASSERT(page);
3267
3268     page->setFullscreenAutoHideDuration(Seconds(duration));
3269 }
3270
3271 void Internals::setFullscreenControlsHidden(bool hidden)
3272 {
3273     Page* page = contextDocument()->frame()->page();
3274     ASSERT(page);
3275
3276     page->setFullscreenControlsHidden(hidden);
3277 }
3278
3279 #if ENABLE(VIDEO_PRESENTATION_MODE)
3280 void Internals::setMockVideoPresentationModeEnabled(bool enabled)
3281 {
3282     Document* document = contextDocument();
3283     if (!document || !document->page())
3284         return;
3285
3286     document->page()->chrome().client().setMockVideoPresentationModeEnabled(enabled);
3287 }
3288 #endif
3289
3290 void Internals::setApplicationCacheOriginQuota(unsigned long long quota)
3291 {
3292     Document* document = contextDocument();
3293     if (!document || !document->page())
3294         return;
3295     document->page()->applicationCacheStorage().storeUpdatedQuotaForOrigin(&document->securityOrigin(), quota);
3296 }
3297
3298 void Internals::registerURLSchemeAsBypassingContentSecurityPolicy(const String& scheme)
3299 {
3300     LegacySchemeRegistry::registerURLSchemeAsBypassingContentSecurityPolicy(scheme);
3301 }
3302
3303 void Internals::removeURLSchemeRegisteredAsBypassingContentSecurityPolicy(const String& scheme)
3304 {
3305     LegacySchemeRegistry::removeURLSchemeRegisteredAsBypassingContentSecurityPolicy(scheme);
3306 }
3307
3308 void Internals::registerDefaultPortForProtocol(unsigned short port, const String& protocol)
3309 {
3310     registerDefaultPortForProtocolForTesting(port, protocol);
3311 }
3312
3313 Ref<MallocStatistics> Internals::mallocStatistics() const
3314 {
3315     return MallocStatistics::create();
3316 }
3317
3318 Ref<TypeConversions> Internals::typeConversions() const
3319 {
3320     return TypeConversions::create();
3321 }
3322
3323 Ref<MemoryInfo> Internals::memoryInfo() const
3324 {
3325     return MemoryInfo::create();
3326 }
3327
3328 Vector<String> Internals::getReferencedFilePaths() const
3329 {
3330     frame()->loader().history().saveDocumentAndScrollState();
3331     return FormController::referencedFilePaths(frame()->loader().history().currentItem()->documentState());
3332 }
3333
3334 ExceptionOr<void> Internals::startTrackingRepaints()
3335 {
3336     Document* document = contextDocument();
3337     if (!document || !document->view())
3338         return Exception { InvalidAccessError };
3339
3340     document->view()->setTracksRepaints(true);
3341     return { };
3342 }
3343
3344 ExceptionOr<void> Internals::stopTrackingRepaints()
3345 {
3346     Document* document = contextDocument();
3347     if (!document || !document->view())
3348         return Exception { InvalidAccessError };
3349
3350     document->view()->setTracksRepaints(false);
3351     return { };
3352 }
3353
3354 ExceptionOr<void> Internals::startTrackingLayerFlushes()
3355 {
3356     Document* document = contextDocument();
3357     if (!document || !document->renderView())
3358         return Exception { InvalidAccessError };
3359
3360     document->renderView()->compositor().startTrackingLayerFlushes();
3361     return { };
3362 }
3363
3364 ExceptionOr<unsigned> Internals::layerFlushCount()
3365 {
3366     Document* document = contextDocument();
3367     if (!document || !document->renderView())
3368         return Exception { InvalidAccessError };
3369
3370     return document->renderView()->compositor().layerFlushCount();
3371 }
3372
3373 ExceptionOr<void> Internals::startTrackingStyleRecalcs()
3374 {
3375     Document* document = contextDocument();
3376     if (!document)
3377         return Exception { InvalidAccessError };
3378
3379     document->startTrackingStyleRecalcs();
3380     return { };
3381 }
3382
3383 ExceptionOr<unsigned> Internals::styleRecalcCount()
3384 {
3385     Document* document = contextDocument();
3386     if (!document)
3387         return Exception { InvalidAccessError };
3388
3389     return document->styleRecalcCount();
3390 }
3391
3392 unsigned Internals::lastStyleUpdateSize() const
3393 {
3394     Document* document = contextDocument();
3395     if (!document)
3396         return 0;
3397     return document->lastStyleUpdateSizeForTesting();
3398 }
3399
3400 ExceptionOr<void> Internals::startTrackingCompositingUpdates()
3401 {
3402     Document* document = contextDocument();
3403     if (!document || !document->renderView())
3404         return Exception { InvalidAccessError };
3405
3406     document->renderView()->compositor().startTrackingCompositingUpdates();
3407     return { };
3408 }
3409
3410 ExceptionOr<unsigned> Internals::compositingUpdateCount()
3411 {
3412     Document* document = contextDocument();
3413     if (!document || !document->renderView())
3414         return Exception { InvalidAccessError };
3415
3416     return document->renderView()->compositor().compositingUpdateCount();
3417 }
3418
3419 ExceptionOr<void> Internals::setCompositingPolicyOverride(Optional<CompositingPolicy> policyOverride)
3420 {
3421     Document* document = contextDocument();
3422     if (!document)
3423         return Exception { InvalidAccessError };
3424
3425     if (!policyOverride) {
3426         document->page()->setCompositingPolicyOverride(WTF::nullopt);
3427         return { };
3428     }
3429
3430     switch (policyOverride.value()) {
3431     case Internals::CompositingPolicy::Normal:
3432         document->page()->setCompositingPolicyOverride(WebCore::CompositingPolicy::Normal);
3433         break;
3434     case Internals::CompositingPolicy::Conservative:
3435         document->page()->setCompositingPolicyOverride(WebCore::CompositingPolicy::Conservative);
3436         break;
3437     }
3438     
3439     return { };
3440 }
3441
3442 ExceptionOr<Optional<Internals::CompositingPolicy>> Internals::compositingPolicyOverride() const
3443 {
3444     Document* document = contextDocument();
3445     if (!document)
3446         return Exception { InvalidAccessError };
3447
3448     auto policyOverride = document->page()->compositingPolicyOverride();
3449     if (!policyOverride)
3450         return { WTF::nullopt };
3451
3452     switch (policyOverride.value()) {
3453     case WebCore::CompositingPolicy::Normal:
3454         return { Internals::CompositingPolicy::Normal };
3455     case WebCore::CompositingPolicy::Conservative:
3456         return { Internals::CompositingPolicy::Conservative };
3457     }
3458
3459     return { Internals::CompositingPolicy::Normal };
3460 }
3461
3462 void Internals::updateLayoutAndStyleForAllFrames()
3463 {
3464     auto* document = contextDocument();
3465     if (!document || !document->view())
3466         return;
3467     document->view()->updateLayoutAndStyleIfNeededRecursive();
3468 }
3469
3470 ExceptionOr<void> Internals::updateLayoutIgnorePendingStylesheetsAndRunPostLayoutTasks(Node* node)
3471 {
3472     Document* document;
3473     if (!node)
3474         document = contextDocument();
3475     else if (is<Document>(*node))
3476         document = downcast<Document>(node);
3477     else if (is<HTMLIFrameElement>(*node))
3478         document = downcast<HTMLIFrameElement>(*node).contentDocument();
3479     else
3480         return Exception { TypeError };
3481
3482     document->updateLayoutIgnorePendingStylesheets(Document::RunPostLayoutTasks::Synchronously);
3483     return { };
3484 }
3485
3486 unsigned Internals::layoutCount() const
3487 {
3488     Document* document = contextDocument();
3489     if (!document || !document->view())
3490         return 0;
3491     return document->view()->layoutContext().layoutCount();
3492 }
3493
3494 #if !PLATFORM(IOS_FAMILY)
3495 static const char* cursorTypeToString(Cursor::Type cursorType)
3496 {
3497     switch (cursorType) {
3498     case Cursor::Pointer: return "Pointer";
3499     case Cursor::Cross: return "Cross";
3500     case Cursor::Hand: return "Hand";
3501     case Cursor::IBeam: return "IBeam";
3502     case Cursor::Wait: return "Wait";
3503     case Cursor::Help: return "Help";
3504     case Cursor::EastResize: return "EastResize";
3505     case Cursor::NorthResize: return "NorthResize";
3506     case Cursor::NorthEastResize: return "NorthEastResize";
3507     case Cursor::NorthWestResize: return "NorthWestResize";
3508     case Cursor::SouthResize: return "SouthResize";
3509     case Cursor::SouthEastResize: return "SouthEastResize";
3510     case Cursor::SouthWestResize: return "SouthWestResize";
3511     case Cursor::WestResize: return "WestResize";
3512     case Cursor::NorthSouthResize: return "NorthSouthResize";
3513     case Cursor::EastWestResize: return "EastWestResize";
3514     case Cursor::NorthEastSouthWestResize: return "NorthEastSouthWestResize";
3515     case Cursor::NorthWestSouthEastResize: return "NorthWestSouthEastResize";
3516     case Cursor::ColumnResize: return "ColumnResize";
3517     case Cursor::RowResize: return "RowResize";
3518     case Cursor::MiddlePanning: return "MiddlePanning";
3519     case Cursor::EastPanning: return "EastPanning";
3520     case Cursor::NorthPanning: return "NorthPanning";
3521     case Cursor::NorthEastPanning: return "NorthEastPanning";
3522     case Cursor::NorthWestPanning: return "NorthWestPanning";
3523     case Cursor::SouthPanning: return "SouthPanning";
3524     case Cursor::SouthEastPanning: return "SouthEastPanning";
3525     case Cursor::SouthWestPanning: return "SouthWestPanning";
3526     case Cursor::WestPanning: return "WestPanning";
3527     case Cursor::Move: return "Move";
3528     case Cursor::VerticalText: return "VerticalText";
3529     case Cursor::Cell: return "Cell";
3530     case Cursor::ContextMenu: return "ContextMenu";
3531     case Cursor::Alias: return "Alias";
3532     case Cursor::Progress: return "Progress";
3533     case Cursor::NoDrop: return "NoDrop";
3534     case Cursor::Copy: return "Copy";
3535     case Cursor::None: return "None";
3536     case Cursor::NotAllowed: return "NotAllowed";
3537     case Cursor::ZoomIn: return "ZoomIn";
3538     case Cursor::ZoomOut: return "ZoomOut";
3539     case Cursor::Grab: return "Grab";
3540     case Cursor::Grabbing: return "Grabbing";
3541     case Cursor::Custom: return "Custom";
3542     }
3543
3544     ASSERT_NOT_REACHED();
3545     return "UNKNOWN";
3546 }
3547 #endif
3548
3549 ExceptionOr<String> Internals::getCurrentCursorInfo()
3550 {
3551     Document* document = contextDocument();
3552     if (!document || !document->frame())
3553         return Exception { InvalidAccessError };
3554
3555 #if !PLATFORM(IOS_FAMILY)
3556     Cursor cursor = document->frame()->eventHandler().currentMouseCursor();
3557
3558     StringBuilder result;
3559     result.append("type=", cursorTypeToString(cursor.type()), " hotSpot=", cursor.hotSpot().x(), ',', cursor.hotSpot().y());
3560     if (cursor.image()) {
3561         FloatSize size = cursor.image()->size();
3562         result.append(" image=", size.width(), 'x', size.height());
3563     }
3564 #if ENABLE(MOUSE_CURSOR_SCALE)
3565     if (cursor.imageScaleFactor() != 1)
3566         result.append(" scale=", cursor.imageScaleFactor());
3567 #endif
3568     return result.toString();
3569 #else
3570     return "FAIL: Cursor details not available on this platform."_str;
3571 #endif
3572 }
3573
3574 Ref<ArrayBuffer> Internals::serializeObject(const RefPtr<SerializedScriptValue>& value) const
3575 {
3576     auto& bytes = value->data();
3577     return ArrayBuffer::create(bytes.data(), bytes.size());
3578 }
3579
3580 Ref<SerializedScriptValue> Internals::deserializeBuffer(ArrayBuffer& buffer) const
3581 {
3582     Vector<uint8_t> bytes;
3583     bytes.append(static_cast<const uint8_t*>(buffer.data()), buffer.byteLength());
3584     return SerializedScriptValue::adopt(WTFMove(bytes));
3585 }
3586
3587 bool Internals::isFromCurrentWorld(JSC::JSValue value) const
3588 {
3589     JSC::VM& vm = contextDocument()->vm();
3590     return isWorldCompatible(*vm.topCallFrame->lexicalGlobalObject(vm), value);
3591 }
3592
3593 JSC::JSValue Internals::evaluateInWorldIgnoringException(const String& name, const String& source)
3594 {
3595     auto* document = contextDocument();
3596     auto& scriptController = document->frame()->script();
3597     auto world = ScriptController::createWorld(name);
3598     return scriptController.executeScriptInWorldIgnoringException(world, source);
3599 }
3600
3601 void Internals::setUsesOverlayScrollbars(bool enabled)
3602 {
3603     WebCore::DeprecatedGlobalSettings::setUsesOverlayScrollbars(enabled);
3604 #if PLATFORM(MAC)
3605     ScrollerStyle::setUseOverlayScrollbars(enabled);
3606     ScrollbarTheme& theme = ScrollbarTheme::theme();
3607     if (theme.isMockTheme())
3608         return;
3609
3610     static_cast<ScrollbarThemeMac&>(theme).preferencesChanged();
3611 #endif
3612 }
3613
3614 void Internals::setUsesMockScrollAnimator(bool enabled)
3615 {
3616     WebCore::DeprecatedGlobalSettings::setUsesMockScrollAnimator(enabled);
3617 }
3618
3619 void Internals::forceReload(bool endToEnd)
3620 {
3621     OptionSet<ReloadOption> reloadOptions;
3622     if (endToEnd)
3623         reloadOptions.add(ReloadOption::FromOrigin);
3624
3625     frame()->loader().reload(reloadOptions);
3626 }
3627
3628 void Internals::reloadExpiredOnly()
3629 {
3630     frame()->loader().reload(ReloadOption::ExpiredOnly);
3631 }
3632
3633 void Internals::enableFixedWidthAutoSizeMode(bool enabled, int width, int height)
3634 {
3635     auto* document = contextDocument();
3636     if (!document || !document->view())
3637         return;
3638     document->view()->enableFixedWidthAutoSizeMode(enabled, { width, height });
3639 }
3640
3641 #if ENABLE(LEGACY_ENCRYPTED_MEDIA)
3642
3643 void Internals::initializeMockCDM()
3644 {
3645     LegacyCDM::registerCDMFactory([] (LegacyCDM* cdm) { return makeUnique<LegacyMockCDM>(cdm); },
3646         LegacyMockCDM::supportsKeySystem, LegacyMockCDM::supportsKeySystemAndMimeType);
3647 }
3648
3649 #endif
3650
3651 #if ENABLE(ENCRYPTED_MEDIA)
3652
3653 Ref<MockCDMFactory> Internals::registerMockCDM()
3654 {
3655     return MockCDMFactory::create();
3656 }
3657
3658 #endif
3659
3660 String Internals::markerTextForListItem(Element& element)
3661 {
3662     return WebCore::markerTextForListItem(&element);
3663 }
3664
3665 String Internals::toolTipFromElement(Element& element) const
3666 {
3667     HitTestResult result;
3668     result.setInnerNode(&element);
3669     TextDirection direction;
3670     return result.title(direction);
3671 }
3672
3673 String Internals::getImageSourceURL(Element& element)
3674 {
3675     return element.imageSourceURL();
3676 }
3677
3678 #if ENABLE(VIDEO)
3679
3680 Vector<String> Internals::mediaResponseSources(HTMLMediaElement& media)
3681 {
3682     auto* resourceLoader = media.lastMediaResourceLoaderForTesting();
3683     if (!resourceLoader)
3684         return { };
3685     Vector<String> result;
3686     auto responses = resourceLoader->responsesForTesting();
3687     for (auto& response : responses)
3688         result.append(responseSourceToString(response));
3689     return result;
3690 }
3691
3692 Vector<String> Internals::mediaResponseContentRanges(HTMLMediaElement& media)
3693 {
3694     auto* resourceLoader = media.lastMediaResourceLoaderForTesting();
3695     if (!resourceLoader)
3696         return { };
3697     Vector<String> result;
3698     auto responses = resourceLoader->responsesForTesting();
3699     for (auto& response : responses)
3700         result.append(response.httpHeaderField(HTTPHeaderName::ContentRange));
3701     return result;
3702 }
3703
3704 void Internals::simulateAudioInterruption(HTMLMediaElement& element)
3705 {
3706 #if USE(GSTREAMER)
3707     element.player()->simulateAudioInterruption();
3708 #else
3709     UNUSED_PARAM(element);
3710 #endif
3711 }
3712
3713 ExceptionOr<bool> Internals::mediaElementHasCharacteristic(HTMLMediaElement& element, const String& characteristic)
3714 {
3715     if (equalLettersIgnoringASCIICase(characteristic, "audible"))
3716         return element.hasAudio();
3717     if (equalLettersIgnoringASCIICase(characteristic, "visual"))
3718         return element.hasVideo();
3719     if (equalLettersIgnoringASCIICase(characteristic, "legible"))
3720         return element.hasClosedCaptions();
3721
3722     return Exception { SyntaxError };
3723 }
3724
3725 void Internals::beginSimulatedHDCPError(HTMLMediaElement& element)
3726 {
3727     if (auto player = element.player())
3728         player->beginSimulatedHDCPError();
3729 }
3730
3731 void Internals::endSimulatedHDCPError(HTMLMediaElement& element)
3732 {
3733     if (auto player = element.player())
3734         player->endSimulatedHDCPError();
3735 }
3736
3737 bool Internals::elementShouldBufferData(HTMLMediaElement& element)
3738 {
3739     return element.bufferingPolicy() < MediaPlayer::BufferingPolicy::LimitReadAhead;
3740 }
3741
3742 String Internals::elementBufferingPolicy(HTMLMediaElement& element)
3743 {
3744     switch (element.bufferingPolicy()) {
3745     case MediaPlayer::BufferingPolicy::Default:
3746         return "Default";
3747     case MediaPlayer::BufferingPolicy::LimitReadAhead:
3748         return "LimitReadAhead";
3749     case MediaPlayer::BufferingPolicy::MakeResourcesPurgeable:
3750         return "MakeResourcesPurgeable";
3751     case MediaPlayer::BufferingPolicy::PurgeResources:
3752         return "PurgeResources";
3753     }
3754
3755     ASSERT_NOT_REACHED();
3756     return "UNKNOWN";
3757 }
3758 #endif
3759
3760 bool Internals::isSelectPopupVisible(HTMLSelectElement& element)
3761 {
3762     element.document().updateLayoutIgnorePendingStylesheets();
3763
3764     auto* renderer = element.renderer();
3765     if (!is<RenderMenuList>(renderer))
3766         return false;
3767
3768 #if !PLATFORM(IOS_FAMILY)
3769     return downcast<RenderMenuList>(*renderer).popupIsVisible();
3770 #else
3771     return false;
3772 #endif
3773 }
3774
3775 ExceptionOr<String> Internals::captionsStyleSheetOverride()
3776 {
3777     Document* document = contextDocument();
3778     if (!document || !document->page())
3779         return Exception { InvalidAccessError };
3780
3781 #if ENABLE(VIDEO_TRACK)
3782     return document->page()->group().captionPreferences().captionsStyleSheetOverride();
3783 #else
3784     return String { emptyString() };
3785 #endif
3786 }
3787
3788 ExceptionOr<void> Internals::setCaptionsStyleSheetOverride(const String& override)
3789 {
3790     Document* document = contextDocument();
3791     if (!document || !document->page())
3792         return Exception { InvalidAccessError };
3793
3794 #if ENABLE(VIDEO_TRACK)
3795     document->page()->group().captionPreferences().setCaptionsStyleSheetOverride(override);
3796 #else
3797     UNUSED_PARAM(override);
3798 #endif
3799     return { };
3800 }
3801
3802 ExceptionOr<void> Internals::setPrimaryAudioTrackLanguageOverride(const String& language)
3803 {