WebRTC: Implement MediaEndpointPeerConnection::createOffer()
[WebKit-https.git] / Source / WebCore / testing / Internals.cpp
1 /*
2  * Copyright (C) 2012 Google Inc. All rights reserved.
3  * Copyright (C) 2013-2015 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 "ActiveDOMCallbackMicrotask.h"
32 #include "AnimationController.h"
33 #include "ApplicationCacheStorage.h"
34 #include "Autofill.h"
35 #include "BackForwardController.h"
36 #include "BitmapImage.h"
37 #include "CachedImage.h"
38 #include "CachedResourceLoader.h"
39 #include "Chrome.h"
40 #include "ChromeClient.h"
41 #include "ClientRect.h"
42 #include "ClientRectList.h"
43 #include "ComposedTreeIterator.h"
44 #include "Cursor.h"
45 #include "DOMPath.h"
46 #include "DOMStringList.h"
47 #include "DOMWindow.h"
48 #include "DisplayList.h"
49 #include "Document.h"
50 #include "DocumentMarker.h"
51 #include "DocumentMarkerController.h"
52 #include "Editor.h"
53 #include "Element.h"
54 #include "EventHandler.h"
55 #include "ExceptionCode.h"
56 #include "ExtensionStyleSheets.h"
57 #include "File.h"
58 #include "FontCache.h"
59 #include "FormController.h"
60 #include "FrameLoader.h"
61 #include "FrameView.h"
62 #include "HTMLCanvasElement.h"
63 #include "HTMLIFrameElement.h"
64 #include "HTMLImageElement.h"
65 #include "HTMLInputElement.h"
66 #include "HTMLLinkElement.h"
67 #include "HTMLNames.h"
68 #include "HTMLPlugInElement.h"
69 #include "HTMLPreloadScanner.h"
70 #include "HTMLSelectElement.h"
71 #include "HTMLTextAreaElement.h"
72 #include "HTMLVideoElement.h"
73 #include "HistoryController.h"
74 #include "HistoryItem.h"
75 #include "HitTestResult.h"
76 #include "IconController.h"
77 #include "InspectorClient.h"
78 #include "InspectorController.h"
79 #include "InspectorFrontendClientLocal.h"
80 #include "InspectorOverlay.h"
81 #include "InstrumentingAgents.h"
82 #include "IntRect.h"
83 #include "InternalSettings.h"
84 #include "Language.h"
85 #include "MainFrame.h"
86 #include "MallocStatistics.h"
87 #include "MediaPlayer.h"
88 #include "MemoryCache.h"
89 #include "MemoryInfo.h"
90 #include "MockPageOverlay.h"
91 #include "MockPageOverlayClient.h"
92 #include "Page.h"
93 #include "PageCache.h"
94 #include "PageOverlay.h"
95 #include "PathUtilities.h"
96 #include "PlatformMediaSessionManager.h"
97 #include "PrintContext.h"
98 #include "PseudoElement.h"
99 #include "Range.h"
100 #include "RenderEmbeddedObject.h"
101 #include "RenderLayerBacking.h"
102 #include "RenderLayerCompositor.h"
103 #include "RenderMenuList.h"
104 #include "RenderTreeAsText.h"
105 #include "RenderView.h"
106 #include "RenderedDocumentMarker.h"
107 #include "ResourceLoadObserver.h"
108 #include "RuntimeEnabledFeatures.h"
109 #include "SchemeRegistry.h"
110 #include "ScriptedAnimationController.h"
111 #include "ScrollingCoordinator.h"
112 #include "SerializedScriptValue.h"
113 #include "Settings.h"
114 #include "ShadowRoot.h"
115 #include "SourceBuffer.h"
116 #include "SpellChecker.h"
117 #include "StaticNodeList.h"
118 #include "StyleSheetContents.h"
119 #include "TextIterator.h"
120 #include "TreeScope.h"
121 #include "TypeConversions.h"
122 #include "UserMediaController.h"
123 #include "ViewportArguments.h"
124 #include "WebCoreJSClientData.h"
125 #include "WorkerThread.h"
126 #include "XMLHttpRequest.h"
127 #include <JavaScriptCore/Profile.h>
128 #include <bytecode/CodeBlock.h>
129 #include <inspector/InspectorAgentBase.h>
130 #include <inspector/InspectorFrontendChannel.h>
131 #include <inspector/InspectorValues.h>
132 #include <runtime/JSCInlines.h>
133 #include <runtime/JSCJSValue.h>
134 #include <wtf/text/CString.h>
135 #include <wtf/text/StringBuffer.h>
136
137 #if ENABLE(INPUT_TYPE_COLOR)
138 #include "ColorChooser.h"
139 #endif
140
141 #if ENABLE(BATTERY_STATUS)
142 #include "BatteryController.h"
143 #endif
144
145 #if ENABLE(PROXIMITY_EVENTS)
146 #include "DeviceProximityController.h"
147 #endif
148
149 #if ENABLE(MOUSE_CURSOR_SCALE)
150 #include <wtf/dtoa.h>
151 #endif
152
153 #if ENABLE(ENCRYPTED_MEDIA_V2)
154 #include "CDM.h"
155 #include "MockCDM.h"
156 #endif
157
158 #if ENABLE(VIDEO_TRACK)
159 #include "CaptionUserPreferences.h"
160 #include "PageGroup.h"
161 #endif
162
163 #if ENABLE(VIDEO)
164 #include "HTMLMediaElement.h"
165 #include "TimeRanges.h"
166 #endif
167
168 #if ENABLE(SPEECH_SYNTHESIS)
169 #include "DOMWindowSpeechSynthesis.h"
170 #include "PlatformSpeechSynthesizerMock.h"
171 #include "SpeechSynthesis.h"
172 #endif
173
174 #if ENABLE(VIBRATION)
175 #include "Vibration.h"
176 #endif
177
178 #if ENABLE(MEDIA_STREAM)
179 #include "MockMediaEndpoint.h"
180 #include "MockRealtimeMediaSourceCenter.h"
181 #include "RTCPeerConnection.h"
182 #include "RTCPeerConnectionHandlerMock.h"
183 #endif
184
185 #if ENABLE(MEDIA_SOURCE)
186 #include "MockMediaPlayerMediaSource.h"
187 #endif
188
189 #if PLATFORM(MAC)
190 #include "DictionaryLookup.h"
191 #endif
192
193 #if ENABLE(CONTENT_FILTERING)
194 #include "MockContentFilterSettings.h"
195 #endif
196
197 #if ENABLE(WEB_AUDIO)
198 #include "AudioContext.h"
199 #endif
200
201 #if ENABLE(MEDIA_SESSION)
202 #include "MediaSession.h"
203 #include "MediaSessionManager.h"
204 #endif
205
206 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
207 #include "MediaPlaybackTargetContext.h"
208 #endif
209
210 using JSC::CallData;
211 using JSC::CallType;
212 using JSC::CodeBlock;
213 using JSC::FunctionExecutable;
214 using JSC::Identifier;
215 using JSC::JSFunction;
216 using JSC::JSGlobalObject;
217 using JSC::JSObject;
218 using JSC::JSValue;
219 using JSC::MarkedArgumentBuffer;
220 using JSC::PropertySlot;
221 using JSC::ScriptExecutable;
222 using JSC::StackVisitor;
223
224 using namespace Inspector;
225
226 namespace WebCore {
227
228 using namespace HTMLNames;
229
230 class InspectorStubFrontend : public InspectorFrontendClientLocal, public FrontendChannel {
231 public:
232     InspectorStubFrontend(Page* inspectedPage, RefPtr<DOMWindow>&& frontendWindow);
233     virtual ~InspectorStubFrontend();
234
235     // InspectorFrontendClient API
236     void attachWindow(DockSide) override { }
237     void detachWindow() override { }
238     void closeWindow() override;
239     void bringToFront() override { }
240     String localizedStringsURL() override { return String(); }
241     void inspectedURLChanged(const String&) override { }
242 protected:
243     void setAttachedWindowHeight(unsigned) override { }
244     void setAttachedWindowWidth(unsigned) override { }
245
246 public:
247     // Inspector::FrontendChannel API
248     bool sendMessageToFrontend(const String& message) override;
249     ConnectionType connectionType() const override { return ConnectionType::Local; }
250
251 private:
252     Page* frontendPage() const
253     {
254         if (!m_frontendWindow || !m_frontendWindow->document())
255             return nullptr;
256
257         return m_frontendWindow->document()->page();
258     }
259
260     RefPtr<DOMWindow> m_frontendWindow;
261     InspectorController& m_frontendController;
262 };
263
264 InspectorStubFrontend::InspectorStubFrontend(Page* inspectedPage, RefPtr<DOMWindow>&& frontendWindow)
265     : InspectorFrontendClientLocal(&inspectedPage->inspectorController(), frontendWindow->document()->page(), std::make_unique<InspectorFrontendClientLocal::Settings>())
266     , m_frontendWindow(frontendWindow.copyRef())
267     , m_frontendController(frontendPage()->inspectorController())
268 {
269     ASSERT_ARG(inspectedPage, inspectedPage);
270     ASSERT_ARG(frontendWindow, frontendWindow);
271
272     m_frontendController.setInspectorFrontendClient(this);
273     inspectedPage->inspectorController().connectFrontend(this);
274 }
275
276 InspectorStubFrontend::~InspectorStubFrontend()
277 {
278     closeWindow();
279 }
280
281 void InspectorStubFrontend::closeWindow()
282 {
283     if (!m_frontendWindow)
284         return;
285
286     m_frontendController.setInspectorFrontendClient(nullptr);
287     inspectedPage()->inspectorController().disconnectFrontend(this);
288
289     m_frontendWindow->close(m_frontendWindow->scriptExecutionContext());
290     m_frontendWindow = nullptr;
291 }
292
293 bool InspectorStubFrontend::sendMessageToFrontend(const String& message)
294 {
295     ASSERT_ARG(message, !message.isEmpty());
296
297     return InspectorClient::doDispatchMessageOnFrontendPage(frontendPage(), message);
298 }
299
300 static bool markerTypeFrom(const String& markerType, DocumentMarker::MarkerType& result)
301 {
302     if (equalLettersIgnoringASCIICase(markerType, "spelling"))
303         result = DocumentMarker::Spelling;
304     else if (equalLettersIgnoringASCIICase(markerType, "grammar"))
305         result = DocumentMarker::Grammar;
306     else if (equalLettersIgnoringASCIICase(markerType, "textmatch"))
307         result = DocumentMarker::TextMatch;
308     else if (equalLettersIgnoringASCIICase(markerType, "replacement"))
309         result = DocumentMarker::Replacement;
310     else if (equalLettersIgnoringASCIICase(markerType, "correctionindicator"))
311         result = DocumentMarker::CorrectionIndicator;
312     else if (equalLettersIgnoringASCIICase(markerType, "rejectedcorrection"))
313         result = DocumentMarker::RejectedCorrection;
314     else if (equalLettersIgnoringASCIICase(markerType, "autocorrected"))
315         result = DocumentMarker::Autocorrected;
316     else if (equalLettersIgnoringASCIICase(markerType, "spellcheckingexemption"))
317         result = DocumentMarker::SpellCheckingExemption;
318     else if (equalLettersIgnoringASCIICase(markerType, "deletedautocorrection"))
319         result = DocumentMarker::DeletedAutocorrection;
320     else if (equalLettersIgnoringASCIICase(markerType, "dictationalternatives"))
321         result = DocumentMarker::DictationAlternatives;
322 #if ENABLE(TELEPHONE_NUMBER_DETECTION)
323     else if (equalLettersIgnoringASCIICase(markerType, "telephonenumber"))
324         result = DocumentMarker::TelephoneNumber;
325 #endif
326     else
327         return false;
328     
329     return true;
330 }
331
332 static bool markerTypesFrom(const String& markerType, DocumentMarker::MarkerTypes& result)
333 {
334     DocumentMarker::MarkerType singularResult;
335
336     if (markerType.isEmpty() || equalLettersIgnoringASCIICase(markerType, "all"))
337         result = DocumentMarker::AllMarkers();
338     else if (markerTypeFrom(markerType, singularResult))
339         result = singularResult;
340     else
341         return false;
342
343     return true;
344 }
345
346 const char* Internals::internalsId = "internals";
347
348 Ref<Internals> Internals::create(Document* document)
349 {
350     return adoptRef(*new Internals(document));
351 }
352
353 Internals::~Internals()
354 {
355 }
356
357 void Internals::resetToConsistentState(Page* page)
358 {
359     ASSERT(page);
360
361     page->setPageScaleFactor(1, IntPoint(0, 0));
362     page->setPagination(Pagination());
363     page->setPaginationLineGridEnabled(false);
364
365     page->setDefersLoading(false);
366     
367     page->mainFrame().setTextZoomFactor(1.0f);
368     
369     FrameView* mainFrameView = page->mainFrame().view();
370     if (mainFrameView) {
371         mainFrameView->setHeaderHeight(0);
372         mainFrameView->setFooterHeight(0);
373         page->setTopContentInset(0);
374         mainFrameView->setUseFixedLayout(false);
375         mainFrameView->setFixedLayoutSize(IntSize());
376     }
377
378     WebCore::overrideUserPreferredLanguages(Vector<String>());
379     WebCore::Settings::setUsesOverlayScrollbars(false);
380     WebCore::Settings::setUsesMockScrollAnimator(false);
381     page->inspectorController().setLegacyProfilerEnabled(false);
382 #if ENABLE(VIDEO_TRACK)
383     page->group().captionPreferences().setCaptionsStyleSheetOverride(emptyString());
384     page->group().captionPreferences().setTestingMode(false);
385 #endif
386     if (!page->mainFrame().editor().isContinuousSpellCheckingEnabled())
387         page->mainFrame().editor().toggleContinuousSpellChecking();
388     if (page->mainFrame().editor().isOverwriteModeEnabled())
389         page->mainFrame().editor().toggleOverwriteModeEnabled();
390     page->mainFrame().loader().clearTestingOverrides();
391     ApplicationCacheStorage::singleton().setDefaultOriginQuota(ApplicationCacheStorage::noQuota());
392 #if ENABLE(VIDEO)
393     PlatformMediaSessionManager::sharedManager().resetRestrictions();
394     PlatformMediaSessionManager::sharedManager().setWillIgnoreSystemInterruptions(true);
395 #endif
396 #if HAVE(ACCESSIBILITY)
397     AXObjectCache::setEnhancedUserInterfaceAccessibility(false);
398     AXObjectCache::disableAccessibility();
399 #endif
400
401     MockPageOverlayClient::singleton().uninstallAllOverlays();
402
403 #if ENABLE(CONTENT_FILTERING)
404     MockContentFilterSettings::reset();
405 #endif
406
407     page->setShowAllPlugins(false);
408 }
409
410 Internals::Internals(Document* document)
411     : ContextDestructionObserver(document)
412 {
413 #if ENABLE(VIDEO_TRACK)
414     if (document && document->page())
415         document->page()->group().captionPreferences().setTestingMode(true);
416 #endif
417
418 #if ENABLE(MEDIA_STREAM)
419     setMockMediaCaptureDevicesEnabled(true);
420     enableMockMediaEndpoint();
421     enableMockRTCPeerConnectionHandler();
422 #endif
423
424 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
425     if (document && document->page())
426         document->page()->setMockMediaPlaybackTargetPickerEnabled(true);
427 #endif
428 }
429
430 Document* Internals::contextDocument() const
431 {
432     return downcast<Document>(scriptExecutionContext());
433 }
434
435 Frame* Internals::frame() const
436 {
437     if (!contextDocument())
438         return nullptr;
439     return contextDocument()->frame();
440 }
441
442 InternalSettings* Internals::settings() const
443 {
444     Document* document = contextDocument();
445     if (!document)
446         return 0;
447     Page* page = document->page();
448     if (!page)
449         return 0;
450     return InternalSettings::from(page);
451 }
452
453 unsigned Internals::workerThreadCount() const
454 {
455     return WorkerThread::workerThreadCount();
456 }
457
458 String Internals::address(Node* node)
459 {
460     return String::format("%p", node);
461 }
462
463 bool Internals::nodeNeedsStyleRecalc(Node* node, ExceptionCode& exception)
464 {
465     if (!node) {
466         exception = INVALID_ACCESS_ERR;
467         return false;
468     }
469
470     return node->needsStyleRecalc();
471 }
472
473 static String styleChangeTypeToString(StyleChangeType type)
474 {
475     switch (type) {
476     case NoStyleChange:
477         return "NoStyleChange";
478     case InlineStyleChange:
479         return "InlineStyleChange";
480     case FullStyleChange:
481         return "FullStyleChange";
482     case SyntheticStyleChange:
483         return "SyntheticStyleChange";
484     case ReconstructRenderTree:
485         return "ReconstructRenderTree";
486     }
487     ASSERT_NOT_REACHED();
488     return "";
489 }
490
491 String Internals::styleChangeType(Node* node, ExceptionCode& exception)
492 {
493     if (!node) {
494         exception = INVALID_ACCESS_ERR;
495         return { };
496     }
497
498     return styleChangeTypeToString(node->styleChangeType());
499 }
500
501 String Internals::description(Deprecated::ScriptValue value)
502 {
503     return toString(value.jsValue());
504 }
505
506 bool Internals::isPreloaded(const String& url)
507 {
508     Document* document = contextDocument();
509     return document->cachedResourceLoader().isPreloaded(url);
510 }
511
512 bool Internals::isLoadingFromMemoryCache(const String& url)
513 {
514     if (!contextDocument() || !contextDocument()->page())
515         return false;
516
517     ResourceRequest request(contextDocument()->completeURL(url));
518 #if ENABLE(CACHE_PARTITIONING)
519     request.setDomainForCachePartition(contextDocument()->topOrigin()->domainForCachePartition());
520 #endif
521     CachedResource* resource = MemoryCache::singleton().resourceForRequest(request, contextDocument()->page()->sessionID());
522     return resource && resource->status() == CachedResource::Cached;
523 }
524
525 String Internals::xhrResponseSource(XMLHttpRequest* xhr)
526 {
527     if (!xhr)
528         return "Null xhr";
529     if (xhr->resourceResponse().isNull())
530         return "Null response";
531     switch (xhr->resourceResponse().source()) {
532     case ResourceResponse::Source::Unknown:
533         return "Unknown";
534     case ResourceResponse::Source::Network:
535         return "Network";
536     case ResourceResponse::Source::DiskCache:
537         return "Disk cache";
538     case ResourceResponse::Source::DiskCacheAfterValidation:
539         return "Disk cache after validation";
540     case ResourceResponse::Source::MemoryCache:
541         return "Memory cache";
542     case ResourceResponse::Source::MemoryCacheAfterValidation:
543         return "Memory cache after validation";
544     }
545     ASSERT_NOT_REACHED();
546     return "Error";
547 }
548
549 bool Internals::isSharingStyleSheetContents(Element* a, Element* b)
550 {
551     if (!is<HTMLLinkElement>(a) || !is<HTMLLinkElement>(b))
552         return false;
553     auto& aLink = downcast<HTMLLinkElement>(*a);
554     auto& bLink = downcast<HTMLLinkElement>(*b);
555     if (!aLink.sheet() || !bLink.sheet())
556         return false;
557     return &aLink.sheet()->contents() == &bLink.sheet()->contents();
558 }
559
560 bool Internals::isStyleSheetLoadingSubresources(Element* link)
561 {
562     if (!is<HTMLLinkElement>(link))
563         return false;
564     auto& linkElement = downcast<HTMLLinkElement>(*link);
565     return linkElement.sheet() && linkElement.sheet()->contents().isLoadingSubresources();
566 }
567
568 static ResourceRequestCachePolicy stringToResourceRequestCachePolicy(const String& policy)
569 {
570     if (policy == "UseProtocolCachePolicy")
571         return UseProtocolCachePolicy;
572     if (policy == "ReloadIgnoringCacheData")
573         return ReloadIgnoringCacheData;
574     if (policy == "ReturnCacheDataElseLoad")
575         return ReturnCacheDataElseLoad;
576     if (policy == "ReturnCacheDataDontLoad")
577         return ReturnCacheDataDontLoad;
578     ASSERT_NOT_REACHED();
579     return UseProtocolCachePolicy;
580 }
581
582 void Internals::setOverrideCachePolicy(const String& policy)
583 {
584     frame()->loader().setOverrideCachePolicyForTesting(stringToResourceRequestCachePolicy(policy));
585 }
586
587 void Internals::setCanShowModalDialogOverride(bool allow, ExceptionCode& ec)
588 {
589     if (!contextDocument() || !contextDocument()->domWindow()) {
590         ec = INVALID_ACCESS_ERR;
591         return;
592     }
593
594     contextDocument()->domWindow()->setCanShowModalDialogOverride(allow);
595 }
596
597 static ResourceLoadPriority stringToResourceLoadPriority(const String& policy)
598 {
599     if (policy == "ResourceLoadPriorityVeryLow")
600         return ResourceLoadPriority::VeryLow;
601     if (policy == "ResourceLoadPriorityLow")
602         return ResourceLoadPriority::Low;
603     if (policy == "ResourceLoadPriorityMedium")
604         return ResourceLoadPriority::Medium;
605     if (policy == "ResourceLoadPriorityHigh")
606         return ResourceLoadPriority::High;
607     if (policy == "ResourceLoadPriorityVeryHigh")
608         return ResourceLoadPriority::VeryHigh;
609     ASSERT_NOT_REACHED();
610     return ResourceLoadPriority::Low;
611 }
612
613 void Internals::setOverrideResourceLoadPriority(const String& priority)
614 {
615     frame()->loader().setOverrideResourceLoadPriorityForTesting(stringToResourceLoadPriority(priority));
616 }
617
618 void Internals::setStrictRawResourceValidationPolicyDisabled(bool disabled)
619 {
620     frame()->loader().setStrictRawResourceValidationPolicyDisabledForTesting(disabled);
621 }
622
623 void Internals::clearMemoryCache()
624 {
625     MemoryCache::singleton().evictResources();
626 }
627
628 void Internals::pruneMemoryCacheToSize(unsigned size)
629 {
630     MemoryCache::singleton().pruneDeadResourcesToSize(size);
631     MemoryCache::singleton().pruneLiveResourcesToSize(size, true);
632 }
633
634 unsigned Internals::memoryCacheSize() const
635 {
636     return MemoryCache::singleton().size();
637 }
638
639 size_t Internals::imageFrameIndex(Element* element, ExceptionCode& ec)
640 {
641     if (!is<HTMLImageElement>(element)) {
642         ec = TypeError;
643         return 0;
644     }
645
646     auto* cachedImage = downcast<HTMLImageElement>(*element).cachedImage();
647     if (!cachedImage)
648         return 0;
649
650     auto* image = cachedImage->image();
651     return is<BitmapImage>(image) ? downcast<BitmapImage>(*image).currentFrame() : 0;
652 }
653
654 void Internals::clearPageCache()
655 {
656     PageCache::singleton().pruneToSizeNow(0, PruningReason::None);
657 }
658
659 unsigned Internals::pageCacheSize() const
660 {
661     return PageCache::singleton().pageCount();
662 }
663
664 Node* Internals::treeScopeRootNode(Node* node, ExceptionCode& ec)
665 {
666     if (!node) {
667         ec = INVALID_ACCESS_ERR;
668         return nullptr;
669     }
670
671     return &node->treeScope().rootNode();
672 }
673
674 Node* Internals::parentTreeScope(Node* node, ExceptionCode& ec)
675 {
676     if (!node) {
677         ec = INVALID_ACCESS_ERR;
678         return nullptr;
679     }
680     const TreeScope* parentTreeScope = node->treeScope().parentTreeScope();
681     return parentTreeScope ? &parentTreeScope->rootNode() : nullptr;
682 }
683
684 unsigned Internals::lastSpatialNavigationCandidateCount(ExceptionCode& ec) const
685 {
686     if (!contextDocument() || !contextDocument()->page()) {
687         ec = INVALID_ACCESS_ERR;
688         return 0;
689     }
690
691     return contextDocument()->page()->lastSpatialNavigationCandidateCount();
692 }
693
694 unsigned Internals::numberOfActiveAnimations() const
695 {
696     return frame()->animation().numberOfActiveAnimations(frame()->document());
697 }
698
699 bool Internals::animationsAreSuspended(ExceptionCode& ec) const
700 {
701     Document* document = contextDocument();
702     if (!document || !document->frame()) {
703         ec = INVALID_ACCESS_ERR;
704         return false;
705     }
706
707     return document->frame()->animation().isSuspended();
708 }
709
710 void Internals::suspendAnimations(ExceptionCode& ec) const
711 {
712     Document* document = contextDocument();
713     if (!document || !document->frame()) {
714         ec = INVALID_ACCESS_ERR;
715         return;
716     }
717
718     document->frame()->animation().suspendAnimations();
719 }
720
721 void Internals::resumeAnimations(ExceptionCode& ec) const
722 {
723     Document* document = contextDocument();
724     if (!document || !document->frame()) {
725         ec = INVALID_ACCESS_ERR;
726         return;
727     }
728
729     document->frame()->animation().resumeAnimations();
730 }
731
732 bool Internals::pauseAnimationAtTimeOnElement(const String& animationName, double pauseTime, Element* element, ExceptionCode& ec)
733 {
734     if (!element || pauseTime < 0) {
735         ec = INVALID_ACCESS_ERR;
736         return false;
737     }
738     return frame()->animation().pauseAnimationAtTime(element->renderer(), AtomicString(animationName), pauseTime);
739 }
740
741 bool Internals::pauseAnimationAtTimeOnPseudoElement(const String& animationName, double pauseTime, Element* element, const String& pseudoId, ExceptionCode& ec)
742 {
743     if (!element || pauseTime < 0) {
744         ec = INVALID_ACCESS_ERR;
745         return false;
746     }
747
748     if (pseudoId != "before" && pseudoId != "after") {
749         ec = INVALID_ACCESS_ERR;
750         return false;
751     }
752
753     PseudoElement* pseudoElement = pseudoId == "before" ? element->beforePseudoElement() : element->afterPseudoElement();
754     if (!pseudoElement) {
755         ec = INVALID_ACCESS_ERR;
756         return false;
757     }
758
759     return frame()->animation().pauseAnimationAtTime(pseudoElement->renderer(), AtomicString(animationName), pauseTime);
760 }
761
762 bool Internals::pauseTransitionAtTimeOnElement(const String& propertyName, double pauseTime, Element* element, ExceptionCode& ec)
763 {
764     if (!element || pauseTime < 0) {
765         ec = INVALID_ACCESS_ERR;
766         return false;
767     }
768     return frame()->animation().pauseTransitionAtTime(element->renderer(), propertyName, pauseTime);
769 }
770
771 bool Internals::pauseTransitionAtTimeOnPseudoElement(const String& property, double pauseTime, Element* element, const String& pseudoId, ExceptionCode& ec)
772 {
773     if (!element || pauseTime < 0) {
774         ec = INVALID_ACCESS_ERR;
775         return false;
776     }
777
778     if (pseudoId != "before" && pseudoId != "after") {
779         ec = INVALID_ACCESS_ERR;
780         return false;
781     }
782
783     PseudoElement* pseudoElement = pseudoId == "before" ? element->beforePseudoElement() : element->afterPseudoElement();
784     if (!pseudoElement) {
785         ec = INVALID_ACCESS_ERR;
786         return false;
787     }
788
789     return frame()->animation().pauseTransitionAtTime(pseudoElement->renderer(), property, pauseTime);
790 }
791
792 // FIXME: Remove.
793 bool Internals::attached(Node* node, ExceptionCode& ec)
794 {
795     if (!node) {
796         ec = INVALID_ACCESS_ERR;
797         return false;
798     }
799
800     return true;
801 }
802
803 String Internals::elementRenderTreeAsText(Element* element, ExceptionCode& ec)
804 {
805     if (!element) {
806         ec = INVALID_ACCESS_ERR;
807         return String();
808     }
809
810     element->document().updateStyleIfNeeded();
811
812     String representation = externalRepresentation(element);
813     if (representation.isEmpty()) {
814         ec = INVALID_ACCESS_ERR;
815         return String();
816     }
817
818     return representation;
819 }
820
821 bool Internals::hasPausedImageAnimations(Element* element, ExceptionCode& ec)
822 {
823     if (!element) {
824         ec = INVALID_ACCESS_ERR;
825         return false;
826     }
827     return element->renderer() && element->renderer()->hasPausedImageAnimations();
828 }
829
830 RefPtr<CSSComputedStyleDeclaration> Internals::computedStyleIncludingVisitedInfo(Node* node, ExceptionCode& ec) const
831 {
832     if (!node) {
833         ec = INVALID_ACCESS_ERR;
834         return nullptr;
835     }
836
837     bool allowVisitedStyle = true;
838     return CSSComputedStyleDeclaration::create(node, allowVisitedStyle);
839 }
840
841 Node* Internals::ensureShadowRoot(Element* host, ExceptionCode& ec)
842 {
843     if (!host) {
844         ec = INVALID_ACCESS_ERR;
845         return 0;
846     }
847
848     if (ShadowRoot* shadowRoot = host->shadowRoot())
849         return shadowRoot;
850
851     return host->createShadowRoot(ec).get();
852 }
853
854 Node* Internals::ensureUserAgentShadowRoot(Element* host, ExceptionCode& ec)
855 {
856     if (!host) {
857         ec = INVALID_ACCESS_ERR;
858         return nullptr;
859     }
860     return &host->ensureUserAgentShadowRoot();
861 }
862
863 Node* Internals::createShadowRoot(Element* host, ExceptionCode& ec)
864 {
865     if (!host) {
866         ec = INVALID_ACCESS_ERR;
867         return 0;
868     }
869     return host->createShadowRoot(ec).get();
870 }
871
872 Node* Internals::shadowRoot(Element* host, ExceptionCode& ec)
873 {
874     if (!host) {
875         ec = INVALID_ACCESS_ERR;
876         return nullptr;
877     }
878     return host->shadowRoot();
879 }
880
881 String Internals::shadowRootType(const Node* root, ExceptionCode& ec) const
882 {
883     if (!is<ShadowRoot>(root)) {
884         ec = INVALID_ACCESS_ERR;
885         return String();
886     }
887
888     switch (downcast<ShadowRoot>(*root).type()) {
889     case ShadowRoot::Type::UserAgent:
890         return String("UserAgentShadowRoot");
891     case ShadowRoot::Type::Closed:
892         return String("ClosedShadowRoot");
893     case ShadowRoot::Type::Open:
894         return String("OpenShadowRoot");
895     default:
896         ASSERT_NOT_REACHED();
897         return String("Unknown");
898     }
899 }
900
901 Element* Internals::includerFor(Node*, ExceptionCode& ec)
902 {
903     ec = INVALID_ACCESS_ERR;
904     return nullptr;
905 }
906
907 String Internals::shadowPseudoId(Element* element, ExceptionCode& ec)
908 {
909     if (!element) {
910         ec = INVALID_ACCESS_ERR;
911         return String();
912     }
913
914     return element->shadowPseudoId().string();
915 }
916
917 void Internals::setShadowPseudoId(Element* element, const String& id, ExceptionCode& ec)
918 {
919     if (!element) {
920         ec = INVALID_ACCESS_ERR;
921         return;
922     }
923
924     return element->setPseudo(id);
925 }
926
927 bool Internals::isTimerThrottled(int timeoutId, ExceptionCode& ec)
928 {
929     DOMTimer* timer = scriptExecutionContext()->findTimeout(timeoutId);
930     if (!timer) {
931         ec = NOT_FOUND_ERR;
932         return false;
933     }
934     return timer->m_throttleState == DOMTimer::ShouldThrottle;
935 }
936
937 bool Internals::isRequestAnimationFrameThrottled() const
938 {
939 #if ENABLE(REQUEST_ANIMATION_FRAME)
940     auto* scriptedAnimationController = contextDocument()->scriptedAnimationController();
941     if (!scriptedAnimationController)
942         return false;
943     return scriptedAnimationController->isThrottled();
944 #else
945     return false;
946 #endif
947 }
948
949 bool Internals::areTimersThrottled() const
950 {
951     return contextDocument()->isTimerThrottlingEnabled();
952 }
953
954 String Internals::visiblePlaceholder(Element* element)
955 {
956     if (is<HTMLTextFormControlElement>(element)) {
957         const HTMLTextFormControlElement& textFormControlElement = downcast<HTMLTextFormControlElement>(*element);
958         if (!textFormControlElement.isPlaceholderVisible())
959             return String();
960         if (HTMLElement* placeholderElement = textFormControlElement.placeholderElement())
961             return placeholderElement->textContent();
962     }
963
964     return String();
965 }
966
967 void Internals::selectColorInColorChooser(Element* element, const String& colorValue)
968 {
969     if (!is<HTMLInputElement>(element))
970         return;
971     auto& inputElement = downcast<HTMLInputElement>(*element);
972     inputElement.selectColor(Color(colorValue));
973 }
974
975 Vector<String> Internals::formControlStateOfPreviousHistoryItem(ExceptionCode& ec)
976 {
977     HistoryItem* mainItem = frame()->loader().history().previousItem();
978     if (!mainItem) {
979         ec = INVALID_ACCESS_ERR;
980         return Vector<String>();
981     }
982     String uniqueName = frame()->tree().uniqueName();
983     if (mainItem->target() != uniqueName && !mainItem->childItemWithTarget(uniqueName)) {
984         ec = INVALID_ACCESS_ERR;
985         return Vector<String>();
986     }
987     return mainItem->target() == uniqueName ? mainItem->documentState() : mainItem->childItemWithTarget(uniqueName)->documentState();
988 }
989
990 void Internals::setFormControlStateOfPreviousHistoryItem(const Vector<String>& state, ExceptionCode& ec)
991 {
992     HistoryItem* mainItem = frame()->loader().history().previousItem();
993     if (!mainItem) {
994         ec = INVALID_ACCESS_ERR;
995         return;
996     }
997     String uniqueName = frame()->tree().uniqueName();
998     if (mainItem->target() == uniqueName)
999         mainItem->setDocumentState(state);
1000     else if (HistoryItem* subItem = mainItem->childItemWithTarget(uniqueName))
1001         subItem->setDocumentState(state);
1002     else
1003         ec = INVALID_ACCESS_ERR;
1004 }
1005
1006 #if ENABLE(SPEECH_SYNTHESIS)
1007 void Internals::enableMockSpeechSynthesizer()
1008 {
1009     Document* document = contextDocument();
1010     if (!document || !document->domWindow())
1011         return;
1012     SpeechSynthesis* synthesis = DOMWindowSpeechSynthesis::speechSynthesis(*document->domWindow());
1013     if (!synthesis)
1014         return;
1015     
1016     synthesis->setPlatformSynthesizer(std::make_unique<PlatformSpeechSynthesizerMock>(synthesis));
1017 }
1018 #endif
1019
1020 #if ENABLE(MEDIA_STREAM)
1021 void Internals::enableMockMediaEndpoint()
1022 {
1023     MediaEndpoint::create = MockMediaEndpoint::create;
1024 }
1025
1026 void Internals::enableMockRTCPeerConnectionHandler()
1027 {
1028     RTCPeerConnectionHandler::create = RTCPeerConnectionHandlerMock::create;
1029 }
1030
1031 void Internals::setMockMediaCaptureDevicesEnabled(bool enabled)
1032 {
1033     WebCore::Settings::setMockCaptureDevicesEnabled(enabled);
1034 }
1035 #endif
1036
1037 Ref<ClientRect> Internals::absoluteCaretBounds(ExceptionCode& ec)
1038 {
1039     Document* document = contextDocument();
1040     if (!document || !document->frame()) {
1041         ec = INVALID_ACCESS_ERR;
1042         return ClientRect::create();
1043     }
1044
1045     return ClientRect::create(document->frame()->selection().absoluteCaretBounds());
1046 }
1047
1048 Ref<ClientRect> Internals::boundingBox(Element* element, ExceptionCode& ec)
1049 {
1050     if (!element) {
1051         ec = INVALID_ACCESS_ERR;
1052         return ClientRect::create();
1053     }
1054
1055     element->document().updateLayoutIgnorePendingStylesheets();
1056     auto renderer = element->renderer();
1057     if (!renderer)
1058         return ClientRect::create();
1059     return ClientRect::create(renderer->absoluteBoundingBoxRectIgnoringTransforms());
1060 }
1061
1062 Ref<ClientRectList> Internals::inspectorHighlightRects(ExceptionCode& ec)
1063 {
1064     Document* document = contextDocument();
1065     if (!document || !document->page()) {
1066         ec = INVALID_ACCESS_ERR;
1067         return ClientRectList::create();
1068     }
1069
1070     Highlight highlight;
1071     document->page()->inspectorController().getHighlight(highlight, InspectorOverlay::CoordinateSystem::View);
1072     return ClientRectList::create(highlight.quads);
1073 }
1074
1075 String Internals::inspectorHighlightObject(ExceptionCode& ec)
1076 {
1077     Document* document = contextDocument();
1078     if (!document || !document->page()) {
1079         ec = INVALID_ACCESS_ERR;
1080         return String();
1081     }
1082
1083     return document->page()->inspectorController().buildObjectForHighlightedNodes()->toJSONString();
1084 }
1085
1086 unsigned Internals::markerCountForNode(Node* node, const String& markerType, ExceptionCode& ec)
1087 {
1088     if (!node) {
1089         ec = INVALID_ACCESS_ERR;
1090         return 0;
1091     }
1092
1093     DocumentMarker::MarkerTypes markerTypes = 0;
1094     if (!markerTypesFrom(markerType, markerTypes)) {
1095         ec = SYNTAX_ERR;
1096         return 0;
1097     }
1098
1099     node->document().frame()->editor().updateEditorUINowIfScheduled();
1100
1101     return node->document().markers().markersFor(node, markerTypes).size();
1102 }
1103
1104 RenderedDocumentMarker* Internals::markerAt(Node* node, const String& markerType, unsigned index, ExceptionCode& ec)
1105 {
1106     node->document().updateLayoutIgnorePendingStylesheets();
1107     if (!node) {
1108         ec = INVALID_ACCESS_ERR;
1109         return nullptr;
1110     }
1111
1112     DocumentMarker::MarkerTypes markerTypes = 0;
1113     if (!markerTypesFrom(markerType, markerTypes)) {
1114         ec = SYNTAX_ERR;
1115         return nullptr;
1116     }
1117
1118     node->document().frame()->editor().updateEditorUINowIfScheduled();
1119
1120     Vector<RenderedDocumentMarker*> markers = node->document().markers().markersFor(node, markerTypes);
1121     if (markers.size() <= index)
1122         return nullptr;
1123     return markers[index];
1124 }
1125
1126 RefPtr<Range> Internals::markerRangeForNode(Node* node, const String& markerType, unsigned index, ExceptionCode& ec)
1127 {
1128     RenderedDocumentMarker* marker = markerAt(node, markerType, index, ec);
1129     if (!marker)
1130         return nullptr;
1131     return Range::create(node->document(), node, marker->startOffset(), node, marker->endOffset());
1132 }
1133
1134 String Internals::markerDescriptionForNode(Node* node, const String& markerType, unsigned index, ExceptionCode& ec)
1135 {
1136     RenderedDocumentMarker* marker = markerAt(node, markerType, index, ec);
1137     if (!marker)
1138         return String();
1139     return marker->description();
1140 }
1141
1142 String Internals::dumpMarkerRects(const String& markerTypeString, ExceptionCode& ec)
1143 {
1144     DocumentMarker::MarkerType markerType;
1145     if (!markerTypeFrom(markerTypeString, markerType)) {
1146         ec = SYNTAX_ERR;
1147         return String();
1148     }
1149
1150     contextDocument()->markers().updateRectsForInvalidatedMarkersOfType(markerType);
1151     auto rects = contextDocument()->markers().renderedRectsForMarkers(markerType);
1152
1153     StringBuilder rectString;
1154     rectString.appendLiteral("marker rects: ");
1155     for (const auto& rect : rects) {
1156         rectString.append('(');
1157         rectString.appendNumber(rect.x());
1158         rectString.appendLiteral(", ");
1159         rectString.appendNumber(rect.y());
1160         rectString.appendLiteral(", ");
1161         rectString.appendNumber(rect.width());
1162         rectString.appendLiteral(", ");
1163         rectString.appendNumber(rect.height());
1164         rectString.appendLiteral(") ");
1165     }
1166     return rectString.toString();
1167 }
1168
1169 void Internals::addTextMatchMarker(const Range* range, bool isActive)
1170 {
1171     range->ownerDocument().updateLayoutIgnorePendingStylesheets();
1172     range->ownerDocument().markers().addTextMatchMarker(range, isActive);
1173 }
1174
1175 void Internals::setMarkedTextMatchesAreHighlighted(bool flag, ExceptionCode& ec)
1176 {
1177     Document* document = contextDocument();
1178     if (!document || !document->frame()) {
1179         ec = INVALID_ACCESS_ERR;
1180         return;
1181     }
1182     document->frame()->editor().setMarkedTextMatchesAreHighlighted(flag);
1183 }
1184
1185 void Internals::invalidateFontCache()
1186 {
1187     FontCache::singleton().invalidate();
1188 }
1189
1190 void Internals::setScrollViewPosition(long x, long y, ExceptionCode& ec)
1191 {
1192     Document* document = contextDocument();
1193     if (!document || !document->view()) {
1194         ec = INVALID_ACCESS_ERR;
1195         return;
1196     }
1197
1198     FrameView* frameView = document->view();
1199     bool constrainsScrollingToContentEdgeOldValue = frameView->constrainsScrollingToContentEdge();
1200     bool scrollbarsSuppressedOldValue = frameView->scrollbarsSuppressed();
1201
1202     frameView->setConstrainsScrollingToContentEdge(false);
1203     frameView->setScrollbarsSuppressed(false);
1204     frameView->setScrollOffsetFromInternals(IntPoint(x, y));
1205     frameView->setScrollbarsSuppressed(scrollbarsSuppressedOldValue);
1206     frameView->setConstrainsScrollingToContentEdge(constrainsScrollingToContentEdgeOldValue);
1207 }
1208
1209 void Internals::setViewBaseBackgroundColor(const String& colorValue, ExceptionCode& ec)
1210 {
1211     Document* document = contextDocument();
1212     if (!document || !document->view()) {
1213         ec = INVALID_ACCESS_ERR;
1214         return;
1215     }
1216
1217     document->view()->setBaseBackgroundColor(Color(colorValue));
1218 }
1219
1220 void Internals::setPagination(const String& mode, int gap, int pageLength, ExceptionCode& ec)
1221 {
1222     Document* document = contextDocument();
1223     if (!document || !document->page()) {
1224         ec = INVALID_ACCESS_ERR;
1225         return;
1226     }
1227     Page* page = document->page();
1228
1229     Pagination pagination;
1230     if (mode == "Unpaginated")
1231         pagination.mode = Pagination::Unpaginated;
1232     else if (mode == "LeftToRightPaginated")
1233         pagination.mode = Pagination::LeftToRightPaginated;
1234     else if (mode == "RightToLeftPaginated")
1235         pagination.mode = Pagination::RightToLeftPaginated;
1236     else if (mode == "TopToBottomPaginated")
1237         pagination.mode = Pagination::TopToBottomPaginated;
1238     else if (mode == "BottomToTopPaginated")
1239         pagination.mode = Pagination::BottomToTopPaginated;
1240     else {
1241         ec = SYNTAX_ERR;
1242         return;
1243     }
1244
1245     pagination.gap = gap;
1246     pagination.pageLength = pageLength;
1247     page->setPagination(pagination);
1248 }
1249
1250 void Internals::setPaginationLineGridEnabled(bool enabled, ExceptionCode& ec)
1251 {
1252     Document* document = contextDocument();
1253     if (!document || !document->page()) {
1254         ec = INVALID_ACCESS_ERR;
1255         return;
1256     }
1257     Page* page = document->page();
1258     page->setPaginationLineGridEnabled(enabled);
1259 }
1260
1261 String Internals::configurationForViewport(float devicePixelRatio, int deviceWidth, int deviceHeight, int availableWidth, int availableHeight, ExceptionCode& ec)
1262 {
1263     Document* document = contextDocument();
1264     if (!document || !document->page()) {
1265         ec = INVALID_ACCESS_ERR;
1266         return String();
1267     }
1268     Page* page = document->page();
1269
1270     const int defaultLayoutWidthForNonMobilePages = 980;
1271
1272     ViewportArguments arguments = page->viewportArguments();
1273     ViewportAttributes attributes = computeViewportAttributes(arguments, defaultLayoutWidthForNonMobilePages, deviceWidth, deviceHeight, devicePixelRatio, IntSize(availableWidth, availableHeight));
1274     restrictMinimumScaleFactorToViewportSize(attributes, IntSize(availableWidth, availableHeight), devicePixelRatio);
1275     restrictScaleFactorToInitialScaleIfNotUserScalable(attributes);
1276
1277     return "viewport size " + String::number(attributes.layoutSize.width()) + "x" + String::number(attributes.layoutSize.height()) + " scale " + String::number(attributes.initialScale) + " with limits [" + String::number(attributes.minimumScale) + ", " + String::number(attributes.maximumScale) + "] and userScalable " + (attributes.userScalable ? "true" : "false");
1278 }
1279
1280 bool Internals::wasLastChangeUserEdit(Element* textField, ExceptionCode& ec)
1281 {
1282     if (!textField) {
1283         ec = INVALID_ACCESS_ERR;
1284         return false;
1285     }
1286
1287     if (is<HTMLInputElement>(*textField))
1288         return downcast<HTMLInputElement>(*textField).lastChangeWasUserEdit();
1289
1290     if (is<HTMLTextAreaElement>(*textField))
1291         return downcast<HTMLTextAreaElement>(*textField).lastChangeWasUserEdit();
1292
1293     ec = INVALID_NODE_TYPE_ERR;
1294     return false;
1295 }
1296
1297 bool Internals::elementShouldAutoComplete(Element* element, ExceptionCode& ec)
1298 {
1299     if (!element) {
1300         ec = INVALID_ACCESS_ERR;
1301         return false;
1302     }
1303
1304     if (!is<HTMLInputElement>(*element)) {
1305         ec = INVALID_NODE_TYPE_ERR;
1306         return false;
1307     }
1308
1309     return downcast<HTMLInputElement>(*element).shouldAutocomplete();
1310 }
1311
1312 void Internals::setEditingValue(Element* element, const String& value, ExceptionCode& ec)
1313 {
1314     if (!element) {
1315         ec = INVALID_ACCESS_ERR;
1316         return;
1317     }
1318
1319     if (!is<HTMLInputElement>(*element)) {
1320         ec = INVALID_NODE_TYPE_ERR;
1321         return;
1322     }
1323
1324     downcast<HTMLInputElement>(*element).setEditingValue(value);
1325 }
1326
1327 void Internals::setAutofilled(Element* element, bool enabled, ExceptionCode& ec)
1328 {
1329     if (!element) {
1330         ec = INVALID_ACCESS_ERR;
1331         return;
1332     }
1333
1334     if (!is<HTMLInputElement>(*element)) {
1335         ec = INVALID_NODE_TYPE_ERR;
1336         return;
1337     }
1338
1339     downcast<HTMLInputElement>(*element).setAutoFilled(enabled);
1340 }
1341
1342 static AutoFillButtonType stringToAutoFillButtonType(const String& autoFillButtonType)
1343 {
1344     if (autoFillButtonType == "AutoFillButtonTypeNone")
1345         return AutoFillButtonType::None;
1346     if (autoFillButtonType == "AutoFillButtonTypeCredentials")
1347         return AutoFillButtonType::Credentials;
1348     if (autoFillButtonType == "AutoFillButtonTypeContacts")
1349         return AutoFillButtonType::Contacts;
1350     ASSERT_NOT_REACHED();
1351     return AutoFillButtonType::None;
1352 }
1353
1354 void Internals::setShowAutoFillButton(Element* element, const String& autoFillButtonType, ExceptionCode& ec)
1355 {
1356     if (!element) {
1357         ec = INVALID_ACCESS_ERR;
1358         return;
1359     }
1360
1361     if (!is<HTMLInputElement>(*element)) {
1362         ec = INVALID_NODE_TYPE_ERR;
1363         return;
1364     }
1365
1366     downcast<HTMLInputElement>(*element).setShowAutoFillButton(stringToAutoFillButtonType(autoFillButtonType));
1367 }
1368
1369
1370 void Internals::scrollElementToRect(Element* element, long x, long y, long w, long h, ExceptionCode& ec)
1371 {
1372     if (!element || !element->document().view()) {
1373         ec = INVALID_ACCESS_ERR;
1374         return;
1375     }
1376     FrameView* frameView = element->document().view();
1377     frameView->scrollElementToRect(*element, IntRect(x, y, w, h));
1378 }
1379
1380 String Internals::autofillFieldName(Element* element, ExceptionCode& ec)
1381 {
1382     if (!element) {
1383         ec = INVALID_ACCESS_ERR;
1384         return { };
1385     }
1386
1387     if (!is<HTMLFormControlElement>(*element)) {
1388         ec = INVALID_NODE_TYPE_ERR;
1389         return { };
1390     }
1391
1392     return downcast<HTMLFormControlElement>(*element).autofillData().fieldName;
1393 }
1394
1395 void Internals::paintControlTints(ExceptionCode& ec)
1396 {
1397     Document* document = contextDocument();
1398     if (!document || !document->view()) {
1399         ec = INVALID_ACCESS_ERR;
1400         return;
1401     }
1402
1403     FrameView* frameView = document->view();
1404     frameView->paintControlTints();
1405 }
1406
1407 RefPtr<Range> Internals::rangeFromLocationAndLength(Element* scope, int rangeLocation, int rangeLength, ExceptionCode& ec)
1408 {
1409     if (!scope) {
1410         ec = INVALID_ACCESS_ERR;
1411         return nullptr;
1412     }
1413
1414     return TextIterator::rangeFromLocationAndLength(scope, rangeLocation, rangeLength);
1415 }
1416
1417 unsigned Internals::locationFromRange(Element* scope, const Range* range, ExceptionCode& ec)
1418 {
1419     if (!scope || !range) {
1420         ec = INVALID_ACCESS_ERR;
1421         return 0;
1422     }
1423
1424     size_t location = 0;
1425     size_t unusedLength = 0;
1426     TextIterator::getLocationAndLengthFromRange(scope, range, location, unusedLength);
1427     return location;
1428 }
1429
1430 unsigned Internals::lengthFromRange(Element* scope, const Range* range, ExceptionCode& ec)
1431 {
1432     if (!scope || !range) {
1433         ec = INVALID_ACCESS_ERR;
1434         return 0;
1435     }
1436
1437     size_t unusedLocation = 0;
1438     size_t length = 0;
1439     TextIterator::getLocationAndLengthFromRange(scope, range, unusedLocation, length);
1440     return length;
1441 }
1442
1443 String Internals::rangeAsText(const Range* range, ExceptionCode& ec)
1444 {
1445     if (!range) {
1446         ec = INVALID_ACCESS_ERR;
1447         return String();
1448     }
1449
1450     return range->text();
1451 }
1452
1453 RefPtr<Range> Internals::subrange(Range* range, int rangeLocation, int rangeLength, ExceptionCode& ec)
1454 {
1455     if (!range) {
1456         ec = INVALID_ACCESS_ERR;
1457         return nullptr;
1458     }
1459
1460     return TextIterator::subrange(range, rangeLocation, rangeLength);
1461 }
1462
1463 RefPtr<Range> Internals::rangeForDictionaryLookupAtLocation(int x, int y, ExceptionCode& ec)
1464 {
1465 #if PLATFORM(MAC)
1466     Document* document = contextDocument();
1467     if (!document || !document->frame()) {
1468         ec = INVALID_ACCESS_ERR;
1469         return nullptr;
1470     }
1471
1472     document->updateLayoutIgnorePendingStylesheets();
1473     
1474     HitTestResult result = document->frame()->mainFrame().eventHandler().hitTestResultAtPoint(IntPoint(x, y));
1475     NSDictionary *options = nullptr;
1476     return DictionaryLookup::rangeAtHitTestResult(result, &options);
1477 #else
1478     UNUSED_PARAM(x);
1479     UNUSED_PARAM(y);
1480     ec = INVALID_ACCESS_ERR;
1481     return nullptr;
1482 #endif
1483 }
1484
1485 void Internals::setDelegatesScrolling(bool enabled, ExceptionCode& ec)
1486 {
1487     Document* document = contextDocument();
1488     // Delegate scrolling is valid only on mainframe's view.
1489     if (!document || !document->view() || !document->page() || &document->page()->mainFrame() != document->frame()) {
1490         ec = INVALID_ACCESS_ERR;
1491         return;
1492     }
1493
1494     document->view()->setDelegatesScrolling(enabled);
1495 }
1496
1497 int Internals::lastSpellCheckRequestSequence(ExceptionCode& ec)
1498 {
1499     Document* document = contextDocument();
1500     if (!document || !document->frame()) {
1501         ec = INVALID_ACCESS_ERR;
1502         return -1;
1503     }
1504
1505     return document->frame()->editor().spellChecker().lastRequestSequence();
1506 }
1507
1508 int Internals::lastSpellCheckProcessedSequence(ExceptionCode& ec)
1509 {
1510     Document* document = contextDocument();
1511     if (!document || !document->frame()) {
1512         ec = INVALID_ACCESS_ERR;
1513         return -1;
1514     }
1515
1516     return document->frame()->editor().spellChecker().lastProcessedSequence();
1517 }
1518
1519 Vector<String> Internals::userPreferredLanguages() const
1520 {
1521     return WebCore::userPreferredLanguages();
1522 }
1523
1524 void Internals::setUserPreferredLanguages(const Vector<String>& languages)
1525 {
1526     WebCore::overrideUserPreferredLanguages(languages);
1527 }
1528
1529 Vector<String> Internals::userPreferredAudioCharacteristics() const
1530 {
1531     Document* document = contextDocument();
1532     if (!document || !document->page())
1533         return Vector<String>();
1534 #if ENABLE(VIDEO_TRACK)
1535     return document->page()->group().captionPreferences().preferredAudioCharacteristics();
1536 #else
1537     return Vector<String>();
1538 #endif
1539 }
1540
1541 void Internals::setUserPreferredAudioCharacteristic(const String& characteristic)
1542 {
1543     Document* document = contextDocument();
1544     if (!document || !document->page())
1545         return;
1546 #if ENABLE(VIDEO_TRACK)
1547     document->page()->group().captionPreferences().setPreferredAudioCharacteristic(characteristic);
1548 #else
1549     UNUSED_PARAM(characteristic);
1550 #endif
1551 }
1552
1553 unsigned Internals::wheelEventHandlerCount(ExceptionCode& ec)
1554 {
1555     Document* document = contextDocument();
1556     if (!document) {
1557         ec = INVALID_ACCESS_ERR;
1558         return 0;
1559     }
1560
1561     return document->wheelEventHandlerCount();
1562 }
1563
1564 unsigned Internals::touchEventHandlerCount(ExceptionCode& ec)
1565 {
1566     Document* document = contextDocument();
1567     if (!document) {
1568         ec = INVALID_ACCESS_ERR;
1569         return 0;
1570     }
1571
1572     return document->touchEventHandlerCount();
1573 }
1574
1575 // FIXME: Remove the document argument. It is almost always the same as
1576 // contextDocument(), with the exception of a few tests that pass a
1577 // different document, and could just make the call through another Internals
1578 // instance instead.
1579 RefPtr<NodeList> Internals::nodesFromRect(Document* document, int centerX, int centerY, unsigned topPadding, unsigned rightPadding,
1580     unsigned bottomPadding, unsigned leftPadding, bool ignoreClipping, bool allowShadowContent, bool allowChildFrameContent, ExceptionCode& ec) const
1581 {
1582     if (!document || !document->frame() || !document->frame()->view()) {
1583         ec = INVALID_ACCESS_ERR;
1584         return nullptr;
1585     }
1586
1587     Frame* frame = document->frame();
1588     FrameView* frameView = document->view();
1589     RenderView* renderView = document->renderView();
1590     if (!renderView)
1591         return nullptr;
1592
1593     document->updateLayoutIgnorePendingStylesheets();
1594
1595     float zoomFactor = frame->pageZoomFactor();
1596     LayoutPoint point(centerX * zoomFactor + frameView->scrollX(), centerY * zoomFactor + frameView->scrollY());
1597
1598     HitTestRequest::HitTestRequestType hitType = HitTestRequest::ReadOnly | HitTestRequest::Active;
1599     if (ignoreClipping)
1600         hitType |= HitTestRequest::IgnoreClipping;
1601     if (!allowShadowContent)
1602         hitType |= HitTestRequest::DisallowShadowContent;
1603     if (allowChildFrameContent)
1604         hitType |= HitTestRequest::AllowChildFrameContent;
1605
1606     HitTestRequest request(hitType);
1607
1608     // When ignoreClipping is false, this method returns null for coordinates outside of the viewport.
1609     if (!request.ignoreClipping() && !frameView->visibleContentRect().intersects(HitTestLocation::rectForPoint(point, topPadding, rightPadding, bottomPadding, leftPadding)))
1610         return nullptr;
1611
1612     Vector<Ref<Node>> matches;
1613
1614     // Need padding to trigger a rect based hit test, but we want to return a NodeList
1615     // so we special case this.
1616     if (!topPadding && !rightPadding && !bottomPadding && !leftPadding) {
1617         HitTestResult result(point);
1618         renderView->hitTest(request, result);
1619         if (result.innerNode())
1620             matches.append(*result.innerNode()->deprecatedShadowAncestorNode());
1621     } else {
1622         HitTestResult result(point, topPadding, rightPadding, bottomPadding, leftPadding);
1623         renderView->hitTest(request, result);
1624         
1625         const HitTestResult::NodeSet& nodeSet = result.rectBasedTestResult();
1626         matches.reserveInitialCapacity(nodeSet.size());
1627         for (auto& node : nodeSet)
1628             matches.uncheckedAppend(*node);
1629     }
1630
1631     return StaticNodeList::adopt(matches);
1632 }
1633
1634 class GetCallerCodeBlockFunctor {
1635 public:
1636     GetCallerCodeBlockFunctor()
1637         : m_iterations(0)
1638         , m_codeBlock(0)
1639     {
1640     }
1641
1642     StackVisitor::Status operator()(StackVisitor& visitor)
1643     {
1644         ++m_iterations;
1645         if (m_iterations < 2)
1646             return StackVisitor::Continue;
1647
1648         m_codeBlock = visitor->codeBlock();
1649         return StackVisitor::Done;
1650     }
1651
1652     CodeBlock* codeBlock() const { return m_codeBlock; }
1653
1654 private:
1655     int m_iterations;
1656     CodeBlock* m_codeBlock;
1657 };
1658
1659 String Internals::parserMetaData(Deprecated::ScriptValue value)
1660 {
1661     JSC::VM& vm = contextDocument()->vm();
1662     JSC::ExecState* exec = vm.topCallFrame;
1663     JSC::JSValue code = value.jsValue();
1664     ScriptExecutable* executable;
1665
1666     if (!code || code.isNull() || code.isUndefined()) {
1667         GetCallerCodeBlockFunctor iter;
1668         exec->iterate(iter);
1669         CodeBlock* codeBlock = iter.codeBlock();
1670         executable = codeBlock->ownerScriptExecutable();
1671     } else if (code.isFunction()) {
1672         JSFunction* funcObj = JSC::jsCast<JSFunction*>(code.toObject(exec));
1673         executable = funcObj->jsExecutable();
1674     } else
1675         return String();
1676
1677     unsigned startLine = executable->firstLine();
1678     unsigned startColumn = executable->startColumn();
1679     unsigned endLine = executable->lastLine();
1680     unsigned endColumn = executable->endColumn();
1681
1682     StringBuilder result;
1683
1684     if (executable->isFunctionExecutable()) {
1685         FunctionExecutable* funcExecutable = reinterpret_cast<FunctionExecutable*>(executable);
1686         String inferredName = funcExecutable->inferredName().string();
1687         result.appendLiteral("function \"");
1688         result.append(inferredName);
1689         result.append('"');
1690     } else if (executable->isEvalExecutable())
1691         result.appendLiteral("eval");
1692     else if (executable->isModuleProgramExecutable())
1693         result.appendLiteral("module");
1694     else if (executable->isProgramExecutable())
1695         result.appendLiteral("program");
1696 #if ENABLE(WEBASSEMBLY)
1697     else if (executable->isWebAssemblyExecutable())
1698         result.appendLiteral("WebAssembly");
1699 #endif
1700     else
1701         ASSERT_NOT_REACHED();
1702
1703     result.appendLiteral(" { ");
1704     result.appendNumber(startLine);
1705     result.append(':');
1706     result.appendNumber(startColumn);
1707     result.appendLiteral(" - ");
1708     result.appendNumber(endLine);
1709     result.append(':');
1710     result.appendNumber(endColumn);
1711     result.appendLiteral(" }");
1712
1713     return result.toString();
1714 }
1715
1716 void Internals::setBatteryStatus(const String& eventType, bool charging, double chargingTime, double dischargingTime, double level, ExceptionCode& ec)
1717 {
1718     Document* document = contextDocument();
1719     if (!document || !document->page()) {
1720         ec = INVALID_ACCESS_ERR;
1721         return;
1722     }
1723
1724 #if ENABLE(BATTERY_STATUS)
1725     BatteryController::from(document->page())->didChangeBatteryStatus(eventType, BatteryStatus::create(charging, chargingTime, dischargingTime, level));
1726 #else
1727     UNUSED_PARAM(eventType);
1728     UNUSED_PARAM(charging);
1729     UNUSED_PARAM(chargingTime);
1730     UNUSED_PARAM(dischargingTime);
1731     UNUSED_PARAM(level);
1732 #endif
1733 }
1734
1735 void Internals::setDeviceProximity(const String& eventType, double value, double min, double max, ExceptionCode& ec)
1736 {
1737     Document* document = contextDocument();
1738     if (!document || !document->page()) {
1739         ec = INVALID_ACCESS_ERR;
1740         return;
1741     }
1742
1743 #if ENABLE(PROXIMITY_EVENTS)
1744     DeviceProximityController::from(document->page())->didChangeDeviceProximity(value, min, max);
1745 #else
1746     UNUSED_PARAM(eventType);
1747     UNUSED_PARAM(value);
1748     UNUSED_PARAM(min);
1749     UNUSED_PARAM(max);
1750 #endif
1751 }
1752
1753 void Internals::updateEditorUINowIfScheduled()
1754 {
1755     if (Document* document = contextDocument()) {
1756         if (Frame* frame = document->frame())
1757             frame->editor().updateEditorUINowIfScheduled();
1758     }
1759 }
1760
1761 bool Internals::hasSpellingMarker(int from, int length, ExceptionCode&)
1762 {
1763     Document* document = contextDocument();
1764     if (!document || !document->frame())
1765         return false;
1766
1767     updateEditorUINowIfScheduled();
1768
1769     return document->frame()->editor().selectionStartHasMarkerFor(DocumentMarker::Spelling, from, length);
1770 }
1771     
1772 bool Internals::hasAutocorrectedMarker(int from, int length, ExceptionCode&)
1773 {
1774     Document* document = contextDocument();
1775     if (!document || !document->frame())
1776         return false;
1777
1778     updateEditorUINowIfScheduled();
1779
1780     return document->frame()->editor().selectionStartHasMarkerFor(DocumentMarker::Autocorrected, from, length);
1781 }
1782
1783 void Internals::setContinuousSpellCheckingEnabled(bool enabled, ExceptionCode&)
1784 {
1785     if (!contextDocument() || !contextDocument()->frame())
1786         return;
1787
1788     if (enabled != contextDocument()->frame()->editor().isContinuousSpellCheckingEnabled())
1789         contextDocument()->frame()->editor().toggleContinuousSpellChecking();
1790 }
1791
1792 void Internals::setAutomaticQuoteSubstitutionEnabled(bool enabled, ExceptionCode&)
1793 {
1794     if (!contextDocument() || !contextDocument()->frame())
1795         return;
1796
1797 #if USE(AUTOMATIC_TEXT_REPLACEMENT)
1798     if (enabled != contextDocument()->frame()->editor().isAutomaticQuoteSubstitutionEnabled())
1799         contextDocument()->frame()->editor().toggleAutomaticQuoteSubstitution();
1800 #else
1801     UNUSED_PARAM(enabled);
1802 #endif
1803 }
1804
1805 void Internals::setAutomaticLinkDetectionEnabled(bool enabled, ExceptionCode&)
1806 {
1807     if (!contextDocument() || !contextDocument()->frame())
1808         return;
1809
1810 #if USE(AUTOMATIC_TEXT_REPLACEMENT)
1811     if (enabled != contextDocument()->frame()->editor().isAutomaticLinkDetectionEnabled())
1812         contextDocument()->frame()->editor().toggleAutomaticLinkDetection();
1813 #else
1814     UNUSED_PARAM(enabled);
1815 #endif
1816 }
1817
1818 void Internals::setAutomaticDashSubstitutionEnabled(bool enabled, ExceptionCode&)
1819 {
1820     if (!contextDocument() || !contextDocument()->frame())
1821         return;
1822
1823 #if USE(AUTOMATIC_TEXT_REPLACEMENT)
1824     if (enabled != contextDocument()->frame()->editor().isAutomaticDashSubstitutionEnabled())
1825         contextDocument()->frame()->editor().toggleAutomaticDashSubstitution();
1826 #else
1827     UNUSED_PARAM(enabled);
1828 #endif
1829 }
1830
1831 void Internals::setAutomaticTextReplacementEnabled(bool enabled, ExceptionCode&)
1832 {
1833     if (!contextDocument() || !contextDocument()->frame())
1834         return;
1835
1836 #if USE(AUTOMATIC_TEXT_REPLACEMENT)
1837     if (enabled != contextDocument()->frame()->editor().isAutomaticTextReplacementEnabled())
1838         contextDocument()->frame()->editor().toggleAutomaticTextReplacement();
1839 #else
1840     UNUSED_PARAM(enabled);
1841 #endif
1842 }
1843
1844 void Internals::setAutomaticSpellingCorrectionEnabled(bool enabled, ExceptionCode&)
1845 {
1846     if (!contextDocument() || !contextDocument()->frame())
1847         return;
1848
1849 #if USE(AUTOMATIC_TEXT_REPLACEMENT)
1850     if (enabled != contextDocument()->frame()->editor().isAutomaticSpellingCorrectionEnabled())
1851         contextDocument()->frame()->editor().toggleAutomaticSpellingCorrection();
1852 #else
1853     UNUSED_PARAM(enabled);
1854 #endif
1855 }
1856
1857 void Internals::handleAcceptedCandidate(const String& candidate, ExceptionCode&)
1858 {
1859     if (!contextDocument() || !contextDocument()->frame())
1860         return;
1861
1862     TextCheckingResult result;
1863     result.type = TextCheckingTypeNone;
1864     result.length = candidate.length();
1865     result.replacement = candidate;
1866     contextDocument()->frame()->editor().handleAcceptedCandidate(result);
1867 }
1868
1869 bool Internals::isOverwriteModeEnabled(ExceptionCode&)
1870 {
1871     Document* document = contextDocument();
1872     if (!document || !document->frame())
1873         return false;
1874
1875     return document->frame()->editor().isOverwriteModeEnabled();
1876 }
1877
1878 void Internals::toggleOverwriteModeEnabled(ExceptionCode&)
1879 {
1880     Document* document = contextDocument();
1881     if (!document || !document->frame())
1882         return;
1883
1884     document->frame()->editor().toggleOverwriteModeEnabled();
1885 }
1886
1887 unsigned Internals::countMatchesForText(const String& text, unsigned findOptions, const String& markMatches, ExceptionCode&)
1888 {
1889     Document* document = contextDocument();
1890     if (!document || !document->frame())
1891         return 0;
1892
1893     bool mark = markMatches == "mark";
1894     return document->frame()->editor().countMatchesForText(text, nullptr, findOptions, 1000, mark, nullptr);
1895 }
1896
1897 const ProfilesArray& Internals::consoleProfiles() const
1898 {
1899     return contextDocument()->page()->console().profiles();
1900 }
1901
1902 unsigned Internals::numberOfLiveNodes() const
1903 {
1904     unsigned nodeCount = 0;
1905     for (auto* document : Document::allDocuments())
1906         nodeCount += document->referencingNodeCount();
1907     return nodeCount;
1908 }
1909
1910 unsigned Internals::numberOfLiveDocuments() const
1911 {
1912     return Document::allDocuments().size();
1913 }
1914
1915 RefPtr<DOMWindow> Internals::openDummyInspectorFrontend(const String& url)
1916 {
1917     Page* inspectedPage = contextDocument()->frame()->page();
1918     RefPtr<DOMWindow> window = inspectedPage->mainFrame().document()->domWindow();
1919     RefPtr<DOMWindow> frontendWindow = window->open(url, "", "", *window, *window);
1920     m_inspectorFrontend = std::make_unique<InspectorStubFrontend>(inspectedPage, frontendWindow.copyRef());
1921
1922     return frontendWindow;
1923 }
1924
1925 void Internals::closeDummyInspectorFrontend()
1926 {
1927     m_inspectorFrontend = nullptr;
1928 }
1929
1930 void Internals::setLegacyJavaScriptProfilingEnabled(bool enabled, ExceptionCode& ec)
1931 {
1932     Page* page = contextDocument()->frame()->page();
1933     if (!page) {
1934         ec = INVALID_ACCESS_ERR;
1935         return;
1936     }
1937
1938     page->inspectorController().setLegacyProfilerEnabled(enabled);
1939 }
1940
1941 void Internals::setInspectorIsUnderTest(bool isUnderTest, ExceptionCode& ec)
1942 {
1943     Page* page = contextDocument()->frame()->page();
1944     if (!page) {
1945         ec = INVALID_ACCESS_ERR;
1946         return;
1947     }
1948
1949     page->inspectorController().setIsUnderTest(isUnderTest);
1950 }
1951
1952 bool Internals::hasGrammarMarker(int from, int length, ExceptionCode&)
1953 {
1954     Document* document = contextDocument();
1955     if (!document || !document->frame())
1956         return false;
1957
1958     return document->frame()->editor().selectionStartHasMarkerFor(DocumentMarker::Grammar, from, length);
1959 }
1960
1961 unsigned Internals::numberOfScrollableAreas(ExceptionCode&)
1962 {
1963     Document* document = contextDocument();
1964     if (!document || !document->frame())
1965         return 0;
1966
1967     unsigned count = 0;
1968     Frame* frame = document->frame();
1969     if (frame->view()->scrollableAreas())
1970         count += frame->view()->scrollableAreas()->size();
1971
1972     for (Frame* child = frame->tree().firstChild(); child; child = child->tree().nextSibling()) {
1973         if (child->view() && child->view()->scrollableAreas())
1974             count += child->view()->scrollableAreas()->size();
1975     }
1976
1977     return count;
1978 }
1979     
1980 bool Internals::isPageBoxVisible(int pageNumber, ExceptionCode& ec)
1981 {
1982     Document* document = contextDocument();
1983     if (!document) {
1984         ec = INVALID_ACCESS_ERR;
1985         return false;
1986     }
1987
1988     return document->isPageBoxVisible(pageNumber);
1989 }
1990
1991 // FIXME: Remove the document argument. It is almost always the same as
1992 // contextDocument(), with the exception of a few tests that pass a
1993 // different document, and could just make the call through another Internals
1994 // instance instead.
1995 String Internals::layerTreeAsText(Document* document, ExceptionCode& ec) const
1996 {
1997     return layerTreeAsText(document, 0, ec);
1998 }
1999
2000 String Internals::layerTreeAsText(Document* document, unsigned flags, ExceptionCode& ec) const
2001 {
2002     if (!document || !document->frame()) {
2003         ec = INVALID_ACCESS_ERR;
2004         return String();
2005     }
2006
2007     LayerTreeFlags layerTreeFlags = 0;
2008     if (flags & LAYER_TREE_INCLUDES_VISIBLE_RECTS)
2009         layerTreeFlags |= LayerTreeFlagsIncludeVisibleRects;
2010     if (flags & LAYER_TREE_INCLUDES_TILE_CACHES)
2011         layerTreeFlags |= LayerTreeFlagsIncludeTileCaches;
2012     if (flags & LAYER_TREE_INCLUDES_REPAINT_RECTS)
2013         layerTreeFlags |= LayerTreeFlagsIncludeRepaintRects;
2014     if (flags & LAYER_TREE_INCLUDES_PAINTING_PHASES)
2015         layerTreeFlags |= LayerTreeFlagsIncludePaintingPhases;
2016     if (flags & LAYER_TREE_INCLUDES_CONTENT_LAYERS)
2017         layerTreeFlags |= LayerTreeFlagsIncludeContentLayers;
2018
2019     return document->frame()->layerTreeAsText(layerTreeFlags);
2020 }
2021
2022 String Internals::repaintRectsAsText(ExceptionCode& ec) const
2023 {
2024     Document* document = contextDocument();
2025     if (!document || !document->frame()) {
2026         ec = INVALID_ACCESS_ERR;
2027         return String();
2028     }
2029
2030     return document->frame()->trackedRepaintRectsAsText();
2031 }
2032
2033 String Internals::scrollingStateTreeAsText(ExceptionCode& ec) const
2034 {
2035     Document* document = contextDocument();
2036     if (!document || !document->frame()) {
2037         ec = INVALID_ACCESS_ERR;
2038         return String();
2039     }
2040
2041     Page* page = document->page();
2042     if (!page)
2043         return String();
2044
2045     return page->scrollingStateTreeAsText();
2046 }
2047
2048 String Internals::mainThreadScrollingReasons(ExceptionCode& ec) const
2049 {
2050     Document* document = contextDocument();
2051     if (!document || !document->frame()) {
2052         ec = INVALID_ACCESS_ERR;
2053         return String();
2054     }
2055
2056     Page* page = document->page();
2057     if (!page)
2058         return String();
2059
2060     return page->synchronousScrollingReasonsAsText();
2061 }
2062
2063 RefPtr<ClientRectList> Internals::nonFastScrollableRects(ExceptionCode& ec) const
2064 {
2065     Document* document = contextDocument();
2066     if (!document || !document->frame()) {
2067         ec = INVALID_ACCESS_ERR;
2068         return nullptr;
2069     }
2070
2071     Page* page = document->page();
2072     if (!page)
2073         return nullptr;
2074
2075     return page->nonFastScrollableRects();
2076 }
2077
2078 void Internals::setElementUsesDisplayListDrawing(Element* element, bool usesDisplayListDrawing, ExceptionCode& ec)
2079 {
2080     Document* document = contextDocument();
2081     if (!document || !document->renderView()) {
2082         ec = INVALID_ACCESS_ERR;
2083         return;
2084     }
2085
2086     if (!element || !element->renderer()) {
2087         ec = INVALID_ACCESS_ERR;
2088         return;
2089     }
2090
2091     if (is<HTMLCanvasElement>(*element)) {
2092         downcast<HTMLCanvasElement>(*element).setUsesDisplayListDrawing(usesDisplayListDrawing);
2093         return;
2094     }
2095
2096     if (!element->renderer()->hasLayer()) {
2097         ec = INVALID_ACCESS_ERR;
2098         return;
2099     }
2100     
2101     RenderLayer* layer = downcast<RenderLayerModelObject>(element->renderer())->layer();
2102     if (!layer->isComposited()) {
2103         ec = INVALID_ACCESS_ERR;
2104         return;
2105     }
2106     
2107     layer->backing()->setUsesDisplayListDrawing(usesDisplayListDrawing);
2108 }
2109
2110 void Internals::setElementTracksDisplayListReplay(Element* element, bool isTrackingReplay, ExceptionCode& ec)
2111 {
2112     Document* document = contextDocument();
2113     if (!document || !document->renderView()) {
2114         ec = INVALID_ACCESS_ERR;
2115         return;
2116     }
2117
2118     if (!element || !element->renderer()) {
2119         ec = INVALID_ACCESS_ERR;
2120         return;
2121     }
2122
2123     if (is<HTMLCanvasElement>(*element)) {
2124         downcast<HTMLCanvasElement>(*element).setTracksDisplayListReplay(isTrackingReplay);
2125         return;
2126     }
2127
2128     if (!element->renderer()->hasLayer()) {
2129         ec = INVALID_ACCESS_ERR;
2130         return;
2131     }
2132
2133     RenderLayer* layer = downcast<RenderLayerModelObject>(element->renderer())->layer();
2134     if (!layer->isComposited()) {
2135         ec = INVALID_ACCESS_ERR;
2136         return;
2137     }
2138     
2139     layer->backing()->setIsTrackingDisplayListReplay(isTrackingReplay);
2140 }
2141
2142 String Internals::displayListForElement(Element* element, ExceptionCode& ec)
2143 {
2144     return displayListForElement(element, 0, ec);
2145 }
2146
2147 String Internals::displayListForElement(Element* element, unsigned flags, ExceptionCode& ec)
2148 {
2149     Document* document = contextDocument();
2150     if (!document || !document->renderView()) {
2151         ec = INVALID_ACCESS_ERR;
2152         return String();
2153     }
2154
2155     if (!element || !element->renderer()) {
2156         ec = INVALID_ACCESS_ERR;
2157         return String();
2158     }
2159
2160     DisplayList::AsTextFlags displayListFlags = 0;
2161     if (flags & DISPLAY_LIST_INCLUDES_PLATFORM_OPERATIONS)
2162         displayListFlags |= DisplayList::AsTextFlag::IncludesPlatformOperations;
2163
2164     if (is<HTMLCanvasElement>(*element))
2165         return downcast<HTMLCanvasElement>(*element).displayListAsText(displayListFlags);
2166
2167     if (!element->renderer()->hasLayer()) {
2168         ec = INVALID_ACCESS_ERR;
2169         return String();
2170     }
2171
2172     RenderLayer* layer = downcast<RenderLayerModelObject>(element->renderer())->layer();
2173     if (!layer->isComposited()) {
2174         ec = INVALID_ACCESS_ERR;
2175         return String();
2176     }
2177
2178     return layer->backing()->displayListAsText(displayListFlags);
2179 }
2180
2181 String Internals::replayDisplayListForElement(Element* element, ExceptionCode& ec)
2182 {
2183     return replayDisplayListForElement(element, 0, ec);
2184 }
2185
2186 String Internals::replayDisplayListForElement(Element* element, unsigned flags, ExceptionCode& ec)
2187 {
2188     Document* document = contextDocument();
2189     if (!document || !document->renderView()) {
2190         ec = INVALID_ACCESS_ERR;
2191         return String();
2192     }
2193
2194     if (!element || !element->renderer()) {
2195         ec = INVALID_ACCESS_ERR;
2196         return String();
2197     }
2198
2199     DisplayList::AsTextFlags displayListFlags = 0;
2200     if (flags & DISPLAY_LIST_INCLUDES_PLATFORM_OPERATIONS)
2201         displayListFlags |= DisplayList::AsTextFlag::IncludesPlatformOperations;
2202
2203     if (is<HTMLCanvasElement>(*element))
2204         return downcast<HTMLCanvasElement>(*element).replayDisplayListAsText(displayListFlags);
2205
2206     if (!element->renderer()->hasLayer()) {
2207         ec = INVALID_ACCESS_ERR;
2208         return String();
2209     }
2210
2211     RenderLayer* layer = downcast<RenderLayerModelObject>(element->renderer())->layer();
2212     if (!layer->isComposited()) {
2213         ec = INVALID_ACCESS_ERR;
2214         return String();
2215     }
2216
2217     return layer->backing()->replayDisplayListAsText(displayListFlags);
2218 }
2219
2220 void Internals::garbageCollectDocumentResources(ExceptionCode& ec) const
2221 {
2222     Document* document = contextDocument();
2223     if (!document) {
2224         ec = INVALID_ACCESS_ERR;
2225         return;
2226     }
2227     document->cachedResourceLoader().garbageCollectDocumentResources();
2228 }
2229
2230 void Internals::insertAuthorCSS(const String& css, ExceptionCode& ec) const
2231 {
2232     Document* document = contextDocument();
2233     if (!document) {
2234         ec = INVALID_ACCESS_ERR;
2235         return;
2236     }
2237
2238     auto parsedSheet = StyleSheetContents::create(*document);
2239     parsedSheet.get().setIsUserStyleSheet(false);
2240     parsedSheet.get().parseString(css);
2241     document->extensionStyleSheets().addAuthorStyleSheetForTesting(WTFMove(parsedSheet));
2242 }
2243
2244 void Internals::insertUserCSS(const String& css, ExceptionCode& ec) const
2245 {
2246     Document* document = contextDocument();
2247     if (!document) {
2248         ec = INVALID_ACCESS_ERR;
2249         return;
2250     }
2251
2252     auto parsedSheet = StyleSheetContents::create(*document);
2253     parsedSheet.get().setIsUserStyleSheet(true);
2254     parsedSheet.get().parseString(css);
2255     document->extensionStyleSheets().addUserStyleSheet(WTFMove(parsedSheet));
2256 }
2257
2258 String Internals::counterValue(Element* element)
2259 {
2260     if (!element)
2261         return String();
2262
2263     return counterValueForElement(element);
2264 }
2265
2266 int Internals::pageNumber(Element* element, float pageWidth, float pageHeight)
2267 {
2268     if (!element)
2269         return 0;
2270
2271     return PrintContext::pageNumberForElement(element, FloatSize(pageWidth, pageHeight));
2272 }
2273
2274 Vector<String> Internals::shortcutIconURLs() const
2275 {
2276     Vector<String> vector;
2277
2278     if (!frame())
2279         return vector;
2280
2281     auto string = frame()->loader().icon().url().string();
2282     if (!string.isNull())
2283         vector.append(string);
2284     return vector;
2285 }
2286
2287 int Internals::numberOfPages(float pageWidth, float pageHeight)
2288 {
2289     if (!frame())
2290         return -1;
2291
2292     return PrintContext::numberOfPages(*frame(), FloatSize(pageWidth, pageHeight));
2293 }
2294
2295 String Internals::pageProperty(String propertyName, int pageNumber, ExceptionCode& ec) const
2296 {
2297     if (!frame()) {
2298         ec = INVALID_ACCESS_ERR;
2299         return String();
2300     }
2301
2302     return PrintContext::pageProperty(frame(), propertyName.utf8().data(), pageNumber);
2303 }
2304
2305 String Internals::pageSizeAndMarginsInPixels(int pageNumber, int width, int height, int marginTop, int marginRight, int marginBottom, int marginLeft, ExceptionCode& ec) const
2306 {
2307     if (!frame()) {
2308         ec = INVALID_ACCESS_ERR;
2309         return String();
2310     }
2311
2312     return PrintContext::pageSizeAndMarginsInPixels(frame(), pageNumber, width, height, marginTop, marginRight, marginBottom, marginLeft);
2313 }
2314
2315 void Internals::setPageScaleFactor(float scaleFactor, int x, int y, ExceptionCode& ec)
2316 {
2317     Document* document = contextDocument();
2318     if (!document || !document->page()) {
2319         ec = INVALID_ACCESS_ERR;
2320         return;
2321     }
2322     Page* page = document->page();
2323     page->setPageScaleFactor(scaleFactor, IntPoint(x, y));
2324 }
2325
2326 void Internals::setPageZoomFactor(float zoomFactor, ExceptionCode& ec)
2327 {
2328     Document* document = contextDocument();
2329     if (!document || !document->frame()) {
2330         ec = INVALID_ACCESS_ERR;
2331         return;
2332     }
2333     Frame* frame = document->frame();
2334     frame->setPageZoomFactor(zoomFactor);
2335 }
2336
2337 void Internals::setTextZoomFactor(float zoomFactor, ExceptionCode& ec)
2338 {
2339     Document* document = contextDocument();
2340     if (!document || !document->frame()) {
2341         ec = INVALID_ACCESS_ERR;
2342         return;
2343     }
2344     Frame* frame = document->frame();
2345     frame->setTextZoomFactor(zoomFactor);
2346 }
2347
2348 void Internals::setUseFixedLayout(bool useFixedLayout, ExceptionCode& ec)
2349 {
2350     Document* document = contextDocument();
2351     if (!document || !document->view()) {
2352         ec = INVALID_ACCESS_ERR;
2353         return;
2354     }
2355     FrameView* frameView = document->view();
2356     frameView->setUseFixedLayout(useFixedLayout);
2357 }
2358
2359 void Internals::setFixedLayoutSize(int width, int height, ExceptionCode& ec)
2360 {
2361     Document* document = contextDocument();
2362     if (!document || !document->view()) {
2363         ec = INVALID_ACCESS_ERR;
2364         return;
2365     }
2366     FrameView* frameView = document->view();
2367     frameView->setFixedLayoutSize(IntSize(width, height));
2368 }
2369
2370 void Internals::setHeaderHeight(float height)
2371 {
2372     Document* document = contextDocument();
2373     if (!document || !document->view())
2374         return;
2375
2376     FrameView* frameView = document->view();
2377     frameView->setHeaderHeight(height);
2378 }
2379
2380 void Internals::setFooterHeight(float height)
2381 {
2382     Document* document = contextDocument();
2383     if (!document || !document->view())
2384         return;
2385
2386     FrameView* frameView = document->view();
2387     frameView->setFooterHeight(height);
2388 }
2389     
2390 void Internals::setTopContentInset(float contentInset)
2391 {
2392     Document* document = contextDocument();
2393     if (!document)
2394         return;
2395     
2396     Page* page = document->page();
2397     page->setTopContentInset(contentInset);
2398 }
2399
2400 #if ENABLE(FULLSCREEN_API)
2401 void Internals::webkitWillEnterFullScreenForElement(Element* element)
2402 {
2403     Document* document = contextDocument();
2404     if (!document)
2405         return;
2406     document->webkitWillEnterFullScreenForElement(element);
2407 }
2408
2409 void Internals::webkitDidEnterFullScreenForElement(Element* element)
2410 {
2411     Document* document = contextDocument();
2412     if (!document)
2413         return;
2414     document->webkitDidEnterFullScreenForElement(element);
2415 }
2416
2417 void Internals::webkitWillExitFullScreenForElement(Element* element)
2418 {
2419     Document* document = contextDocument();
2420     if (!document)
2421         return;
2422     document->webkitWillExitFullScreenForElement(element);
2423 }
2424
2425 void Internals::webkitDidExitFullScreenForElement(Element* element)
2426 {
2427     Document* document = contextDocument();
2428     if (!document)
2429         return;
2430     document->webkitDidExitFullScreenForElement(element);
2431 }
2432 #endif
2433
2434 void Internals::setApplicationCacheOriginQuota(unsigned long long quota)
2435 {
2436     Document* document = contextDocument();
2437     if (!document)
2438         return;
2439     ApplicationCacheStorage::singleton().storeUpdatedQuotaForOrigin(document->securityOrigin(), quota);
2440 }
2441
2442 void Internals::registerURLSchemeAsBypassingContentSecurityPolicy(const String& scheme)
2443 {
2444     SchemeRegistry::registerURLSchemeAsBypassingContentSecurityPolicy(scheme);
2445 }
2446
2447 void Internals::removeURLSchemeRegisteredAsBypassingContentSecurityPolicy(const String& scheme)
2448 {
2449     SchemeRegistry::removeURLSchemeRegisteredAsBypassingContentSecurityPolicy(scheme);
2450 }
2451
2452 Ref<MallocStatistics> Internals::mallocStatistics() const
2453 {
2454     return MallocStatistics::create();
2455 }
2456
2457 Ref<TypeConversions> Internals::typeConversions() const
2458 {
2459     return TypeConversions::create();
2460 }
2461
2462 Ref<MemoryInfo> Internals::memoryInfo() const
2463 {
2464     return MemoryInfo::create();
2465 }
2466
2467 Vector<String> Internals::getReferencedFilePaths() const
2468 {
2469     frame()->loader().history().saveDocumentAndScrollState();
2470     return FormController::getReferencedFilePaths(frame()->loader().history().currentItem()->documentState());
2471 }
2472
2473 void Internals::startTrackingRepaints(ExceptionCode& ec)
2474 {
2475     Document* document = contextDocument();
2476     if (!document || !document->view()) {
2477         ec = INVALID_ACCESS_ERR;
2478         return;
2479     }
2480
2481     FrameView* frameView = document->view();
2482     frameView->setTracksRepaints(true);
2483 }
2484
2485 void Internals::stopTrackingRepaints(ExceptionCode& ec)
2486 {
2487     Document* document = contextDocument();
2488     if (!document || !document->view()) {
2489         ec = INVALID_ACCESS_ERR;
2490         return;
2491     }
2492
2493     FrameView* frameView = document->view();
2494     frameView->setTracksRepaints(false);
2495 }
2496
2497 void Internals::startTrackingLayerFlushes(ExceptionCode& ec)
2498 {
2499     Document* document = contextDocument();
2500     if (!document || !document->renderView()) {
2501         ec = INVALID_ACCESS_ERR;
2502         return;
2503     }
2504
2505     document->renderView()->compositor().startTrackingLayerFlushes();
2506 }
2507
2508 unsigned long Internals::layerFlushCount(ExceptionCode& ec)
2509 {
2510     Document* document = contextDocument();
2511     if (!document || !document->renderView()) {
2512         ec = INVALID_ACCESS_ERR;
2513         return 0;
2514     }
2515
2516     return document->renderView()->compositor().layerFlushCount();
2517 }
2518
2519 void Internals::startTrackingStyleRecalcs(ExceptionCode& ec)
2520 {
2521     Document* document = contextDocument();
2522     if (!document) {
2523         ec = INVALID_ACCESS_ERR;
2524         return;
2525     }
2526     document->startTrackingStyleRecalcs();
2527 }
2528
2529 unsigned long Internals::styleRecalcCount(ExceptionCode& ec)
2530 {
2531     Document* document = contextDocument();
2532     if (!document) {
2533         ec = INVALID_ACCESS_ERR;
2534         return 0;
2535     }
2536     
2537     return document->styleRecalcCount();
2538 }
2539
2540 void Internals::startTrackingCompositingUpdates(ExceptionCode& ec)
2541 {
2542     Document* document = contextDocument();
2543     if (!document || !document->renderView()) {
2544         ec = INVALID_ACCESS_ERR;
2545         return;
2546     }
2547
2548     document->renderView()->compositor().startTrackingCompositingUpdates();
2549 }
2550
2551 unsigned long Internals::compositingUpdateCount(ExceptionCode& ec)
2552 {
2553     Document* document = contextDocument();
2554     if (!document || !document->renderView()) {
2555         ec = INVALID_ACCESS_ERR;
2556         return 0;
2557     }
2558     
2559     return document->renderView()->compositor().compositingUpdateCount();
2560 }
2561
2562 void Internals::updateLayoutIgnorePendingStylesheetsAndRunPostLayoutTasks(ExceptionCode& ec)
2563 {
2564     updateLayoutIgnorePendingStylesheetsAndRunPostLayoutTasks(nullptr, ec);
2565 }
2566
2567 void Internals::updateLayoutIgnorePendingStylesheetsAndRunPostLayoutTasks(Node* node, ExceptionCode& ec)
2568 {
2569     Document* document;
2570     if (!node)
2571         document = contextDocument();
2572     else if (is<Document>(*node))
2573         document = downcast<Document>(node);
2574     else if (is<HTMLIFrameElement>(*node))
2575         document = downcast<HTMLIFrameElement>(*node).contentDocument();
2576     else {
2577         ec = TypeError;
2578         return;
2579     }
2580
2581     document->updateLayoutIgnorePendingStylesheets(Document::RunPostLayoutTasks::Synchronously);
2582 }
2583
2584 unsigned Internals::layoutCount() const
2585 {
2586     Document* document = contextDocument();
2587     if (!document || !document->view())
2588         return 0;
2589     return document->view()->layoutCount();
2590 }
2591
2592 #if !PLATFORM(IOS)
2593 static const char* cursorTypeToString(Cursor::Type cursorType)
2594 {
2595     switch (cursorType) {
2596     case Cursor::Pointer: return "Pointer";
2597     case Cursor::Cross: return "Cross";
2598     case Cursor::Hand: return "Hand";
2599     case Cursor::IBeam: return "IBeam";
2600     case Cursor::Wait: return "Wait";
2601     case Cursor::Help: return "Help";
2602     case Cursor::EastResize: return "EastResize";
2603     case Cursor::NorthResize: return "NorthResize";
2604     case Cursor::NorthEastResize: return "NorthEastResize";
2605     case Cursor::NorthWestResize: return "NorthWestResize";
2606     case Cursor::SouthResize: return "SouthResize";
2607     case Cursor::SouthEastResize: return "SouthEastResize";
2608     case Cursor::SouthWestResize: return "SouthWestResize";
2609     case Cursor::WestResize: return "WestResize";
2610     case Cursor::NorthSouthResize: return "NorthSouthResize";
2611     case Cursor::EastWestResize: return "EastWestResize";
2612     case Cursor::NorthEastSouthWestResize: return "NorthEastSouthWestResize";
2613     case Cursor::NorthWestSouthEastResize: return "NorthWestSouthEastResize";
2614     case Cursor::ColumnResize: return "ColumnResize";
2615     case Cursor::RowResize: return "RowResize";
2616     case Cursor::MiddlePanning: return "MiddlePanning";
2617     case Cursor::EastPanning: return "EastPanning";
2618     case Cursor::NorthPanning: return "NorthPanning";
2619     case Cursor::NorthEastPanning: return "NorthEastPanning";
2620     case Cursor::NorthWestPanning: return "NorthWestPanning";
2621     case Cursor::SouthPanning: return "SouthPanning";
2622     case Cursor::SouthEastPanning: return "SouthEastPanning";
2623     case Cursor::SouthWestPanning: return "SouthWestPanning";
2624     case Cursor::WestPanning: return "WestPanning";
2625     case Cursor::Move: return "Move";
2626     case Cursor::VerticalText: return "VerticalText";
2627     case Cursor::Cell: return "Cell";
2628     case Cursor::ContextMenu: return "ContextMenu";
2629     case Cursor::Alias: return "Alias";
2630     case Cursor::Progress: return "Progress";
2631     case Cursor::NoDrop: return "NoDrop";
2632     case Cursor::Copy: return "Copy";
2633     case Cursor::None: return "None";
2634     case Cursor::NotAllowed: return "NotAllowed";
2635     case Cursor::ZoomIn: return "ZoomIn";
2636     case Cursor::ZoomOut: return "ZoomOut";
2637     case Cursor::Grab: return "Grab";
2638     case Cursor::Grabbing: return "Grabbing";
2639     case Cursor::Custom: return "Custom";
2640     }
2641
2642     ASSERT_NOT_REACHED();
2643     return "UNKNOWN";
2644 }
2645 #endif
2646
2647 String Internals::getCurrentCursorInfo(ExceptionCode& ec)
2648 {
2649     Document* document = contextDocument();
2650     if (!document || !document->frame()) {
2651         ec = INVALID_ACCESS_ERR;
2652         return String();
2653     }
2654
2655 #if !PLATFORM(IOS)
2656     Cursor cursor = document->frame()->eventHandler().currentMouseCursor();
2657
2658     StringBuilder result;
2659     result.appendLiteral("type=");
2660     result.append(cursorTypeToString(cursor.type()));
2661     result.appendLiteral(" hotSpot=");
2662     result.appendNumber(cursor.hotSpot().x());
2663     result.append(',');
2664     result.appendNumber(cursor.hotSpot().y());
2665     if (cursor.image()) {
2666         FloatSize size = cursor.image()->size();
2667         result.appendLiteral(" image=");
2668         result.appendNumber(size.width());
2669         result.append('x');
2670         result.appendNumber(size.height());
2671     }
2672 #if ENABLE(MOUSE_CURSOR_SCALE)
2673     if (cursor.imageScaleFactor() != 1) {
2674         result.appendLiteral(" scale=");
2675         NumberToStringBuffer buffer;
2676         result.append(numberToFixedPrecisionString(cursor.imageScaleFactor(), 8, buffer, true));
2677     }
2678 #endif
2679     return result.toString();
2680 #else
2681     return "FAIL: Cursor details not available on this platform.";
2682 #endif
2683 }
2684
2685 RefPtr<ArrayBuffer> Internals::serializeObject(PassRefPtr<SerializedScriptValue> value) const
2686 {
2687     Vector<uint8_t> bytes = value->data();
2688     return ArrayBuffer::create(bytes.data(), bytes.size());
2689 }
2690
2691 RefPtr<SerializedScriptValue> Internals::deserializeBuffer(PassRefPtr<ArrayBuffer> buffer) const
2692 {
2693     Vector<uint8_t> bytes;
2694     bytes.append(static_cast<const uint8_t*>(buffer->data()), buffer->byteLength());
2695     return SerializedScriptValue::adopt(WTFMove(bytes));
2696 }
2697
2698 bool Internals::isFromCurrentWorld(Deprecated::ScriptValue value) const
2699 {
2700     ASSERT(!value.hasNoValue());
2701     
2702     JSC::ExecState* exec = contextDocument()->vm().topCallFrame;
2703     if (!value.isObject() || &worldForDOMObject(value.jsValue().getObject()) == &currentWorld(exec))
2704         return true;
2705     return false;
2706 }
2707
2708 void Internals::setUsesOverlayScrollbars(bool enabled)
2709 {
2710     WebCore::Settings::setUsesOverlayScrollbars(enabled);
2711 }
2712
2713 void Internals::setUsesMockScrollAnimator(bool enabled)
2714 {
2715     WebCore::Settings::setUsesMockScrollAnimator(enabled);
2716 }
2717
2718 void Internals::forceReload(bool endToEnd)
2719 {
2720     frame()->loader().reload(endToEnd);
2721 }
2722
2723 void Internals::enableAutoSizeMode(bool enabled, int minimumWidth, int minimumHeight, int maximumWidth, int maximumHeight)
2724 {
2725     Document* document = contextDocument();
2726     if (!document || !document->view())
2727         return;
2728     document->view()->enableAutoSizeMode(enabled, IntSize(minimumWidth, minimumHeight), IntSize(maximumWidth, maximumHeight));
2729 }
2730
2731 #if ENABLE(ENCRYPTED_MEDIA_V2)
2732 void Internals::initializeMockCDM()
2733 {
2734     CDM::registerCDMFactory([](CDM* cdm) { return std::make_unique<MockCDM>(cdm); },
2735         MockCDM::supportsKeySystem, MockCDM::supportsKeySystemAndMimeType);
2736 }
2737 #endif
2738
2739 String Internals::markerTextForListItem(Element* element, ExceptionCode& ec)
2740 {
2741     if (!element) {
2742         ec = INVALID_ACCESS_ERR;
2743         return String();
2744     }
2745     return WebCore::markerTextForListItem(element);
2746 }
2747
2748 String Internals::toolTipFromElement(Element* element, ExceptionCode& ec) const
2749 {
2750     if (!element) {
2751         ec = INVALID_ACCESS_ERR;
2752         return String();
2753     }
2754     HitTestResult result;
2755     result.setInnerNode(element);
2756     TextDirection dir;
2757     return result.title(dir);
2758 }
2759
2760 String Internals::getImageSourceURL(Element* element, ExceptionCode& ec)
2761 {
2762     if (!element) {
2763         ec = INVALID_ACCESS_ERR;
2764         return String();
2765     }
2766     return element->imageSourceURL();
2767 }
2768
2769 #if ENABLE(VIDEO)
2770 void Internals::simulateAudioInterruption(Node* node)
2771 {
2772 #if USE(GSTREAMER)
2773     HTMLMediaElement* element = downcast<HTMLMediaElement>(node);
2774     element->player()->simulateAudioInterruption();
2775 #else
2776     UNUSED_PARAM(node);
2777 #endif
2778 }
2779
2780 bool Internals::mediaElementHasCharacteristic(Node* node, const String& characteristic, ExceptionCode& ec)
2781 {
2782     if (!is<HTMLMediaElement>(*node))
2783         return false;
2784
2785     HTMLMediaElement* element = downcast<HTMLMediaElement>(node);
2786
2787     if (equalLettersIgnoringASCIICase(characteristic, "audible"))
2788         return element->hasAudio();
2789     if (equalLettersIgnoringASCIICase(characteristic, "visual"))
2790         return element->hasVideo();
2791     if (equalLettersIgnoringASCIICase(characteristic, "legible"))
2792         return element->hasClosedCaptions();
2793
2794     ec = SYNTAX_ERR;
2795     return false;
2796 }
2797 #endif
2798
2799 bool Internals::isSelectPopupVisible(Node* node)
2800 {
2801     if (!is<HTMLSelectElement>(*node))
2802         return false;
2803
2804     HTMLSelectElement& select = downcast<HTMLSelectElement>(*node);
2805
2806     auto* renderer = select.renderer();
2807     ASSERT(renderer);
2808     if (!is<RenderMenuList>(*renderer))
2809         return false;
2810
2811 #if !PLATFORM(IOS)
2812     return downcast<RenderMenuList>(*renderer).popupIsVisible();
2813 #else
2814     return false;
2815 #endif // !PLATFORM(IOS)
2816 }
2817
2818 String Internals::captionsStyleSheetOverride(ExceptionCode& ec)
2819 {
2820     Document* document = contextDocument();
2821     if (!document || !document->page()) {
2822         ec = INVALID_ACCESS_ERR;
2823         return emptyString();
2824     }
2825
2826 #if ENABLE(VIDEO_TRACK)
2827     return document->page()->group().captionPreferences().captionsStyleSheetOverride();
2828 #else
2829     return emptyString();
2830 #endif
2831 }
2832
2833 void Internals::setCaptionsStyleSheetOverride(const String& override, ExceptionCode& ec)
2834 {
2835     Document* document = contextDocument();
2836     if (!document || !document->page()) {
2837         ec = INVALID_ACCESS_ERR;
2838         return;
2839     }
2840
2841 #if ENABLE(VIDEO_TRACK)
2842     document->page()->group().captionPreferences().setCaptionsStyleSheetOverride(override);
2843 #else
2844     UNUSED_PARAM(override);
2845 #endif
2846 }
2847
2848 void Internals::setPrimaryAudioTrackLanguageOverride(const String& language, ExceptionCode& ec)
2849 {
2850     Document* document = contextDocument();
2851     if (!document || !document->page()) {
2852         ec = INVALID_ACCESS_ERR;
2853         return;
2854     }
2855
2856 #if ENABLE(VIDEO_TRACK)
2857     document->page()->group().captionPreferences().setPrimaryAudioTrackLanguageOverride(language);
2858 #else
2859     UNUSED_PARAM(language);
2860 #endif
2861 }
2862
2863 void Internals::setCaptionDisplayMode(const String& mode, ExceptionCode& ec)
2864 {
2865     Document* document = contextDocument();
2866     if (!document || !document->page()) {
2867         ec = INVALID_ACCESS_ERR;
2868         return;
2869     }
2870     
2871 #if ENABLE(VIDEO_TRACK)
2872     auto& captionPreferences = document->page()->group().captionPreferences();
2873     
2874     if (equalLettersIgnoringASCIICase(mode, "automatic"))
2875         captionPreferences.setCaptionDisplayMode(CaptionUserPreferences::Automatic);
2876     else if (equalLettersIgnoringASCIICase(mode, "forcedonly"))
2877         captionPreferences.setCaptionDisplayMode(CaptionUserPreferences::ForcedOnly);
2878     else if (equalLettersIgnoringASCIICase(mode, "alwayson"))
2879         captionPreferences.setCaptionDisplayMode(CaptionUserPreferences::AlwaysOn);
2880     else if (equalLettersIgnoringASCIICase(mode, "manual"))
2881         captionPreferences.setCaptionDisplayMode(CaptionUserPreferences::Manual);
2882     else
2883         ec = SYNTAX_ERR;
2884 #else
2885     UNUSED_PARAM(mode);
2886 #endif
2887 }
2888
2889 #if ENABLE(VIDEO)
2890 Ref<TimeRanges> Internals::createTimeRanges(Float32Array* startTimes, Float32Array* endTimes)
2891 {
2892     ASSERT(startTimes && endTimes);
2893     ASSERT(startTimes->length() == endTimes->length());
2894     Ref<TimeRanges> ranges = TimeRanges::create();
2895
2896     unsigned count = std::min(startTimes->length(), endTimes->length());
2897     for (unsigned i = 0; i < count; ++i)
2898         ranges->add(startTimes->item(i), endTimes->item(i));
2899     return ranges;
2900 }
2901
2902 double Internals::closestTimeToTimeRanges(double time, TimeRanges* ranges)
2903 {
2904     return ranges->nearest(time);
2905 }
2906 #endif
2907
2908 Ref<ClientRect> Internals::selectionBounds(ExceptionCode& ec)
2909 {
2910     Document* document = contextDocument();
2911     if (!document || !document->frame()) {
2912         ec = INVALID_ACCESS_ERR;
2913         return ClientRect::create();
2914     }
2915
2916     return ClientRect::create(document->frame()->selection().selectionBounds());
2917 }
2918
2919 #if ENABLE(VIBRATION)
2920 bool Internals::isVibrating()
2921 {
2922     Page* page = contextDocument()->page();
2923     ASSERT(page);
2924
2925     return Vibration::from(page)->isVibrating();
2926 }
2927 #endif
2928
2929 bool Internals::isPluginUnavailabilityIndicatorObscured(Element* element, ExceptionCode& ec)
2930 {
2931     if (!element) {
2932         ec = INVALID_ACCESS_ERR;
2933         return false;
2934     }
2935
2936     auto* renderer = element->renderer();
2937     if (!is<RenderEmbeddedObject>(renderer)) {
2938         ec = INVALID_ACCESS_ERR;
2939         return false;
2940     }
2941
2942     return downcast<RenderEmbeddedObject>(*renderer).isReplacementObscured();
2943 }
2944     
2945 bool Internals::isPluginSnapshotted(Element* element, ExceptionCode& ec)
2946 {
2947     if (!element) {
2948         ec = INVALID_ACCESS_ERR;
2949         return false;
2950     }
2951     HTMLPlugInElement* pluginElement = downcast<HTMLPlugInElement>(element);
2952     return pluginElement->displayState() <= HTMLPlugInElement::DisplayingSnapshot;
2953 }
2954     
2955 #if ENABLE(MEDIA_SOURCE)
2956 void Internals::initializeMockMediaSource()
2957 {
2958 #if USE(AVFOUNDATION)
2959     WebCore::Settings::setAVFoundationEnabled(false);
2960 #endif
2961     MediaPlayerFactorySupport::callRegisterMediaEngine(MockMediaPlayerMediaSource::registerMediaEngine);
2962 }
2963
2964 Vector<String> Internals::bufferedSamplesForTrackID(SourceBuffer* buffer, const AtomicString& trackID)
2965 {
2966     if (!buffer)
2967         return Vector<String>();
2968
2969     return buffer->bufferedSamplesForTrackID(trackID);
2970 }
2971     
2972 void Internals::setShouldGenerateTimestamps(SourceBuffer* buffer, bool flag)
2973 {
2974     if (buffer)
2975         buffer->setShouldGenerateTimestamps(flag);
2976 }
2977 #endif
2978
2979 #if ENABLE(VIDEO)
2980 void Internals::beginMediaSessionInterruption(const String& interruptionString, ExceptionCode& ec)
2981 {
2982     PlatformMediaSession::InterruptionType interruption = PlatformMediaSession::SystemInterruption;
2983
2984     if (equalLettersIgnoringASCIICase(interruptionString, "system"))
2985         interruption = PlatformMediaSession::SystemInterruption;
2986     else if (equalLettersIgnoringASCIICase(interruptionString, "systemsleep"))
2987         interruption = PlatformMediaSession::SystemSleep;
2988     else if (equalLettersIgnoringASCIICase(interruptionString, "enteringbackground"))
2989         interruption = PlatformMediaSession::EnteringBackground;
2990     else {
2991         ec = INVALID_ACCESS_ERR;
2992         return;
2993     }
2994
2995     PlatformMediaSessionManager::sharedManager().beginInterruption(interruption);
2996 }
2997
2998 void Internals::endMediaSessionInterruption(const String& flagsString)
2999 {
3000     PlatformMediaSession::EndInterruptionFlags flags = PlatformMediaSession::NoFlags;
3001
3002     if (equalLettersIgnoringASCIICase(flagsString, "mayresumeplaying"))
3003         flags = PlatformMediaSession::MayResumePlaying;
3004     
3005     PlatformMediaSessionManager::sharedManager().endInterruption(flags);
3006 }
3007
3008 void Internals::applicationDidEnterForeground() const
3009 {
3010     PlatformMediaSessionManager::sharedManager().applicationDidEnterForeground();
3011 }
3012
3013 void Internals::applicationWillEnterBackground() const
3014 {
3015     PlatformMediaSessionManager::sharedManager().applicationWillEnterBackground();
3016 }
3017
3018 void Internals::setMediaSessionRestrictions(const String& mediaTypeString, const String& restrictionsString, ExceptionCode& ec)
3019 {
3020     PlatformMediaSession::MediaType mediaType = PlatformMediaSession::None;
3021     if (equalLettersIgnoringASCIICase(mediaTypeString, "video"))
3022         mediaType = PlatformMediaSession::Video;
3023     else if (equalLettersIgnoringASCIICase(mediaTypeString, "audio"))
3024         mediaType = PlatformMediaSession::Audio;
3025     else if (equalLettersIgnoringASCIICase(mediaTypeString, "webaudio"))
3026         mediaType = PlatformMediaSession::WebAudio;
3027     else {
3028         ec = INVALID_ACCESS_ERR;
3029         return;
3030     }
3031
3032     PlatformMediaSessionManager::SessionRestrictions restrictions = PlatformMediaSessionManager::sharedManager().restrictions(mediaType);
3033     PlatformMediaSessionManager::sharedManager().removeRestriction(mediaType, restrictions);
3034
3035     restrictions = PlatformMediaSessionManager::NoRestrictions;
3036
3037     Vector<String> restrictionsArray;
3038     restrictionsString.split(',', false, restrictionsArray);
3039     for (auto& restrictionString : restrictionsArray) {
3040         if (equalLettersIgnoringASCIICase(restrictionString, "concurrentplaybacknotpermitted"))
3041             restrictions |= PlatformMediaSessionManager::ConcurrentPlaybackNotPermitted;
3042         if (equalLettersIgnoringASCIICase(restrictionString, "backgroundprocessplaybackrestricted"))
3043             restrictions |= PlatformMediaSessionManager::BackgroundProcessPlaybackRestricted;
3044         if (equalLettersIgnoringASCIICase(restrictionString, "backgroundtabplaybackrestricted"))
3045             restrictions |= PlatformMediaSessionManager::BackgroundTabPlaybackRestricted;
3046         if (equalLettersIgnoringASCIICase(restrictionString, "interruptedplaybacknotpermitted"))
3047             restrictions |= PlatformMediaSessionManager::InterruptedPlaybackNotPermitted;
3048     }
3049     PlatformMediaSessionManager::sharedManager().addRestriction(mediaType, restrictions);
3050 }
3051
3052 void Internals::setMediaElementRestrictions(HTMLMediaElement* element, const String& restrictionsString, ExceptionCode& ec)
3053 {
3054     if (!element) {
3055         ec = INVALID_ACCESS_ERR;
3056         return;
3057     }
3058
3059     MediaElementSession::BehaviorRestrictions restrictions = element->mediaSession().behaviorRestrictions();
3060     element->mediaSession().removeBehaviorRestriction(restrictions);
3061
3062     restrictions = MediaElementSession::NoRestrictions;
3063
3064     Vector<String> restrictionsArray;
3065     restrictionsString.split(',', false, restrictionsArray);
3066     for (auto& restrictionString : restrictionsArray) {
3067         if (equalLettersIgnoringASCIICase(restrictionString, "norestrictions"))
3068             restrictions |= MediaElementSession::NoRestrictions;
3069         if (equalLettersIgnoringASCIICase(restrictionString, "requireusergestureforload"))
3070             restrictions |= MediaElementSession::RequireUserGestureForLoad;
3071         if (equalLettersIgnoringASCIICase(restrictionString, "requireusergestureforratechange"))
3072             restrictions |= MediaElementSession::RequireUserGestureForRateChange;
3073         if (equalLettersIgnoringASCIICase(restrictionString, "requireusergestureforfullscreen"))
3074             restrictions |= MediaElementSession::RequireUserGestureForFullscreen;
3075         if (equalLettersIgnoringASCIICase(restrictionString, "requirepageconsenttoloadmedia"))
3076             restrictions |= MediaElementSession::RequirePageConsentToLoadMedia;
3077         if (equalLettersIgnoringASCIICase(restrictionString, "requirepageconsenttoresumemedia"))
3078             restrictions |= MediaElementSession::RequirePageConsentToResumeMedia;
3079 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
3080         if (equalLettersIgnoringASCIICase(restrictionString, "requireusergesturetoshowplaybacktargetpicker"))
3081             restrictions |= MediaElementSession::RequireUserGestureToShowPlaybackTargetPicker;
3082         if (equalLettersIgnoringASCIICase(restrictionString, "wirelessvideoplaybackdisabled"))
3083             restrictions |= MediaElementSession::WirelessVideoPlaybackDisabled;
3084 #endif
3085         if (equalLettersIgnoringASCIICase(restrictionString, "requireusergestureforaudioratechange"))
3086             restrictions |= MediaElementSession::RequireUserGestureForAudioRateChange;
3087         if (equalLettersIgnoringASCIICase(restrictionString, "metadatapreloadingnotpermitted"))
3088             restrictions |= MediaElementSession::MetadataPreloadingNotPermitted;
3089         if (equalLettersIgnoringASCIICase(restrictionString, "autopreloadingnotpermitted"))
3090             restrictions |= MediaElementSession::AutoPreloadingNotPermitted;
3091         if (equalLettersIgnoringASCIICase(restrictionString, "invisibleautoplaynotpermitted"))
3092             restrictions |= MediaElementSession::InvisibleAutoplayNotPermitted;
3093     }
3094     element->mediaSession().addBehaviorRestriction(restrictions);
3095 }
3096
3097 void Internals::postRemoteControlCommand(const String& commandString, ExceptionCode& ec)
3098 {
3099     PlatformMediaSession::RemoteControlCommandType command;
3100     
3101     if (equalLettersIgnoringASCIICase(commandString, "play"))
3102         command = PlatformMediaSession::PlayCommand;
3103     else if (equalLettersIgnoringASCIICase(commandString, "pause"))
3104         command = PlatformMediaSession::PauseCommand;
3105     else if (equalLettersIgnoringASCIICase(commandString, "stop"))
3106         command = PlatformMediaSession::StopCommand;
3107     else if (equalLettersIgnoringASCIICase(commandString, "toggleplaypause"))
3108         command = PlatformMediaSession::TogglePlayPauseCommand;
3109     else if (equalLettersIgnoringASCIICase(commandString, "beginseekingbackward"))
3110         command = PlatformMediaSession::BeginSeekingBackwardCommand;
3111     else if (equalLettersIgnoringASCIICase(commandString, "endseekingbackward"))
3112         command = PlatformMediaSession::EndSeekingBackwardCommand;
3113     else if (equalLettersIgnoringASCIICase(commandString, "beginseekingforward"))
3114         command = PlatformMediaSession::BeginSeekingForwardCommand;
3115     else if (equalLettersIgnoringASCIICase(commandString, "endseekingforward"))
3116         command = PlatformMediaSession::EndSeekingForwardCommand;
3117     else {
3118         ec = INVALID_ACCESS_ERR;
3119         return;
3120     }
3121     
3122     PlatformMediaSessionManager::sharedManager().didReceiveRemoteControlCommand(command);
3123 }
3124
3125 bool Internals::elementIsBlockingDisplaySleep(Element* element) const
3126 {
3127     HTMLMediaElement* mediaElement = downcast<HTMLMediaElement>(element);
3128     return mediaElement ? mediaElement->isDisablingSleep() : false;
3129 }
3130
3131 #endif // ENABLE(VIDEO)
3132
3133 #if ENABLE(MEDIA_SESSION)
3134 static MediaSessionInterruptingCategory interruptingCategoryFromString(const String& interruptingCategoryString)
3135 {
3136     if (interruptingCategoryString == "content")
3137         return MediaSessionInterruptingCategory::Content;
3138     if (interruptingCategoryString == "transient")
3139         return MediaSessionInterruptingCategory::Transient;
3140     if (interruptingCategoryString == "transient-solo")
3141         return MediaSessionInterruptingCategory::TransientSolo;
3142     ASSERT_NOT_REACHED();
3143     return MediaSessionInterruptingCategory::Content;
3144 }
3145
3146 void Internals::sendMediaSessionStartOfInterruptionNotification(const String& interruptingCategoryString)
3147 {
3148     MediaSessionManager::singleton().didReceiveStartOfInterruptionNotification(interruptingCategoryFromString(interruptingCategoryString));
3149 }
3150
3151 void Internals::sendMediaSessionEndOfInterruptionNotification(const String& interruptingCategoryString)
3152 {
3153     MediaSessionManager::singleton().didReceiveEndOfInterruptionNotification(interruptingCategoryFromString(interruptingCategoryString));
3154 }
3155
3156 String Internals::mediaSessionCurrentState(MediaSession* session) const
3157 {
3158     switch (session->currentState()) {
3159     case MediaSession::State::Active:
3160         return "active";
3161     case MediaSession::State::Interrupted:
3162         return "interrupted";
3163     case MediaSession::State::Idle:
3164         return "idle";
3165     }
3166 }
3167
3168 double Internals::mediaElementPlayerVolume(HTMLMediaElement* element) const
3169 {
3170     ASSERT_ARG(element, element);
3171     return element->playerVolume();
3172 }
3173
3174 void Internals::sendMediaControlEvent(const String& event)
3175 {
3176     if (event == "play-pause")
3177         MediaSessionManager::singleton().togglePlayback();
3178     else if (event == "next-track")
3179         MediaSessionManager::singleton().skipToNextTrack();
3180     else if (event == "previous-track")
3181         MediaSessionManager::singleton().skipToPreviousTrack();
3182     else
3183         ASSERT_NOT_REACHED();
3184 }
3185 #endif // ENABLE(MEDIA_SESSION)
3186
3187 #if ENABLE(WEB_AUDIO)
3188 void Internals::setAudioContextRestrictions(AudioContext* context, const String &restrictionsString, ExceptionCode &ec)
3189 {
3190     if (!context) {
3191         ec = INVALID_ACCESS_ERR;
3192         return;
3193     }
3194
3195     AudioContext::BehaviorRestrictions restrictions = context->behaviorRestrictions();
3196     context->removeBehaviorRestriction(restrictions);
3197
3198     restrictions = AudioContext::NoRestrictions;
3199
3200     Vector<String> restrictionsArray;
3201     restrictionsString.split(',', false, restrictionsArray);
3202     for (auto& restrictionString : restrictionsArray) {
3203         if (equalLettersIgnoringASCIICase(restrictionString, "norestrictions"))
3204             restrictions |= AudioContext::NoRestrictions;
3205         if (equalLettersIgnoringASCIICase(restrictionString, "requireusergestureforaudiostart"))
3206             restrictions |= AudioContext::RequireUserGestureForAudioStartRestriction;
3207         if (equalLettersIgnoringASCIICase(restrictionString, "requirepageconsentforaudiostart"))
3208             restrictions |= AudioContext::RequirePageConsentForAudioStartRestriction;
3209     }
3210     context->addBehaviorRestriction(restrictions);
3211 }
3212 #endif
3213
3214 void Internals::simulateSystemSleep() const
3215 {
3216 #if ENABLE(VIDEO)
3217     PlatformMediaSessionManager::sharedManager().systemWillSleep();
3218 #endif
3219 }
3220
3221 void Internals::simulateSystemWake() const
3222 {
3223 #if ENABLE(VIDEO)
3224     PlatformMediaSessionManager::sharedManager().systemDidWake();
3225 #endif
3226 }
3227
3228 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
3229 void Internals::setMockMediaPlaybackTargetPickerEnabled(bool enabled)
3230 {
3231     Page* page = contextDocument()->frame()->page();
3232     ASSERT(page);
3233
3234     page->setMockMediaPlaybackTargetPickerEnabled(enabled);
3235 }
3236
3237 void Internals::setMockMediaPlaybackTargetPickerState(const String& deviceName, const String& deviceState, ExceptionCode& ec)
3238 {
3239     Page* page = contextDocument()->frame()->page();
3240     ASSERT(page);
3241
3242     MediaPlaybackTargetContext::State state = MediaPlaybackTargetContext::Unknown;
3243
3244     if (equalLettersIgnoringASCIICase(deviceState, "deviceavailable"))
3245         state = MediaPlaybackTargetContext::OutputDeviceAvailable;
3246     else if (equalLettersIgnoringASCIICase(deviceState, "deviceunavailable"))
3247         state = MediaPlaybackTargetContext::OutputDeviceUnavailable;
3248     else if (equalLettersIgnoringASCIICase(deviceState, "unknown"))
3249         state = MediaPlaybackTargetContext::Unknown;
3250     else {
3251         ec = INVALID_ACCESS_ERR;
3252         return;
3253     }
3254
3255     page->setMockMediaPlaybackTargetPickerState(deviceName, state);
3256 }
3257 #endif
3258
3259 RefPtr<MockPageOverlay> Internals::installMockPageOverlay(const String& overlayType, ExceptionCode& ec)
3260 {
3261     Document* document = contextDocument();
3262     if (!document || !document->frame()) {
3263         ec = INVALID_ACCESS_ERR;
3264         return nullptr;
3265     }
3266
3267     return MockPageOverlayClient::singleton().installOverlay(document->frame()->mainFrame(), overlayType == "view" ? PageOverlay::OverlayType::View : PageOverlay::OverlayType::Document);
3268 }
3269
3270 String Internals::pageOverlayLayerTreeAsText(ExceptionCode& ec) const
3271 {
3272     Document* document = contextDocument();
3273     if (!document || !document->frame()) {
3274         ec = INVALID_ACCESS_ERR;
3275         return String();
3276     }
3277
3278     document->updateLayout();
3279
3280     return MockPageOverlayClient::singleton().layerTreeAsText(document->frame()->mainFrame());
3281 }
3282
3283 void Internals::setPageMuted(bool muted)
3284 {
3285     Document* document = contextDocument();
3286     if (!document)
3287         return;
3288
3289     if (Page* page = document->page())
3290         page->setMuted(muted);
3291 }
3292
3293 bool Internals::isPagePlayingAudio()
3294 {
3295     Document* document = contextDocument();
3296     if (!document || !document->page())
3297         return false;
3298
3299     return !!(document->page()->mediaState() & MediaProducer::IsPlayingAudio);
3300 }
3301
3302 void Internals::setPageDefersLoading(bool defersLoading)
3303 {
3304     Document* document = contextDocument();
3305     if (!document)
3306         return;
3307     if (Page* page = document->page())
3308         page->setDefersLoading(defersLoading);
3309 }
3310
3311 RefPtr<File> Internals::createFile(const String& path)
3312 {
3313     Document* document = contextDocument();
3314     if (!document)
3315         return nullptr;
3316
3317     URL url = document->completeURL(path);
3318     if (!url.isLocalFile())
3319         return nullptr;
3320
3321     return File::create(url.fileSystemPath());
3322 }
3323
3324 void Internals::queueMicroTask(int testNumber)
3325 {
3326     Document* document = contextDocument();
3327     if (!document)
3328         return;
3329
3330     auto microtask = std::make_unique<ActiveDOMCallbackMicrotask>(MicrotaskQueue::mainThreadQueue(), *document, [document, testNumber]() {
3331         document->addConsoleMessage(MessageSource::JS, MessageLevel::Debug, makeString("MicroTask #", String::number(testNumber), " has run."));
3332     });
3333
3334     MicrotaskQueue::mainThreadQueue().append(WTFMove(microtask));
3335 }
3336
3337 #if ENABLE(CONTENT_FILTERING)
3338 MockContentFilterSettings& Internals::mockContentFilterSettings()
3339 {
3340     return MockContentFilterSettings::singleton();
3341 }
3342 #endif
3343
3344 #if ENABLE(CSS_SCROLL_SNAP)
3345 static void appendOffsets(StringBuilder& builder, const Vector<LayoutUnit>& snapOffsets)
3346 {
3347     bool justStarting = true;
3348
3349     builder.append("{ ");
3350     for (auto& coordinate : snapOffsets) {
3351         if (!justStarting)
3352             builder.append(", ");
3353         else
3354             justStarting = false;
3355         
3356         builder.append(String::number(coordinate.toUnsigned()));
3357     }
3358     builder.append(" }");
3359 }
3360     
3361 String Internals::scrollSnapOffsets(Element* element, ExceptionCode& ec)
3362 {
3363     if (!element) {
3364         ec = INVALID_ACCESS_ERR;
3365         return String();
3366     }
3367
3368     if (!element->renderBox())
3369         return String();
3370
3371     RenderBox& box = *element->renderBox();
3372     ScrollableArea* scrollableArea;
3373     
3374     if (box.isBody()) {
3375         FrameView* frameView = box.frame().mainFrame().view();
3376         if (!frameView || !frameView->isScrollable()) {
3377             ec = INVALID_ACCESS_ERR;
3378             return String();
3379         }
3380         scrollableArea = frameView;
3381         
3382     } else {
3383         if (!box.canBeScrolledAndHasScrollableArea()) {
3384             ec = INVALID_ACCESS_ERR;
3385             return String();
3386         }
3387         scrollableArea = box.layer();
3388     }
3389
3390     if (!scrollableArea)
3391         return String();
3392     
3393     StringBuilder result;
3394
3395     if (scrollableArea->horizontalSnapOffsets()) {
3396         result.append("horizontal = ");
3397         appendOffsets(result, *scrollableArea->horizontalSnapOffsets());
3398     }
3399
3400     if (scrollableArea->verticalSnapOffsets()) {
3401         if (result.length())
3402             result.append(", ");
3403
3404         result.append("vertical = ");
3405         appendOffsets(result, *scrollableArea->verticalSnapOffsets());
3406     }
3407
3408     return result.toString();
3409 }
3410 #endif
3411
3412 bool Internals::testPreloaderSettingViewport()
3413 {
3414     return testPreloadScannerViewportSupport(contextDocument());
3415 }
3416
3417 String Internals::pathStringWithShrinkWrappedRects(Vector<double> rectComponents, double radius, ExceptionCode& ec)
3418 {
3419     if (rectComponents.size() % 4) {
3420         ec = INVALID_ACCESS_ERR;
3421         return String();
3422     }
3423
3424     Vector<FloatRect> rects;
3425     while (!rectComponents.isEmpty()) {
3426         double height = rectComponents.takeLast();
3427         double width = rectComponents.takeLast();
3428         double y = rectComponents.takeLast();
3429         double x = rectComponents.takeLast();
3430
3431         rects.append(FloatRect(x, y, width, height));
3432     }
3433
3434     rects.reverse();
3435
3436     Path path = PathUtilities::pathWithShrinkWrappedRects(rects, radius);
3437
3438     String pathString;
3439     buildStringFromPath(path, pathString);
3440
3441     return pathString;
3442 }
3443
3444
3445 String Internals::getCurrentMediaControlsStatusForElement(HTMLMediaElement* mediaElement)
3446 {
3447 #if !ENABLE(MEDIA_CONTROLS_SCRIPT)
3448     UNUSED_PARAM(mediaElement);
3449     return String();
3450 #else
3451     if (!mediaElement)
3452         return String();
3453
3454     return mediaElement->getCurrentMediaControlsStatus();
3455 #endif
3456 }
3457
3458 #if !PLATFORM(COCOA)
3459 String Internals::userVisibleString(const DOMURL*)
3460 {
3461     // Not implemented in WebCore.
3462     return String();
3463 }
3464 #endif
3465
3466 void Internals::setShowAllPlugins(bool show)
3467 {
3468     Document* document = contextDocument();
3469     if (!document)
3470         return;
3471     
3472     Page* page = document->page();
3473     if (!page)
3474         return;
3475
3476     page->setShowAllPlugins(show);
3477 }
3478
3479 #if ENABLE(STREAMS_API)
3480 bool Internals::isReadableStreamDisturbed(ScriptState& state, JSValue stream)
3481 {
3482     JSGlobalObject* globalObject = state.vmEntryGlobalObject();
3483     JSVMClientData* clientData = static_cast<JSVMClientData*>(state.vm().clientData);
3484     const Identifier& privateName = clientData->builtinFunctions().readableStreamInternalsBuiltins().isReadableStreamDisturbedPrivateName();
3485     JSValue value;
3486     PropertySlot propertySlot(value, PropertySlot::InternalMethodType::Get);
3487     globalObject->methodTable()->getOwnPropertySlot(globalObject, &state, privateName, propertySlot);
3488     value = propertySlot.getValue(&state, privateName);
3489     ASSERT(value.isFunction());
3490
3491     JSObject* function = value.getObject();
3492     CallData callData;
3493     CallType callType = JSC::getCallData(function, callData);
3494     ASSERT(callType != JSC::CallType::None);
3495     MarkedArgumentBuffer arguments;
3496     arguments.append(stream);
3497     JSValue returnedValue = JSC::call(&state, function, callType, callData, JSC::jsUndefined(), arguments);
3498     ASSERT(returnedValue.isBoolean());
3499
3500     return returnedValue.asBoolean();
3501 }
3502 #endif
3503
3504 String Internals::resourceLoadStatisticsForOrigin(String origin)
3505 {
3506     return ResourceLoadObserver::sharedObserver().statisticsForOrigin(origin);
3507 }
3508
3509 void Internals::setResourceLoadStatisticsEnabled(bool enable)
3510 {
3511     Settings::setResourceLoadStatisticsEnabled(enable);
3512 }
3513
3514 String Internals::composedTreeAsText(Node* node)
3515 {
3516     if (!is<ContainerNode>(node))
3517         return "";
3518     return WebCore::composedTreeAsText(downcast<ContainerNode>(*node));
3519 }
3520
3521 }