/*
 * Copyright (C) 2012 Google Inc. All rights reserved.
 * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1.  Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 * 2.  Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "config.h"
#include "Internals.h"

#include "AXObjectCache.h"
#include "AnimationController.h"
#include "ApplicationCacheStorage.h"
#include "BackForwardController.h"
#include "CachedImage.h"
#include "CachedResourceLoader.h"
#include "Chrome.h"
#include "ChromeClient.h"
#include "ClientRect.h"
#include "ClientRectList.h"
#include "ContentDistributor.h"
#include "Cursor.h"
#include "DOMPath.h"
#include "DOMStringList.h"
#include "DOMWindow.h"
#include "Document.h"
#include "DocumentMarker.h"
#include "DocumentMarkerController.h"
#include "Editor.h"
#include "Element.h"
#include "EventHandler.h"
#include "ExceptionCode.h"
#include "File.h"
#include "FontCache.h"
#include "FormController.h"
#include "FrameLoader.h"
#include "FrameView.h"
#include "HTMLIFrameElement.h"
#include "HTMLImageElement.h"
#include "HTMLInputElement.h"
#include "HTMLLinkElement.h"
#include "HTMLNames.h"
#include "HTMLPlugInElement.h"
#include "HTMLPreloadScanner.h"
#include "HTMLSelectElement.h"
#include "HTMLTextAreaElement.h"
#include "HTMLVideoElement.h"
#include "HistoryController.h"
#include "HistoryItem.h"
#include "IconController.h"
#include "InspectorClient.h"
#include "InspectorController.h"
#include "InspectorForwarding.h"
#include "InspectorFrontendClientLocal.h"
#include "InspectorInstrumentation.h"
#include "InspectorOverlay.h"
#include "InstrumentingAgents.h"
#include "IntRect.h"
#include "InternalSettings.h"
#include "Language.h"
#include "MainFrame.h"
#include "MallocStatistics.h"
#include "MediaPlayer.h"
#include "MemoryCache.h"
#include "MemoryInfo.h"
#include "MicroTask.h"
#include "MicroTaskTest.h"
#include "MockPageOverlayClient.h"
#include "Page.h"
#include "PageCache.h"
#include "PageOverlay.h"
#include "PathUtilities.h"
#include "PlatformMediaSessionManager.h"
#include "PrintContext.h"
#include "PseudoElement.h"
#include "Range.h"
#include "RenderEmbeddedObject.h"
#include "RenderLayerCompositor.h"
#include "RenderMenuList.h"
#include "RenderTreeAsText.h"
#include "RenderView.h"
#include "RenderedDocumentMarker.h"
#include "RuntimeEnabledFeatures.h"
#include "SchemeRegistry.h"
#include "ScriptedAnimationController.h"
#include "ScrollingCoordinator.h"
#include "SerializedScriptValue.h"
#include "Settings.h"
#include "ShadowRoot.h"
#include "SourceBuffer.h"
#include "SpellChecker.h"
#include "StaticNodeList.h"
#include "StyleSheetContents.h"
#include "TextIterator.h"
#include "TreeScope.h"
#include "TypeConversions.h"
#include "ViewportArguments.h"
#include "WebConsoleAgent.h"
#include "WorkerThread.h"
#include "XMLHttpRequest.h"
#include <JavaScriptCore/Profile.h>
#include <bytecode/CodeBlock.h>
#include <inspector/InspectorAgentBase.h>
#include <inspector/InspectorValues.h>
#include <runtime/JSCInlines.h>
#include <runtime/JSCJSValue.h>
#include <wtf/text/CString.h>
#include <wtf/text/StringBuffer.h>

#if ENABLE(INPUT_TYPE_COLOR)
#include "ColorChooser.h"
#endif

#if ENABLE(BATTERY_STATUS)
#include "BatteryController.h"
#endif

#if ENABLE(PROXIMITY_EVENTS)
#include "DeviceProximityController.h"
#endif

#if ENABLE(MOUSE_CURSOR_SCALE)
#include <wtf/dtoa.h>
#endif

#if ENABLE(ENCRYPTED_MEDIA_V2)
#include "CDM.h"
#include "MockCDM.h"
#endif

#if ENABLE(VIDEO_TRACK)
#include "CaptionUserPreferences.h"
#include "PageGroup.h"
#endif

#if ENABLE(VIDEO)
#include "HTMLMediaElement.h"
#include "TimeRanges.h"
#endif

#if ENABLE(SPEECH_SYNTHESIS)
#include "DOMWindowSpeechSynthesis.h"
#include "PlatformSpeechSynthesizerMock.h"
#include "SpeechSynthesis.h"
#endif

#if ENABLE(VIBRATION)
#include "Vibration.h"
#endif

#if ENABLE(MEDIA_STREAM)
#include "MockRealtimeMediaSourceCenter.h"
#include "RTCPeerConnection.h"
#include "RTCPeerConnectionHandlerMock.h"
#include "UserMediaClientMock.h"
#endif

#if ENABLE(MEDIA_SOURCE)
#include "MockMediaPlayerMediaSource.h"
#endif

#if PLATFORM(MAC)
#include "DictionaryLookup.h"
#endif

#if ENABLE(CONTENT_FILTERING)
#include "MockContentFilterSettings.h"
#endif

#if ENABLE(WEB_AUDIO)
#include "AudioContext.h"
#endif

#if ENABLE(MEDIA_SESSION)
#include "MediaSession.h"
#include "MediaSessionManager.h"
#endif

using JSC::CodeBlock;
using JSC::FunctionExecutable;
using JSC::JSFunction;
using JSC::JSValue;
using JSC::ScriptExecutable;
using JSC::StackVisitor;

using namespace Inspector;

namespace WebCore {

using namespace HTMLNames;

class InspectorFrontendClientDummy : public InspectorFrontendClientLocal {
public:
    InspectorFrontendClientDummy(InspectorController*, Page*);
    virtual ~InspectorFrontendClientDummy() { }
    virtual void attachWindow(DockSide) override { }
    virtual void detachWindow() override { }

    virtual String localizedStringsURL() override { return String(); }

    virtual void bringToFront() override { }
    virtual void closeWindow() override { }

    virtual void inspectedURLChanged(const String&) override { }

protected:
    virtual void setAttachedWindowHeight(unsigned) override { }
    virtual void setAttachedWindowWidth(unsigned) override { }
    virtual void setToolbarHeight(unsigned) override { }
};

InspectorFrontendClientDummy::InspectorFrontendClientDummy(InspectorController* controller, Page* page)
    : InspectorFrontendClientLocal(controller, page, std::make_unique<InspectorFrontendClientLocal::Settings>())
{
}

class InspectorFrontendChannelDummy : public InspectorFrontendChannel {
public:
    explicit InspectorFrontendChannelDummy(Page*);
    virtual ~InspectorFrontendChannelDummy() { }
    virtual bool sendMessageToFrontend(const String& message) override;
    virtual ConnectionType connectionType() const override { return ConnectionType::Local; }

private:
    Page* m_frontendPage;
};

InspectorFrontendChannelDummy::InspectorFrontendChannelDummy(Page* page)
    : m_frontendPage(page)
{
}

bool InspectorFrontendChannelDummy::sendMessageToFrontend(const String& message)
{
    return InspectorClient::doDispatchMessageOnFrontendPage(m_frontendPage, message);
}

static bool markerTypesFrom(const String& markerType, DocumentMarker::MarkerTypes& result)
{
    if (markerType.isEmpty() || equalIgnoringCase(markerType, "all"))
        result = DocumentMarker::AllMarkers();
    else if (equalIgnoringCase(markerType, "Spelling"))
        result =  DocumentMarker::Spelling;
    else if (equalIgnoringCase(markerType, "Grammar"))
        result =  DocumentMarker::Grammar;
    else if (equalIgnoringCase(markerType, "TextMatch"))
        result =  DocumentMarker::TextMatch;
    else if (equalIgnoringCase(markerType, "Replacement"))
        result =  DocumentMarker::Replacement;
    else if (equalIgnoringCase(markerType, "CorrectionIndicator"))
        result =  DocumentMarker::CorrectionIndicator;
    else if (equalIgnoringCase(markerType, "RejectedCorrection"))
        result =  DocumentMarker::RejectedCorrection;
    else if (equalIgnoringCase(markerType, "Autocorrected"))
        result =  DocumentMarker::Autocorrected;
    else if (equalIgnoringCase(markerType, "SpellCheckingExemption"))
        result =  DocumentMarker::SpellCheckingExemption;
    else if (equalIgnoringCase(markerType, "DeletedAutocorrection"))
        result =  DocumentMarker::DeletedAutocorrection;
    else if (equalIgnoringCase(markerType, "DictationAlternatives"))
        result =  DocumentMarker::DictationAlternatives;
#if ENABLE(TELEPHONE_NUMBER_DETECTION)
    else if (equalIgnoringCase(markerType, "TelephoneNumber"))
        result =  DocumentMarker::TelephoneNumber;
#endif
    else
        return false;

    return true;
}

const char* Internals::internalsId = "internals";

PassRefPtr<Internals> Internals::create(Document* document)
{
    return adoptRef(new Internals(document));
}

Internals::~Internals()
{
}

void Internals::resetToConsistentState(Page* page)
{
    ASSERT(page);

    page->setPageScaleFactor(1, IntPoint(0, 0));
    page->setPagination(Pagination());
    
    page->mainFrame().setTextZoomFactor(1.0f);
    
    FrameView* mainFrameView = page->mainFrame().view();
    if (mainFrameView) {
        mainFrameView->setHeaderHeight(0);
        mainFrameView->setFooterHeight(0);
        page->setTopContentInset(0);
        mainFrameView->setUseFixedLayout(false);
        mainFrameView->setFixedLayoutSize(IntSize());
    }

    TextRun::setAllowsRoundingHacks(false);
    WebCore::overrideUserPreferredLanguages(Vector<String>());
    WebCore::Settings::setUsesOverlayScrollbars(false);
    page->inspectorController().setProfilerEnabled(false);
#if ENABLE(VIDEO_TRACK)
    page->group().captionPreferences()->setCaptionsStyleSheetOverride(emptyString());
    page->group().captionPreferences()->setTestingMode(false);
#endif
    if (!page->mainFrame().editor().isContinuousSpellCheckingEnabled())
        page->mainFrame().editor().toggleContinuousSpellChecking();
    if (page->mainFrame().editor().isOverwriteModeEnabled())
        page->mainFrame().editor().toggleOverwriteModeEnabled();
    page->mainFrame().loader().clearTestingOverrides();
    ApplicationCacheStorage::singleton().setDefaultOriginQuota(ApplicationCacheStorage::noQuota());
#if ENABLE(VIDEO)
    PlatformMediaSessionManager::sharedManager().resetRestrictions();
#endif
#if HAVE(ACCESSIBILITY)
    AXObjectCache::setEnhancedUserInterfaceAccessibility(false);
    AXObjectCache::disableAccessibility();
#endif

    MockPageOverlayClient::singleton().uninstallAllOverlays();

#if ENABLE(CONTENT_FILTERING)
    MockContentFilterSettings::reset();
#endif
}

Internals::Internals(Document* document)
    : ContextDestructionObserver(document)
{
#if ENABLE(VIDEO_TRACK)
    if (document && document->page())
        document->page()->group().captionPreferences()->setTestingMode(true);
#endif

#if ENABLE(MEDIA_STREAM)
    MockRealtimeMediaSourceCenter::registerMockRealtimeMediaSourceCenter();
    enableMockRTCPeerConnectionHandler();
    WebCore::provideUserMediaTo(document->page(), new UserMediaClientMock());
#endif
}

Document* Internals::contextDocument() const
{
    return downcast<Document>(scriptExecutionContext());
}

Frame* Internals::frame() const
{
    if (!contextDocument())
        return nullptr;
    return contextDocument()->frame();
}

InternalSettings* Internals::settings() const
{
    Document* document = contextDocument();
    if (!document)
        return 0;
    Page* page = document->page();
    if (!page)
        return 0;
    return InternalSettings::from(page);
}

unsigned Internals::workerThreadCount() const
{
    return WorkerThread::workerThreadCount();
}

String Internals::address(Node* node)
{
    return String::format("%p", node);
}

bool Internals::nodeNeedsStyleRecalc(Node* node, ExceptionCode& exception)
{
    if (!node) {
        exception = INVALID_ACCESS_ERR;
        return false;
    }

    return node->needsStyleRecalc();
}

String Internals::description(Deprecated::ScriptValue value)
{
    return toString(value.jsValue());
}

bool Internals::isPreloaded(const String& url)
{
    Document* document = contextDocument();
    return document->cachedResourceLoader().isPreloaded(url);
}

bool Internals::isLoadingFromMemoryCache(const String& url)
{
    if (!contextDocument() || !contextDocument()->page())
        return false;

    ResourceRequest request(contextDocument()->completeURL(url));
#if ENABLE(CACHE_PARTITIONING)
    request.setDomainForCachePartition(contextDocument()->topOrigin()->domainForCachePartition());
#endif
    CachedResource* resource = MemoryCache::singleton().resourceForRequest(request, contextDocument()->page()->sessionID());
    return resource && resource->status() == CachedResource::Cached;
}

String Internals::xhrResponseSource(XMLHttpRequest* xhr)
{
    if (!xhr)
        return "Null xhr";
    if (xhr->resourceResponse().isNull())
        return "Null response";
    switch (xhr->resourceResponse().source()) {
    case ResourceResponse::Source::Unknown:
        return "Unknown";
    case ResourceResponse::Source::Network:
        return "Network";
    case ResourceResponse::Source::DiskCache:
        return "Disk cache";
    case ResourceResponse::Source::DiskCacheAfterValidation:
        return "Disk cache after validation";
    case ResourceResponse::Source::MemoryCache:
        return "Memory cache";
    case ResourceResponse::Source::MemoryCacheAfterValidation:
        return "Memory cache after validation";
    }
    ASSERT_NOT_REACHED();
    return "Error";
}

bool Internals::isSharingStyleSheetContents(Element* a, Element* b)
{
    if (!is<HTMLLinkElement>(a) || !is<HTMLLinkElement>(b))
        return false;
    auto& aLink = downcast<HTMLLinkElement>(*a);
    auto& bLink = downcast<HTMLLinkElement>(*b);
    if (!aLink.sheet() || !bLink.sheet())
        return false;
    return &aLink.sheet()->contents() == &bLink.sheet()->contents();
}

bool Internals::isStyleSheetLoadingSubresources(Element* link)
{
    if (!is<HTMLLinkElement>(link))
        return false;
    auto& linkElement = downcast<HTMLLinkElement>(*link);
    return linkElement.sheet() && linkElement.sheet()->contents().isLoadingSubresources();
}

static ResourceRequestCachePolicy stringToResourceRequestCachePolicy(const String& policy)
{
    if (policy == "UseProtocolCachePolicy")
        return UseProtocolCachePolicy;
    if (policy == "ReloadIgnoringCacheData")
        return ReloadIgnoringCacheData;
    if (policy == "ReturnCacheDataElseLoad")
        return ReturnCacheDataElseLoad;
    if (policy == "ReturnCacheDataDontLoad")
        return ReturnCacheDataDontLoad;
    ASSERT_NOT_REACHED();
    return UseProtocolCachePolicy;
}

void Internals::setOverrideCachePolicy(const String& policy)
{
    frame()->loader().setOverrideCachePolicyForTesting(stringToResourceRequestCachePolicy(policy));
}

static ResourceLoadPriority stringToResourceLoadPriority(const String& policy)
{
    if (policy == "ResourceLoadPriorityVeryLow")
        return ResourceLoadPriority::VeryLow;
    if (policy == "ResourceLoadPriorityLow")
        return ResourceLoadPriority::Low;
    if (policy == "ResourceLoadPriorityMedium")
        return ResourceLoadPriority::Medium;
    if (policy == "ResourceLoadPriorityHigh")
        return ResourceLoadPriority::High;
    if (policy == "ResourceLoadPriorityVeryHigh")
        return ResourceLoadPriority::VeryHigh;
    ASSERT_NOT_REACHED();
    return ResourceLoadPriority::Low;
}

void Internals::setOverrideResourceLoadPriority(const String& priority)
{
    frame()->loader().setOverrideResourceLoadPriorityForTesting(stringToResourceLoadPriority(priority));
}

void Internals::setStrictRawResourceValidationPolicyDisabled(bool disabled)
{
    frame()->loader().setStrictRawResourceValidationPolicyDisabledForTesting(disabled);
}

void Internals::clearMemoryCache()
{
    MemoryCache::singleton().evictResources();
}

void Internals::pruneMemoryCacheToSize(unsigned size)
{
    MemoryCache::singleton().pruneDeadResourcesToSize(size);
    MemoryCache::singleton().pruneLiveResourcesToSize(size, true);
}

unsigned Internals::memoryCacheSize() const
{
    return MemoryCache::singleton().size();
}

void Internals::clearPageCache()
{
    PageCache::singleton().pruneToSizeNow(0, PruningReason::None);
}

unsigned Internals::pageCacheSize() const
{
    return PageCache::singleton().pageCount();
}

Node* Internals::treeScopeRootNode(Node* node, ExceptionCode& ec)
{
    if (!node) {
        ec = INVALID_ACCESS_ERR;
        return nullptr;
    }

    return &node->treeScope().rootNode();
}

Node* Internals::parentTreeScope(Node* node, ExceptionCode& ec)
{
    if (!node) {
        ec = INVALID_ACCESS_ERR;
        return nullptr;
    }
    const TreeScope* parentTreeScope = node->treeScope().parentTreeScope();
    return parentTreeScope ? &parentTreeScope->rootNode() : nullptr;
}

unsigned Internals::lastSpatialNavigationCandidateCount(ExceptionCode& ec) const
{
    if (!contextDocument() || !contextDocument()->page()) {
        ec = INVALID_ACCESS_ERR;
        return 0;
    }

    return contextDocument()->page()->lastSpatialNavigationCandidateCount();
}

unsigned Internals::numberOfActiveAnimations() const
{
    return frame()->animation().numberOfActiveAnimations(frame()->document());
}

bool Internals::animationsAreSuspended(ExceptionCode& ec) const
{
    Document* document = contextDocument();
    if (!document || !document->frame()) {
        ec = INVALID_ACCESS_ERR;
        return false;
    }

    return document->frame()->animation().isSuspended();
}

void Internals::suspendAnimations(ExceptionCode& ec) const
{
    Document* document = contextDocument();
    if (!document || !document->frame()) {
        ec = INVALID_ACCESS_ERR;
        return;
    }

    document->frame()->animation().suspendAnimations();
}

void Internals::resumeAnimations(ExceptionCode& ec) const
{
    Document* document = contextDocument();
    if (!document || !document->frame()) {
        ec = INVALID_ACCESS_ERR;
        return;
    }

    document->frame()->animation().resumeAnimations();
}

bool Internals::pauseAnimationAtTimeOnElement(const String& animationName, double pauseTime, Element* element, ExceptionCode& ec)
{
    if (!element || pauseTime < 0) {
        ec = INVALID_ACCESS_ERR;
        return false;
    }
    return frame()->animation().pauseAnimationAtTime(element->renderer(), AtomicString(animationName), pauseTime);
}

bool Internals::pauseAnimationAtTimeOnPseudoElement(const String& animationName, double pauseTime, Element* element, const String& pseudoId, ExceptionCode& ec)
{
    if (!element || pauseTime < 0) {
        ec = INVALID_ACCESS_ERR;
        return false;
    }

    if (pseudoId != "before" && pseudoId != "after") {
        ec = INVALID_ACCESS_ERR;
        return false;
    }

    PseudoElement* pseudoElement = pseudoId == "before" ? element->beforePseudoElement() : element->afterPseudoElement();
    if (!pseudoElement) {
        ec = INVALID_ACCESS_ERR;
        return false;
    }

    return frame()->animation().pauseAnimationAtTime(pseudoElement->renderer(), AtomicString(animationName), pauseTime);
}

bool Internals::pauseTransitionAtTimeOnElement(const String& propertyName, double pauseTime, Element* element, ExceptionCode& ec)
{
    if (!element || pauseTime < 0) {
        ec = INVALID_ACCESS_ERR;
        return false;
    }
    return frame()->animation().pauseTransitionAtTime(element->renderer(), propertyName, pauseTime);
}

bool Internals::pauseTransitionAtTimeOnPseudoElement(const String& property, double pauseTime, Element* element, const String& pseudoId, ExceptionCode& ec)
{
    if (!element || pauseTime < 0) {
        ec = INVALID_ACCESS_ERR;
        return false;
    }

    if (pseudoId != "before" && pseudoId != "after") {
        ec = INVALID_ACCESS_ERR;
        return false;
    }

    PseudoElement* pseudoElement = pseudoId == "before" ? element->beforePseudoElement() : element->afterPseudoElement();
    if (!pseudoElement) {
        ec = INVALID_ACCESS_ERR;
        return false;
    }

    return frame()->animation().pauseTransitionAtTime(pseudoElement->renderer(), property, pauseTime);
}

// FIXME: Remove.
bool Internals::attached(Node* node, ExceptionCode& ec)
{
    if (!node) {
        ec = INVALID_ACCESS_ERR;
        return false;
    }

    return true;
}

String Internals::elementRenderTreeAsText(Element* element, ExceptionCode& ec)
{
    if (!element) {
        ec = INVALID_ACCESS_ERR;
        return String();
    }

    element->document().updateStyleIfNeeded();

    String representation = externalRepresentation(element);
    if (representation.isEmpty()) {
        ec = INVALID_ACCESS_ERR;
        return String();
    }

    return representation;
}

bool Internals::hasPausedImageAnimations(Element* element, ExceptionCode& ec)
{
    if (!element) {
        ec = INVALID_ACCESS_ERR;
        return false;
    }
    return element->renderer() && element->renderer()->hasPausedImageAnimations();
}

PassRefPtr<CSSComputedStyleDeclaration> Internals::computedStyleIncludingVisitedInfo(Node* node, ExceptionCode& ec) const
{
    if (!node) {
        ec = INVALID_ACCESS_ERR;
        return 0;
    }

    bool allowVisitedStyle = true;
    return CSSComputedStyleDeclaration::create(node, allowVisitedStyle);
}

Node* Internals::ensureShadowRoot(Element* host, ExceptionCode& ec)
{
    if (!host) {
        ec = INVALID_ACCESS_ERR;
        return 0;
    }

    if (ShadowRoot* shadowRoot = host->shadowRoot())
        return shadowRoot;

    return host->createShadowRoot(ec).get();
}

Node* Internals::ensureUserAgentShadowRoot(Element* host, ExceptionCode& ec)
{
    if (!host) {
        ec = INVALID_ACCESS_ERR;
        return nullptr;
    }
    return &host->ensureUserAgentShadowRoot();
}

Node* Internals::createShadowRoot(Element* host, ExceptionCode& ec)
{
    if (!host) {
        ec = INVALID_ACCESS_ERR;
        return 0;
    }
    return host->createShadowRoot(ec).get();
}

Node* Internals::shadowRoot(Element* host, ExceptionCode& ec)
{
    if (!host) {
        ec = INVALID_ACCESS_ERR;
        return nullptr;
    }
    return host->shadowRoot();
}

String Internals::shadowRootType(const Node* root, ExceptionCode& ec) const
{
    if (!is<ShadowRoot>(root)) {
        ec = INVALID_ACCESS_ERR;
        return String();
    }

    switch (downcast<ShadowRoot>(*root).type()) {
    case ShadowRoot::UserAgentShadowRoot:
        return String("UserAgentShadowRoot");
    default:
        ASSERT_NOT_REACHED();
        return String("Unknown");
    }
}

Element* Internals::includerFor(Node*, ExceptionCode& ec)
{
    ec = INVALID_ACCESS_ERR;
    return nullptr;
}

String Internals::shadowPseudoId(Element* element, ExceptionCode& ec)
{
    if (!element) {
        ec = INVALID_ACCESS_ERR;
        return String();
    }

    return element->shadowPseudoId().string();
}

void Internals::setShadowPseudoId(Element* element, const String& id, ExceptionCode& ec)
{
    if (!element) {
        ec = INVALID_ACCESS_ERR;
        return;
    }

    return element->setPseudo(id);
}

bool Internals::isTimerThrottled(int timeoutId, ExceptionCode& ec)
{
    DOMTimer* timer = scriptExecutionContext()->findTimeout(timeoutId);
    if (!timer) {
        ec = NOT_FOUND_ERR;
        return false;
    }
    return timer->m_throttleState == DOMTimer::ShouldThrottle;
}

bool Internals::isRequestAnimationFrameThrottled() const
{
#if ENABLE(REQUEST_ANIMATION_FRAME)
    auto* scriptedAnimationController = contextDocument()->scriptedAnimationController();
    if (!scriptedAnimationController)
        return false;
    return scriptedAnimationController->isThrottled();
#else
    return false;
#endif
}

bool Internals::areTimersThrottled() const
{
    return contextDocument()->isTimerThrottlingEnabled();
}

String Internals::visiblePlaceholder(Element* element)
{
    if (is<HTMLTextFormControlElement>(element)) {
        const HTMLTextFormControlElement& textFormControlElement = downcast<HTMLTextFormControlElement>(*element);
        if (!textFormControlElement.isPlaceholderVisible())
            return String();
        if (HTMLElement* placeholderElement = textFormControlElement.placeholderElement())
            return placeholderElement->textContent();
    }

    return String();
}

#if ENABLE(INPUT_TYPE_COLOR)
void Internals::selectColorInColorChooser(Element* element, const String& colorValue)
{
    if (!is<HTMLInputElement>(*element))
        return;
    HTMLInputElement* inputElement = element->toInputElement();
    if (!inputElement)
        return;
    inputElement->selectColorInColorChooser(Color(colorValue));
}
#endif

Vector<String> Internals::formControlStateOfPreviousHistoryItem(ExceptionCode& ec)
{
    HistoryItem* mainItem = frame()->loader().history().previousItem();
    if (!mainItem) {
        ec = INVALID_ACCESS_ERR;
        return Vector<String>();
    }
    String uniqueName = frame()->tree().uniqueName();
    if (mainItem->target() != uniqueName && !mainItem->childItemWithTarget(uniqueName)) {
        ec = INVALID_ACCESS_ERR;
        return Vector<String>();
    }
    return mainItem->target() == uniqueName ? mainItem->documentState() : mainItem->childItemWithTarget(uniqueName)->documentState();
}

void Internals::setFormControlStateOfPreviousHistoryItem(const Vector<String>& state, ExceptionCode& ec)
{
    HistoryItem* mainItem = frame()->loader().history().previousItem();
    if (!mainItem) {
        ec = INVALID_ACCESS_ERR;
        return;
    }
    String uniqueName = frame()->tree().uniqueName();
    if (mainItem->target() == uniqueName)
        mainItem->setDocumentState(state);
    else if (HistoryItem* subItem = mainItem->childItemWithTarget(uniqueName))
        subItem->setDocumentState(state);
    else
        ec = INVALID_ACCESS_ERR;
}

#if ENABLE(SPEECH_SYNTHESIS)
void Internals::enableMockSpeechSynthesizer()
{
    Document* document = contextDocument();
    if (!document || !document->domWindow())
        return;
    SpeechSynthesis* synthesis = DOMWindowSpeechSynthesis::speechSynthesis(document->domWindow());
    if (!synthesis)
        return;
    
    synthesis->setPlatformSynthesizer(std::make_unique<PlatformSpeechSynthesizerMock>(synthesis));
}
#endif

#if ENABLE(MEDIA_STREAM)
void Internals::enableMockRTCPeerConnectionHandler()
{
    RTCPeerConnectionHandler::create = RTCPeerConnectionHandlerMock::create;
}
#endif

Ref<ClientRect> Internals::absoluteCaretBounds(ExceptionCode& ec)
{
    Document* document = contextDocument();
    if (!document || !document->frame()) {
        ec = INVALID_ACCESS_ERR;
        return ClientRect::create();
    }

    return ClientRect::create(document->frame()->selection().absoluteCaretBounds());
}

Ref<ClientRect> Internals::boundingBox(Element* element, ExceptionCode& ec)
{
    if (!element) {
        ec = INVALID_ACCESS_ERR;
        return ClientRect::create();
    }

    element->document().updateLayoutIgnorePendingStylesheets();
    auto renderer = element->renderer();
    if (!renderer)
        return ClientRect::create();
    return ClientRect::create(renderer->absoluteBoundingBoxRectIgnoringTransforms());
}

Ref<ClientRectList> Internals::inspectorHighlightRects(ExceptionCode& ec)
{
    Document* document = contextDocument();
    if (!document || !document->page()) {
        ec = INVALID_ACCESS_ERR;
        return ClientRectList::create();
    }

    Highlight highlight;
    document->page()->inspectorController().getHighlight(highlight, InspectorOverlay::CoordinateSystem::View);
    return ClientRectList::create(highlight.quads);
}

String Internals::inspectorHighlightObject(ExceptionCode& ec)
{
    Document* document = contextDocument();
    if (!document || !document->page()) {
        ec = INVALID_ACCESS_ERR;
        return String();
    }

    return document->page()->inspectorController().buildObjectForHighlightedNodes()->toJSONString();
}

unsigned Internals::markerCountForNode(Node* node, const String& markerType, ExceptionCode& ec)
{
    if (!node) {
        ec = INVALID_ACCESS_ERR;
        return 0;
    }

    DocumentMarker::MarkerTypes markerTypes = 0;
    if (!markerTypesFrom(markerType, markerTypes)) {
        ec = SYNTAX_ERR;
        return 0;
    }

    node->document().frame()->editor().updateEditorUINowIfScheduled();

    return node->document().markers().markersFor(node, markerTypes).size();
}

RenderedDocumentMarker* Internals::markerAt(Node* node, const String& markerType, unsigned index, ExceptionCode& ec)
{
    node->document().updateLayoutIgnorePendingStylesheets();
    if (!node) {
        ec = INVALID_ACCESS_ERR;
        return nullptr;
    }

    DocumentMarker::MarkerTypes markerTypes = 0;
    if (!markerTypesFrom(markerType, markerTypes)) {
        ec = SYNTAX_ERR;
        return nullptr;
    }

    node->document().frame()->editor().updateEditorUINowIfScheduled();

    Vector<RenderedDocumentMarker*> markers = node->document().markers().markersFor(node, markerTypes);
    if (markers.size() <= index)
        return nullptr;
    return markers[index];
}

PassRefPtr<Range> Internals::markerRangeForNode(Node* node, const String& markerType, unsigned index, ExceptionCode& ec)
{
    RenderedDocumentMarker* marker = markerAt(node, markerType, index, ec);
    if (!marker)
        return nullptr;
    return Range::create(node->document(), node, marker->startOffset(), node, marker->endOffset());
}

String Internals::markerDescriptionForNode(Node* node, const String& markerType, unsigned index, ExceptionCode& ec)
{
    RenderedDocumentMarker* marker = markerAt(node, markerType, index, ec);
    if (!marker)
        return String();
    return marker->description();
}

void Internals::addTextMatchMarker(const Range* range, bool isActive)
{
    range->ownerDocument().updateLayoutIgnorePendingStylesheets();
    range->ownerDocument().markers().addTextMatchMarker(range, isActive);
}

void Internals::setMarkedTextMatchesAreHighlighted(bool flag, ExceptionCode& ec)
{
    Document* document = contextDocument();
    if (!document || !document->frame()) {
        ec = INVALID_ACCESS_ERR;
        return;
    }
    document->frame()->editor().setMarkedTextMatchesAreHighlighted(flag);
}

void Internals::invalidateFontCache()
{
    FontCache::singleton().invalidate();
}

void Internals::setScrollViewPosition(long x, long y, ExceptionCode& ec)
{
    Document* document = contextDocument();
    if (!document || !document->view()) {
        ec = INVALID_ACCESS_ERR;
        return;
    }

    FrameView* frameView = document->view();
    bool constrainsScrollingToContentEdgeOldValue = frameView->constrainsScrollingToContentEdge();
    bool scrollbarsSuppressedOldValue = frameView->scrollbarsSuppressed();

    frameView->setConstrainsScrollingToContentEdge(false);
    frameView->setScrollbarsSuppressed(false);
    frameView->setScrollOffsetFromInternals(IntPoint(x, y));
    frameView->setScrollbarsSuppressed(scrollbarsSuppressedOldValue);
    frameView->setConstrainsScrollingToContentEdge(constrainsScrollingToContentEdgeOldValue);
}

void Internals::setViewBaseBackgroundColor(const String& colorValue, ExceptionCode& ec)
{
    Document* document = contextDocument();
    if (!document || !document->view()) {
        ec = INVALID_ACCESS_ERR;
        return;
    }

    document->view()->setBaseBackgroundColor(Color(colorValue));
}

void Internals::setPagination(const String& mode, int gap, int pageLength, ExceptionCode& ec)
{
    Document* document = contextDocument();
    if (!document || !document->page()) {
        ec = INVALID_ACCESS_ERR;
        return;
    }
    Page* page = document->page();

    Pagination pagination;
    if (mode == "Unpaginated")
        pagination.mode = Pagination::Unpaginated;
    else if (mode == "LeftToRightPaginated")
        pagination.mode = Pagination::LeftToRightPaginated;
    else if (mode == "RightToLeftPaginated")
        pagination.mode = Pagination::RightToLeftPaginated;
    else if (mode == "TopToBottomPaginated")
        pagination.mode = Pagination::TopToBottomPaginated;
    else if (mode == "BottomToTopPaginated")
        pagination.mode = Pagination::BottomToTopPaginated;
    else {
        ec = SYNTAX_ERR;
        return;
    }

    pagination.gap = gap;
    pagination.pageLength = pageLength;
    page->setPagination(pagination);
}

String Internals::configurationForViewport(float devicePixelRatio, int deviceWidth, int deviceHeight, int availableWidth, int availableHeight, ExceptionCode& ec)
{
    Document* document = contextDocument();
    if (!document || !document->page()) {
        ec = INVALID_ACCESS_ERR;
        return String();
    }
    Page* page = document->page();

    const int defaultLayoutWidthForNonMobilePages = 980;

    ViewportArguments arguments = page->viewportArguments();
    ViewportAttributes attributes = computeViewportAttributes(arguments, defaultLayoutWidthForNonMobilePages, deviceWidth, deviceHeight, devicePixelRatio, IntSize(availableWidth, availableHeight));
    restrictMinimumScaleFactorToViewportSize(attributes, IntSize(availableWidth, availableHeight), devicePixelRatio);
    restrictScaleFactorToInitialScaleIfNotUserScalable(attributes);

    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");
}

bool Internals::wasLastChangeUserEdit(Element* textField, ExceptionCode& ec)
{
    if (!textField) {
        ec = INVALID_ACCESS_ERR;
        return false;
    }

    if (HTMLInputElement* inputElement = textField->toInputElement())
        return inputElement->lastChangeWasUserEdit();

    if (is<HTMLTextAreaElement>(*textField))
        return downcast<HTMLTextAreaElement>(*textField).lastChangeWasUserEdit();

    ec = INVALID_NODE_TYPE_ERR;
    return false;
}

bool Internals::elementShouldAutoComplete(Element* element, ExceptionCode& ec)
{
    if (!element) {
        ec = INVALID_ACCESS_ERR;
        return false;
    }

    if (HTMLInputElement* inputElement = element->toInputElement())
        return inputElement->shouldAutocomplete();

    ec = INVALID_NODE_TYPE_ERR;
    return false;
}

void Internals::setEditingValue(Element* element, const String& value, ExceptionCode& ec)
{
    if (!element) {
        ec = INVALID_ACCESS_ERR;
        return;
    }

    HTMLInputElement* inputElement = element->toInputElement();
    if (!inputElement) {
        ec = INVALID_NODE_TYPE_ERR;
        return;
    }

    inputElement->setEditingValue(value);
}

void Internals::setAutofilled(Element* element, bool enabled, ExceptionCode& ec)
{
    HTMLInputElement* inputElement = element->toInputElement();
    if (!inputElement) {
        ec = INVALID_ACCESS_ERR;
        return;
    }
    inputElement->setAutoFilled(enabled);
}

void Internals::setShowAutoFillButton(Element* element, bool show, ExceptionCode& ec)
{
    HTMLInputElement* inputElement = element->toInputElement();
    if (!inputElement) {
        ec = INVALID_ACCESS_ERR;
        return;
    }
    inputElement->setShowAutoFillButton(show);
}


void Internals::scrollElementToRect(Element* element, long x, long y, long w, long h, ExceptionCode& ec)
{
    if (!element || !element->document().view()) {
        ec = INVALID_ACCESS_ERR;
        return;
    }
    FrameView* frameView = element->document().view();
    frameView->scrollElementToRect(*element, IntRect(x, y, w, h));
}

void Internals::paintControlTints(ExceptionCode& ec)
{
    Document* document = contextDocument();
    if (!document || !document->view()) {
        ec = INVALID_ACCESS_ERR;
        return;
    }

    FrameView* frameView = document->view();
    frameView->paintControlTints();
}

PassRefPtr<Range> Internals::rangeFromLocationAndLength(Element* scope, int rangeLocation, int rangeLength, ExceptionCode& ec)
{
    if (!scope) {
        ec = INVALID_ACCESS_ERR;
        return 0;
    }

    return TextIterator::rangeFromLocationAndLength(scope, rangeLocation, rangeLength);
}

unsigned Internals::locationFromRange(Element* scope, const Range* range, ExceptionCode& ec)
{
    if (!scope || !range) {
        ec = INVALID_ACCESS_ERR;
        return 0;
    }

    size_t location = 0;
    size_t unusedLength = 0;
    TextIterator::getLocationAndLengthFromRange(scope, range, location, unusedLength);
    return location;
}

unsigned Internals::lengthFromRange(Element* scope, const Range* range, ExceptionCode& ec)
{
    if (!scope || !range) {
        ec = INVALID_ACCESS_ERR;
        return 0;
    }

    size_t unusedLocation = 0;
    size_t length = 0;
    TextIterator::getLocationAndLengthFromRange(scope, range, unusedLocation, length);
    return length;
}

String Internals::rangeAsText(const Range* range, ExceptionCode& ec)
{
    if (!range) {
        ec = INVALID_ACCESS_ERR;
        return String();
    }

    return range->text();
}

PassRefPtr<Range> Internals::subrange(Range* range, int rangeLocation, int rangeLength, ExceptionCode& ec)
{
    if (!range) {
        ec = INVALID_ACCESS_ERR;
        return 0;
    }

    return TextIterator::subrange(range, rangeLocation, rangeLength);
}

RefPtr<Range> Internals::rangeForDictionaryLookupAtLocation(int x, int y, ExceptionCode& ec)
{
#if PLATFORM(MAC)
    Document* document = contextDocument();
    if (!document || !document->frame()) {
        ec = INVALID_ACCESS_ERR;
        return nullptr;
    }

    document->updateLayoutIgnorePendingStylesheets();
    
    HitTestResult result = document->frame()->mainFrame().eventHandler().hitTestResultAtPoint(IntPoint(x, y));
    NSDictionary *options = nullptr;
    return DictionaryLookup::rangeAtHitTestResult(result, &options);
#else
    UNUSED_PARAM(x);
    UNUSED_PARAM(y);
    ec = INVALID_ACCESS_ERR;
    return nullptr;
#endif
}

void Internals::setDelegatesScrolling(bool enabled, ExceptionCode& ec)
{
    Document* document = contextDocument();
    // Delegate scrolling is valid only on mainframe's view.
    if (!document || !document->view() || !document->page() || &document->page()->mainFrame() != document->frame()) {
        ec = INVALID_ACCESS_ERR;
        return;
    }

    document->view()->setDelegatesScrolling(enabled);
}

int Internals::lastSpellCheckRequestSequence(ExceptionCode& ec)
{
    Document* document = contextDocument();
    if (!document || !document->frame()) {
        ec = INVALID_ACCESS_ERR;
        return -1;
    }

    return document->frame()->editor().spellChecker().lastRequestSequence();
}

int Internals::lastSpellCheckProcessedSequence(ExceptionCode& ec)
{
    Document* document = contextDocument();
    if (!document || !document->frame()) {
        ec = INVALID_ACCESS_ERR;
        return -1;
    }

    return document->frame()->editor().spellChecker().lastProcessedSequence();
}

Vector<String> Internals::userPreferredLanguages() const
{
    return WebCore::userPreferredLanguages();
}

void Internals::setUserPreferredLanguages(const Vector<String>& languages)
{
    WebCore::overrideUserPreferredLanguages(languages);
}

Vector<String> Internals::userPreferredAudioCharacteristics() const
{
    Document* document = contextDocument();
    if (!document || !document->page())
        return Vector<String>();
#if ENABLE(VIDEO_TRACK)
    return document->page()->group().captionPreferences()->preferredAudioCharacteristics();
#else
    return Vector<String>();
#endif
}

void Internals::setUserPreferredAudioCharacteristic(const String& characteristic)
{
    Document* document = contextDocument();
    if (!document || !document->page())
        return;
#if ENABLE(VIDEO_TRACK)
    document->page()->group().captionPreferences()->setPreferredAudioCharacteristic(characteristic);
#else
    UNUSED_PARAM(characteristic);
#endif
}

unsigned Internals::wheelEventHandlerCount(ExceptionCode& ec)
{
    Document* document = contextDocument();
    if (!document) {
        ec = INVALID_ACCESS_ERR;
        return 0;
    }

    return document->wheelEventHandlerCount();
}

unsigned Internals::touchEventHandlerCount(ExceptionCode& ec)
{
    Document* document = contextDocument();
    if (!document) {
        ec = INVALID_ACCESS_ERR;
        return 0;
    }

    return document->touchEventHandlerCount();
}

// FIXME: Remove the document argument. It is almost always the same as
// contextDocument(), with the exception of a few tests that pass a
// different document, and could just make the call through another Internals
// instance instead.
PassRefPtr<NodeList> Internals::nodesFromRect(Document* document, int centerX, int centerY, unsigned topPadding, unsigned rightPadding,
    unsigned bottomPadding, unsigned leftPadding, bool ignoreClipping, bool allowShadowContent, bool allowChildFrameContent, ExceptionCode& ec) const
{
    if (!document || !document->frame() || !document->frame()->view()) {
        ec = INVALID_ACCESS_ERR;
        return 0;
    }

    Frame* frame = document->frame();
    FrameView* frameView = document->view();
    RenderView* renderView = document->renderView();
    if (!renderView)
        return 0;

    document->updateLayoutIgnorePendingStylesheets();

    float zoomFactor = frame->pageZoomFactor();
    LayoutPoint point(centerX * zoomFactor + frameView->scrollX(), centerY * zoomFactor + frameView->scrollY());

    HitTestRequest::HitTestRequestType hitType = HitTestRequest::ReadOnly | HitTestRequest::Active;
    if (ignoreClipping)
        hitType |= HitTestRequest::IgnoreClipping;
    if (!allowShadowContent)
        hitType |= HitTestRequest::DisallowShadowContent;
    if (allowChildFrameContent)
        hitType |= HitTestRequest::AllowChildFrameContent;

    HitTestRequest request(hitType);

    // When ignoreClipping is false, this method returns null for coordinates outside of the viewport.
    if (!request.ignoreClipping() && !frameView->visibleContentRect().intersects(HitTestLocation::rectForPoint(point, topPadding, rightPadding, bottomPadding, leftPadding)))
        return 0;

    Vector<Ref<Node>> matches;

    // Need padding to trigger a rect based hit test, but we want to return a NodeList
    // so we special case this.
    if (!topPadding && !rightPadding && !bottomPadding && !leftPadding) {
        HitTestResult result(point);
        renderView->hitTest(request, result);
        if (result.innerNode())
            matches.append(*result.innerNode()->deprecatedShadowAncestorNode());
    } else {
        HitTestResult result(point, topPadding, rightPadding, bottomPadding, leftPadding);
        renderView->hitTest(request, result);
        
        const HitTestResult::NodeSet& nodeSet = result.rectBasedTestResult();
        matches.reserveInitialCapacity(nodeSet.size());
        for (auto& node : nodeSet)
            matches.uncheckedAppend(*node);
    }

    return StaticNodeList::adopt(matches);
}

class GetCallerCodeBlockFunctor {
public:
    GetCallerCodeBlockFunctor()
        : m_iterations(0)
        , m_codeBlock(0)
    {
    }

    StackVisitor::Status operator()(StackVisitor& visitor)
    {
        ++m_iterations;
        if (m_iterations < 2)
            return StackVisitor::Continue;

        m_codeBlock = visitor->codeBlock();
        return StackVisitor::Done;
    }

    CodeBlock* codeBlock() const { return m_codeBlock; }

private:
    int m_iterations;
    CodeBlock* m_codeBlock;
};

String Internals::parserMetaData(Deprecated::ScriptValue value)
{
    JSC::VM& vm = contextDocument()->vm();
    JSC::ExecState* exec = vm.topCallFrame;
    JSC::JSValue code = value.jsValue();
    ScriptExecutable* executable;

    if (!code || code.isNull() || code.isUndefined()) {
        GetCallerCodeBlockFunctor iter;
        exec->iterate(iter);
        CodeBlock* codeBlock = iter.codeBlock();
        executable = codeBlock->ownerScriptExecutable();
    } else if (code.isFunction()) {
        JSFunction* funcObj = JSC::jsCast<JSFunction*>(code.toObject(exec));
        executable = funcObj->jsExecutable();
    } else
        return String();

    unsigned startLine = executable->firstLine();
    unsigned startColumn = executable->startColumn();
    unsigned endLine = executable->lastLine();
    unsigned endColumn = executable->endColumn();

    StringBuilder result;

    if (executable->isFunctionExecutable()) {
        FunctionExecutable* funcExecutable = reinterpret_cast<FunctionExecutable*>(executable);
        String inferredName = funcExecutable->inferredName().string();
        result.appendLiteral("function \"");
        result.append(inferredName);
        result.append('"');
    } else if (executable->isEvalExecutable())
        result.appendLiteral("eval");
    else {
        ASSERT(executable->isProgramExecutable());
        result.appendLiteral("program");
    }

    result.appendLiteral(" { ");
    result.appendNumber(startLine);
    result.append(':');
    result.appendNumber(startColumn);
    result.appendLiteral(" - ");
    result.appendNumber(endLine);
    result.append(':');
    result.appendNumber(endColumn);
    result.appendLiteral(" }");

    return result.toString();
}

void Internals::setBatteryStatus(const String& eventType, bool charging, double chargingTime, double dischargingTime, double level, ExceptionCode& ec)
{
    Document* document = contextDocument();
    if (!document || !document->page()) {
        ec = INVALID_ACCESS_ERR;
        return;
    }

#if ENABLE(BATTERY_STATUS)
    BatteryController::from(document->page())->didChangeBatteryStatus(eventType, BatteryStatus::create(charging, chargingTime, dischargingTime, level));
#else
    UNUSED_PARAM(eventType);
    UNUSED_PARAM(charging);
    UNUSED_PARAM(chargingTime);
    UNUSED_PARAM(dischargingTime);
    UNUSED_PARAM(level);
#endif
}

void Internals::setDeviceProximity(const String& eventType, double value, double min, double max, ExceptionCode& ec)
{
    Document* document = contextDocument();
    if (!document || !document->page()) {
        ec = INVALID_ACCESS_ERR;
        return;
    }

#if ENABLE(PROXIMITY_EVENTS)
    DeviceProximityController::from(document->page())->didChangeDeviceProximity(value, min, max);
#else
    UNUSED_PARAM(eventType);
    UNUSED_PARAM(value);
    UNUSED_PARAM(min);
    UNUSED_PARAM(max);
#endif
}

void Internals::updateEditorUINowIfScheduled()
{
    if (Document* document = contextDocument()) {
        if (Frame* frame = document->frame())
            frame->editor().updateEditorUINowIfScheduled();
    }
}

bool Internals::hasSpellingMarker(int from, int length, ExceptionCode&)
{
    Document* document = contextDocument();
    if (!document || !document->frame())
        return false;

    updateEditorUINowIfScheduled();

    return document->frame()->editor().selectionStartHasMarkerFor(DocumentMarker::Spelling, from, length);
}
    
bool Internals::hasAutocorrectedMarker(int from, int length, ExceptionCode&)
{
    Document* document = contextDocument();
    if (!document || !document->frame())
        return false;

    updateEditorUINowIfScheduled();

    return document->frame()->editor().selectionStartHasMarkerFor(DocumentMarker::Autocorrected, from, length);
}

void Internals::setContinuousSpellCheckingEnabled(bool enabled, ExceptionCode&)
{
    if (!contextDocument() || !contextDocument()->frame())
        return;

    if (enabled != contextDocument()->frame()->editor().isContinuousSpellCheckingEnabled())
        contextDocument()->frame()->editor().toggleContinuousSpellChecking();
}

void Internals::setAutomaticQuoteSubstitutionEnabled(bool enabled, ExceptionCode&)
{
    if (!contextDocument() || !contextDocument()->frame())
        return;

#if USE(AUTOMATIC_TEXT_REPLACEMENT)
    if (enabled != contextDocument()->frame()->editor().isAutomaticQuoteSubstitutionEnabled())
        contextDocument()->frame()->editor().toggleAutomaticQuoteSubstitution();
#else
    UNUSED_PARAM(enabled);
#endif
}

void Internals::setAutomaticLinkDetectionEnabled(bool enabled, ExceptionCode&)
{
    if (!contextDocument() || !contextDocument()->frame())
        return;

#if USE(AUTOMATIC_TEXT_REPLACEMENT)
    if (enabled != contextDocument()->frame()->editor().isAutomaticLinkDetectionEnabled())
        contextDocument()->frame()->editor().toggleAutomaticLinkDetection();
#else
    UNUSED_PARAM(enabled);
#endif
}

void Internals::setAutomaticDashSubstitutionEnabled(bool enabled, ExceptionCode&)
{
    if (!contextDocument() || !contextDocument()->frame())
        return;

#if USE(AUTOMATIC_TEXT_REPLACEMENT)
    if (enabled != contextDocument()->frame()->editor().isAutomaticDashSubstitutionEnabled())
        contextDocument()->frame()->editor().toggleAutomaticDashSubstitution();
#else
    UNUSED_PARAM(enabled);
#endif
}

void Internals::setAutomaticTextReplacementEnabled(bool enabled, ExceptionCode&)
{
    if (!contextDocument() || !contextDocument()->frame())
        return;

#if USE(AUTOMATIC_TEXT_REPLACEMENT)
    if (enabled != contextDocument()->frame()->editor().isAutomaticTextReplacementEnabled())
        contextDocument()->frame()->editor().toggleAutomaticTextReplacement();
#else
    UNUSED_PARAM(enabled);
#endif
}

void Internals::setAutomaticSpellingCorrectionEnabled(bool enabled, ExceptionCode&)
{
    if (!contextDocument() || !contextDocument()->frame())
        return;

#if USE(AUTOMATIC_TEXT_REPLACEMENT)
    if (enabled != contextDocument()->frame()->editor().isAutomaticSpellingCorrectionEnabled())
        contextDocument()->frame()->editor().toggleAutomaticSpellingCorrection();
#else
    UNUSED_PARAM(enabled);
#endif
}

bool Internals::isOverwriteModeEnabled(ExceptionCode&)
{
    Document* document = contextDocument();
    if (!document || !document->frame())
        return false;

    return document->frame()->editor().isOverwriteModeEnabled();
}

void Internals::toggleOverwriteModeEnabled(ExceptionCode&)
{
    Document* document = contextDocument();
    if (!document || !document->frame())
        return;

    document->frame()->editor().toggleOverwriteModeEnabled();
}

unsigned Internals::countMatchesForText(const String& text, unsigned findOptions, const String& markMatches, ExceptionCode&)
{
    Document* document = contextDocument();
    if (!document || !document->frame())
        return 0;

    bool mark = markMatches == "mark";
    return document->frame()->editor().countMatchesForText(text, nullptr, findOptions, 1000, mark, nullptr);
}

const ProfilesArray& Internals::consoleProfiles() const
{
    return contextDocument()->page()->console().profiles();
}

unsigned Internals::numberOfLiveNodes() const
{
    unsigned nodeCount = 0;
    for (auto* document : Document::allDocuments())
        nodeCount += document->referencingNodeCount();
    return nodeCount;
}

unsigned Internals::numberOfLiveDocuments() const
{
    return Document::allDocuments().size();
}

Vector<String> Internals::consoleMessageArgumentCounts() const
{
    Document* document = contextDocument();
    if (!document || !document->page())
        return Vector<String>();

    InstrumentingAgents* instrumentingAgents = InspectorInstrumentation::instrumentingAgentsForPage(document->page());
    if (!instrumentingAgents)
        return Vector<String>();

    InspectorConsoleAgent* consoleAgent = instrumentingAgents->webConsoleAgent();
    if (!consoleAgent)
        return Vector<String>();

    Vector<unsigned> counts = consoleAgent->consoleMessageArgumentCounts();
    Vector<String> result(counts.size());
    for (size_t i = 0; i < counts.size(); i++)
        result[i] = String::number(counts[i]);
    return result;
}

PassRefPtr<DOMWindow> Internals::openDummyInspectorFrontend(const String& url)
{
    Page* page = contextDocument()->frame()->page();
    ASSERT(page);

    DOMWindow* window = page->mainFrame().document()->domWindow();
    ASSERT(window);

    m_frontendWindow = window->open(url, "", "", *window, *window);
    ASSERT(m_frontendWindow);

    Page* frontendPage = m_frontendWindow->document()->page();
    ASSERT(frontendPage);

    m_frontendClient = std::make_unique<InspectorFrontendClientDummy>(&page->inspectorController(), frontendPage);
    frontendPage->inspectorController().setInspectorFrontendClient(m_frontendClient.get());

    bool isAutomaticInspection = false;
    m_frontendChannel = std::make_unique<InspectorFrontendChannelDummy>(frontendPage);
    page->inspectorController().connectFrontend(m_frontendChannel.get(), isAutomaticInspection);

    return m_frontendWindow;
}

void Internals::closeDummyInspectorFrontend()
{
    Page* page = contextDocument()->frame()->page();
    ASSERT(page);
    ASSERT(m_frontendWindow);

    page->inspectorController().disconnectFrontend(Inspector::DisconnectReason::InspectorDestroyed);

    m_frontendClient = nullptr;
    m_frontendChannel = nullptr;

    m_frontendWindow->close(m_frontendWindow->scriptExecutionContext());
    m_frontendWindow = nullptr;
}

void Internals::setJavaScriptProfilingEnabled(bool enabled, ExceptionCode& ec)
{
    Page* page = contextDocument()->frame()->page();
    if (!page) {
        ec = INVALID_ACCESS_ERR;
        return;
    }

    page->inspectorController().setProfilerEnabled(enabled);
}

void Internals::setInspectorIsUnderTest(bool isUnderTest, ExceptionCode& ec)
{
    Page* page = contextDocument()->frame()->page();
    if (!page) {
        ec = INVALID_ACCESS_ERR;
        return;
    }

    page->inspectorController().setIsUnderTest(isUnderTest);
}

bool Internals::hasGrammarMarker(int from, int length, ExceptionCode&)
{
    Document* document = contextDocument();
    if (!document || !document->frame())
        return false;

    return document->frame()->editor().selectionStartHasMarkerFor(DocumentMarker::Grammar, from, length);
}

unsigned Internals::numberOfScrollableAreas(ExceptionCode&)
{
    Document* document = contextDocument();
    if (!document || !document->frame())
        return 0;

    unsigned count = 0;
    Frame* frame = document->frame();
    if (frame->view()->scrollableAreas())
        count += frame->view()->scrollableAreas()->size();

    for (Frame* child = frame->tree().firstChild(); child; child = child->tree().nextSibling()) {
        if (child->view() && child->view()->scrollableAreas())
            count += child->view()->scrollableAreas()->size();
    }

    return count;
}
    
bool Internals::isPageBoxVisible(int pageNumber, ExceptionCode& ec)
{
    Document* document = contextDocument();
    if (!document) {
        ec = INVALID_ACCESS_ERR;
        return false;
    }

    return document->isPageBoxVisible(pageNumber);
}

// FIXME: Remove the document argument. It is almost always the same as
// contextDocument(), with the exception of a few tests that pass a
// different document, and could just make the call through another Internals
// instance instead.
String Internals::layerTreeAsText(Document* document, ExceptionCode& ec) const
{
    return layerTreeAsText(document, 0, ec);
}

String Internals::layerTreeAsText(Document* document, unsigned flags, ExceptionCode& ec) const
{
    if (!document || !document->frame()) {
        ec = INVALID_ACCESS_ERR;
        return String();
    }

    LayerTreeFlags layerTreeFlags = 0;
    if (flags & LAYER_TREE_INCLUDES_VISIBLE_RECTS)
        layerTreeFlags |= LayerTreeFlagsIncludeVisibleRects;
    if (flags & LAYER_TREE_INCLUDES_TILE_CACHES)
        layerTreeFlags |= LayerTreeFlagsIncludeTileCaches;
    if (flags & LAYER_TREE_INCLUDES_REPAINT_RECTS)
        layerTreeFlags |= LayerTreeFlagsIncludeRepaintRects;
    if (flags & LAYER_TREE_INCLUDES_PAINTING_PHASES)
        layerTreeFlags |= LayerTreeFlagsIncludePaintingPhases;
    if (flags & LAYER_TREE_INCLUDES_CONTENT_LAYERS)
        layerTreeFlags |= LayerTreeFlagsIncludeContentLayers;

    return document->frame()->layerTreeAsText(layerTreeFlags);
}

String Internals::repaintRectsAsText(ExceptionCode& ec) const
{
    Document* document = contextDocument();
    if (!document || !document->frame()) {
        ec = INVALID_ACCESS_ERR;
        return String();
    }

    return document->frame()->trackedRepaintRectsAsText();
}

String Internals::scrollingStateTreeAsText(ExceptionCode& ec) const
{
    Document* document = contextDocument();
    if (!document || !document->frame()) {
        ec = INVALID_ACCESS_ERR;
        return String();
    }

    Page* page = document->page();
    if (!page)
        return String();

    return page->scrollingStateTreeAsText();
}

String Internals::mainThreadScrollingReasons(ExceptionCode& ec) const
{
    Document* document = contextDocument();
    if (!document || !document->frame()) {
        ec = INVALID_ACCESS_ERR;
        return String();
    }

    Page* page = document->page();
    if (!page)
        return String();

    return page->synchronousScrollingReasonsAsText();
}

RefPtr<ClientRectList> Internals::nonFastScrollableRects(ExceptionCode& ec) const
{
    Document* document = contextDocument();
    if (!document || !document->frame()) {
        ec = INVALID_ACCESS_ERR;
        return nullptr;
    }

    Page* page = document->page();
    if (!page)
        return nullptr;

    return page->nonFastScrollableRects();
}

void Internals::garbageCollectDocumentResources(ExceptionCode& ec) const
{
    Document* document = contextDocument();
    if (!document) {
        ec = INVALID_ACCESS_ERR;
        return;
    }
    document->cachedResourceLoader().garbageCollectDocumentResources();
}

void Internals::allowRoundingHacks() const
{
    TextRun::setAllowsRoundingHacks(true);
}

void Internals::insertAuthorCSS(const String& css, ExceptionCode& ec) const
{
    Document* document = contextDocument();
    if (!document) {
        ec = INVALID_ACCESS_ERR;
        return;
    }

    auto parsedSheet = StyleSheetContents::create(*document);
    parsedSheet.get().setIsUserStyleSheet(false);
    parsedSheet.get().parseString(css);
    document->styleSheetCollection().addAuthorSheet(WTF::move(parsedSheet));
}

void Internals::insertUserCSS(const String& css, ExceptionCode& ec) const
{
    Document* document = contextDocument();
    if (!document) {
        ec = INVALID_ACCESS_ERR;
        return;
    }

    auto parsedSheet = StyleSheetContents::create(*document);
    parsedSheet.get().setIsUserStyleSheet(true);
    parsedSheet.get().parseString(css);
    document->styleSheetCollection().addUserSheet(WTF::move(parsedSheet));
}

String Internals::counterValue(Element* element)
{
    if (!element)
        return String();

    return counterValueForElement(element);
}

int Internals::pageNumber(Element* element, float pageWidth, float pageHeight)
{
    if (!element)
        return 0;

    return PrintContext::pageNumberForElement(element, FloatSize(pageWidth, pageHeight));
}

Vector<String> Internals::shortcutIconURLs() const
{
    Vector<String> vector;

    if (!frame())
        return vector;

    auto string = frame()->loader().icon().url().string();
    if (!string.isNull())
        vector.append(string);
    return vector;
}

int Internals::numberOfPages(float pageWidth, float pageHeight)
{
    if (!frame())
        return -1;

    return PrintContext::numberOfPages(frame(), FloatSize(pageWidth, pageHeight));
}

String Internals::pageProperty(String propertyName, int pageNumber, ExceptionCode& ec) const
{
    if (!frame()) {
        ec = INVALID_ACCESS_ERR;
        return String();
    }

    return PrintContext::pageProperty(frame(), propertyName.utf8().data(), pageNumber);
}

String Internals::pageSizeAndMarginsInPixels(int pageNumber, int width, int height, int marginTop, int marginRight, int marginBottom, int marginLeft, ExceptionCode& ec) const
{
    if (!frame()) {
        ec = INVALID_ACCESS_ERR;
        return String();
    }

    return PrintContext::pageSizeAndMarginsInPixels(frame(), pageNumber, width, height, marginTop, marginRight, marginBottom, marginLeft);
}

void Internals::setPageScaleFactor(float scaleFactor, int x, int y, ExceptionCode& ec)
{
    Document* document = contextDocument();
    if (!document || !document->page()) {
        ec = INVALID_ACCESS_ERR;
        return;
    }
    Page* page = document->page();
    page->setPageScaleFactor(scaleFactor, IntPoint(x, y));
}

void Internals::setPageZoomFactor(float zoomFactor, ExceptionCode& ec)
{
    Document* document = contextDocument();
    if (!document || !document->frame()) {
        ec = INVALID_ACCESS_ERR;
        return;
    }
    Frame* frame = document->frame();
    frame->setPageZoomFactor(zoomFactor);
}

void Internals::setTextZoomFactor(float zoomFactor, ExceptionCode& ec)
{
    Document* document = contextDocument();
    if (!document || !document->frame()) {
        ec = INVALID_ACCESS_ERR;
        return;
    }
    Frame* frame = document->frame();
    frame->setTextZoomFactor(zoomFactor);
}

void Internals::setUseFixedLayout(bool useFixedLayout, ExceptionCode& ec)
{
    Document* document = contextDocument();
    if (!document || !document->view()) {
        ec = INVALID_ACCESS_ERR;
        return;
    }
    FrameView* frameView = document->view();
    frameView->setUseFixedLayout(useFixedLayout);
}

void Internals::setFixedLayoutSize(int width, int height, ExceptionCode& ec)
{
    Document* document = contextDocument();
    if (!document || !document->view()) {
        ec = INVALID_ACCESS_ERR;
        return;
    }
    FrameView* frameView = document->view();
    frameView->setFixedLayoutSize(IntSize(width, height));
}

void Internals::setHeaderHeight(float height)
{
    Document* document = contextDocument();
    if (!document || !document->view())
        return;

    FrameView* frameView = document->view();
    frameView->setHeaderHeight(height);
}

void Internals::setFooterHeight(float height)
{
    Document* document = contextDocument();
    if (!document || !document->view())
        return;

    FrameView* frameView = document->view();
    frameView->setFooterHeight(height);
}
    
void Internals::setTopContentInset(float contentInset)
{
    Document* document = contextDocument();
    if (!document)
        return;
    
    Page* page = document->page();
    page->setTopContentInset(contentInset);
}

#if ENABLE(FULLSCREEN_API)
void Internals::webkitWillEnterFullScreenForElement(Element* element)
{
    Document* document = contextDocument();
    if (!document)
        return;
    document->webkitWillEnterFullScreenForElement(element);
}

void Internals::webkitDidEnterFullScreenForElement(Element* element)
{
    Document* document = contextDocument();
    if (!document)
        return;
    document->webkitDidEnterFullScreenForElement(element);
}

void Internals::webkitWillExitFullScreenForElement(Element* element)
{
    Document* document = contextDocument();
    if (!document)
        return;
    document->webkitWillExitFullScreenForElement(element);
}

void Internals::webkitDidExitFullScreenForElement(Element* element)
{
    Document* document = contextDocument();
    if (!document)
        return;
    document->webkitDidExitFullScreenForElement(element);
}
#endif

void Internals::setApplicationCacheOriginQuota(unsigned long long quota)
{
    Document* document = contextDocument();
    if (!document)
        return;
    ApplicationCacheStorage::singleton().storeUpdatedQuotaForOrigin(document->securityOrigin(), quota);
}

void Internals::registerURLSchemeAsBypassingContentSecurityPolicy(const String& scheme)
{
    SchemeRegistry::registerURLSchemeAsBypassingContentSecurityPolicy(scheme);
}

void Internals::removeURLSchemeRegisteredAsBypassingContentSecurityPolicy(const String& scheme)
{
    SchemeRegistry::removeURLSchemeRegisteredAsBypassingContentSecurityPolicy(scheme);
}

PassRefPtr<MallocStatistics> Internals::mallocStatistics() const
{
    return MallocStatistics::create();
}

PassRefPtr<TypeConversions> Internals::typeConversions() const
{
    return TypeConversions::create();
}

PassRefPtr<MemoryInfo> Internals::memoryInfo() const
{
    return MemoryInfo::create();
}

Vector<String> Internals::getReferencedFilePaths() const
{
    frame()->loader().history().saveDocumentAndScrollState();
    return FormController::getReferencedFilePaths(frame()->loader().history().currentItem()->documentState());
}

void Internals::startTrackingRepaints(ExceptionCode& ec)
{
    Document* document = contextDocument();
    if (!document || !document->view()) {
        ec = INVALID_ACCESS_ERR;
        return;
    }

    FrameView* frameView = document->view();
    frameView->setTracksRepaints(true);
}

void Internals::stopTrackingRepaints(ExceptionCode& ec)
{
    Document* document = contextDocument();
    if (!document || !document->view()) {
        ec = INVALID_ACCESS_ERR;
        return;
    }

    FrameView* frameView = document->view();
    frameView->setTracksRepaints(false);
}

void Internals::startTrackingLayerFlushes(ExceptionCode& ec)
{
    Document* document = contextDocument();
    if (!document || !document->renderView()) {
        ec = INVALID_ACCESS_ERR;
        return;
    }

    document->renderView()->compositor().startTrackingLayerFlushes();
}

unsigned long Internals::layerFlushCount(ExceptionCode& ec)
{
    Document* document = contextDocument();
    if (!document || !document->renderView()) {
        ec = INVALID_ACCESS_ERR;
        return 0;
    }

    return document->renderView()->compositor().layerFlushCount();
}

void Internals::startTrackingStyleRecalcs(ExceptionCode& ec)
{
    Document* document = contextDocument();
    if (!document) {
        ec = INVALID_ACCESS_ERR;
        return;
    }
    document->startTrackingStyleRecalcs();
}

unsigned long Internals::styleRecalcCount(ExceptionCode& ec)
{
    Document* document = contextDocument();
    if (!document) {
        ec = INVALID_ACCESS_ERR;
        return 0;
    }
    
    return document->styleRecalcCount();
}

void Internals::startTrackingCompositingUpdates(ExceptionCode& ec)
{
    Document* document = contextDocument();
    if (!document || !document->renderView()) {
        ec = INVALID_ACCESS_ERR;
        return;
    }

    document->renderView()->compositor().startTrackingCompositingUpdates();
}

unsigned long Internals::compositingUpdateCount(ExceptionCode& ec)
{
    Document* document = contextDocument();
    if (!document || !document->renderView()) {
        ec = INVALID_ACCESS_ERR;
        return 0;
    }
    
    return document->renderView()->compositor().compositingUpdateCount();
}

void Internals::updateLayoutIgnorePendingStylesheetsAndRunPostLayoutTasks(ExceptionCode& ec)
{
    updateLayoutIgnorePendingStylesheetsAndRunPostLayoutTasks(nullptr, ec);
}

void Internals::updateLayoutIgnorePendingStylesheetsAndRunPostLayoutTasks(Node* node, ExceptionCode& ec)
{
    Document* document;
    if (!node)
        document = contextDocument();
    else if (is<Document>(*node))
        document = downcast<Document>(node);
    else if (is<HTMLIFrameElement>(*node))
        document = downcast<HTMLIFrameElement>(*node).contentDocument();
    else {
        ec = TypeError;
        return;
    }

    document->updateLayoutIgnorePendingStylesheets(Document::RunPostLayoutTasks::Synchronously);
}

unsigned Internals::layoutCount() const
{
    Document* document = contextDocument();
    if (!document || !document->view())
        return 0;
    return document->view()->layoutCount();
}

#if !PLATFORM(IOS)
static const char* cursorTypeToString(Cursor::Type cursorType)
{
    switch (cursorType) {
    case Cursor::Pointer: return "Pointer";
    case Cursor::Cross: return "Cross";
    case Cursor::Hand: return "Hand";
    case Cursor::IBeam: return "IBeam";
    case Cursor::Wait: return "Wait";
    case Cursor::Help: return "Help";
    case Cursor::EastResize: return "EastResize";
    case Cursor::NorthResize: return "NorthResize";
    case Cursor::NorthEastResize: return "NorthEastResize";
    case Cursor::NorthWestResize: return "NorthWestResize";
    case Cursor::SouthResize: return "SouthResize";
    case Cursor::SouthEastResize: return "SouthEastResize";
    case Cursor::SouthWestResize: return "SouthWestResize";
    case Cursor::WestResize: return "WestResize";
    case Cursor::NorthSouthResize: return "NorthSouthResize";
    case Cursor::EastWestResize: return "EastWestResize";
    case Cursor::NorthEastSouthWestResize: return "NorthEastSouthWestResize";
    case Cursor::NorthWestSouthEastResize: return "NorthWestSouthEastResize";
    case Cursor::ColumnResize: return "ColumnResize";
    case Cursor::RowResize: return "RowResize";
    case Cursor::MiddlePanning: return "MiddlePanning";
    case Cursor::EastPanning: return "EastPanning";
    case Cursor::NorthPanning: return "NorthPanning";
    case Cursor::NorthEastPanning: return "NorthEastPanning";
    case Cursor::NorthWestPanning: return "NorthWestPanning";
    case Cursor::SouthPanning: return "SouthPanning";
    case Cursor::SouthEastPanning: return "SouthEastPanning";
    case Cursor::SouthWestPanning: return "SouthWestPanning";
    case Cursor::WestPanning: return "WestPanning";
    case Cursor::Move: return "Move";
    case Cursor::VerticalText: return "VerticalText";
    case Cursor::Cell: return "Cell";
    case Cursor::ContextMenu: return "ContextMenu";
    case Cursor::Alias: return "Alias";
    case Cursor::Progress: return "Progress";
    case Cursor::NoDrop: return "NoDrop";
    case Cursor::Copy: return "Copy";
    case Cursor::None: return "None";
    case Cursor::NotAllowed: return "NotAllowed";
    case Cursor::ZoomIn: return "ZoomIn";
    case Cursor::ZoomOut: return "ZoomOut";
    case Cursor::Grab: return "Grab";
    case Cursor::Grabbing: return "Grabbing";
    case Cursor::Custom: return "Custom";
    }

    ASSERT_NOT_REACHED();
    return "UNKNOWN";
}
#endif

String Internals::getCurrentCursorInfo(ExceptionCode& ec)
{
    Document* document = contextDocument();
    if (!document || !document->frame()) {
        ec = INVALID_ACCESS_ERR;
        return String();
    }

#if !PLATFORM(IOS)
    Cursor cursor = document->frame()->eventHandler().currentMouseCursor();

    StringBuilder result;
    result.appendLiteral("type=");
    result.append(cursorTypeToString(cursor.type()));
    result.appendLiteral(" hotSpot=");
    result.appendNumber(cursor.hotSpot().x());
    result.append(',');
    result.appendNumber(cursor.hotSpot().y());
    if (cursor.image()) {
        FloatSize size = cursor.image()->size();
        result.appendLiteral(" image=");
        result.appendNumber(size.width());
        result.append('x');
        result.appendNumber(size.height());
    }
#if ENABLE(MOUSE_CURSOR_SCALE)
    if (cursor.imageScaleFactor() != 1) {
        result.appendLiteral(" scale=");
        NumberToStringBuffer buffer;
        result.append(numberToFixedPrecisionString(cursor.imageScaleFactor(), 8, buffer, true));
    }
#endif
    return result.toString();
#else
    return "FAIL: Cursor details not available on this platform.";
#endif
}

PassRefPtr<ArrayBuffer> Internals::serializeObject(PassRefPtr<SerializedScriptValue> value) const
{
    Vector<uint8_t> bytes = value->data();
    return ArrayBuffer::create(bytes.data(), bytes.size());
}

PassRefPtr<SerializedScriptValue> Internals::deserializeBuffer(PassRefPtr<ArrayBuffer> buffer) const
{
    Vector<uint8_t> bytes;
    bytes.append(static_cast<const uint8_t*>(buffer->data()), buffer->byteLength());
    return SerializedScriptValue::adopt(bytes);
}

bool Internals::isFromCurrentWorld(Deprecated::ScriptValue value) const
{
    ASSERT(!value.hasNoValue());
    
    JSC::ExecState* exec = contextDocument()->vm().topCallFrame;
    if (!value.isObject() || &worldForDOMObject(value.jsValue().getObject()) == &currentWorld(exec))
        return true;
    return false;
}

void Internals::setUsesOverlayScrollbars(bool enabled)
{
    WebCore::Settings::setUsesOverlayScrollbars(enabled);
}

void Internals::forceReload(bool endToEnd)
{
    frame()->loader().reload(endToEnd);
}

#if ENABLE(ENCRYPTED_MEDIA_V2)
void Internals::initializeMockCDM()
{
    CDM::registerCDMFactory([](CDM* cdm) { return std::make_unique<MockCDM>(cdm); },
        MockCDM::supportsKeySystem, MockCDM::supportsKeySystemAndMimeType);
}
#endif

String Internals::markerTextForListItem(Element* element, ExceptionCode& ec)
{
    if (!element) {
        ec = INVALID_ACCESS_ERR;
        return String();
    }
    return WebCore::markerTextForListItem(element);
}

String Internals::toolTipFromElement(Element* element, ExceptionCode& ec) const
{
    if (!element) {
        ec = INVALID_ACCESS_ERR;
        return String();
    }
    HitTestResult result;
    result.setInnerNode(element);
    TextDirection dir;
    return result.title(dir);
}

String Internals::getImageSourceURL(Element* element, ExceptionCode& ec)
{
    if (!element) {
        ec = INVALID_ACCESS_ERR;
        return String();
    }
    return element->imageSourceURL();
}

#if ENABLE(VIDEO)
void Internals::simulateAudioInterruption(Node* node)
{
#if USE(GSTREAMER)
    HTMLMediaElement* element = downcast<HTMLMediaElement>(node);
    element->player()->simulateAudioInterruption();
#else
    UNUSED_PARAM(node);
#endif
}

bool Internals::mediaElementHasCharacteristic(Node* node, const String& characteristic, ExceptionCode& ec)
{
    if (!is<HTMLMediaElement>(*node))
        return false;

    HTMLMediaElement* element = downcast<HTMLMediaElement>(node);

    if (equalIgnoringCase(characteristic, "Audible"))
        return element->hasAudio();
    if (equalIgnoringCase(characteristic, "Visual"))
        return element->hasVideo();
    if (equalIgnoringCase(characteristic, "Legible"))
        return element->hasClosedCaptions();

    ec = SYNTAX_ERR;
    return false;
}
#endif

bool Internals::isSelectPopupVisible(Node* node)
{
    if (!is<HTMLSelectElement>(*node))
        return false;

    HTMLSelectElement& select = downcast<HTMLSelectElement>(*node);

    auto* renderer = select.renderer();
    ASSERT(renderer);
    if (!is<RenderMenuList>(*renderer))
        return false;

#if !PLATFORM(IOS)
    return downcast<RenderMenuList>(*renderer).popupIsVisible();
#else
    return false;
#endif // !PLATFORM(IOS)
}

String Internals::captionsStyleSheetOverride(ExceptionCode& ec)
{
    Document* document = contextDocument();
    if (!document || !document->page()) {
        ec = INVALID_ACCESS_ERR;
        return emptyString();
    }

#if ENABLE(VIDEO_TRACK)
    return document->page()->group().captionPreferences()->captionsStyleSheetOverride();
#else
    return emptyString();
#endif
}

void Internals::setCaptionsStyleSheetOverride(const String& override, ExceptionCode& ec)
{
    Document* document = contextDocument();
    if (!document || !document->page()) {
        ec = INVALID_ACCESS_ERR;
        return;
    }

#if ENABLE(VIDEO_TRACK)
    document->page()->group().captionPreferences()->setCaptionsStyleSheetOverride(override);
#else
    UNUSED_PARAM(override);
#endif
}

void Internals::setPrimaryAudioTrackLanguageOverride(const String& language, ExceptionCode& ec)
{
    Document* document = contextDocument();
    if (!document || !document->page()) {
        ec = INVALID_ACCESS_ERR;
        return;
    }

#if ENABLE(VIDEO_TRACK)
    document->page()->group().captionPreferences()->setPrimaryAudioTrackLanguageOverride(language);
#else
    UNUSED_PARAM(language);
#endif
}

void Internals::setCaptionDisplayMode(const String& mode, ExceptionCode& ec)
{
    Document* document = contextDocument();
    if (!document || !document->page()) {
        ec = INVALID_ACCESS_ERR;
        return;
    }
    
#if ENABLE(VIDEO_TRACK)
    CaptionUserPreferences* captionPreferences = document->page()->group().captionPreferences();
    
    if (equalIgnoringCase(mode, "Automatic"))
        captionPreferences->setCaptionDisplayMode(CaptionUserPreferences::Automatic);
    else if (equalIgnoringCase(mode, "ForcedOnly"))
        captionPreferences->setCaptionDisplayMode(CaptionUserPreferences::ForcedOnly);
    else if (equalIgnoringCase(mode, "AlwaysOn"))
        captionPreferences->setCaptionDisplayMode(CaptionUserPreferences::AlwaysOn);
    else
        ec = SYNTAX_ERR;
#else
    UNUSED_PARAM(mode);
#endif
}

#if ENABLE(VIDEO)
PassRefPtr<TimeRanges> Internals::createTimeRanges(Float32Array* startTimes, Float32Array* endTimes)
{
    ASSERT(startTimes && endTimes);
    ASSERT(startTimes->length() == endTimes->length());
    RefPtr<TimeRanges> ranges = TimeRanges::create();

    unsigned count = std::min(startTimes->length(), endTimes->length());
    for (unsigned i = 0; i < count; ++i)
        ranges->add(startTimes->item(i), endTimes->item(i));
    return ranges;
}

double Internals::closestTimeToTimeRanges(double time, TimeRanges* ranges)
{
    return ranges->nearest(time);
}
#endif

Ref<ClientRect> Internals::selectionBounds(ExceptionCode& ec)
{
    Document* document = contextDocument();
    if (!document || !document->frame()) {
        ec = INVALID_ACCESS_ERR;
        return ClientRect::create();
    }

    return ClientRect::create(document->frame()->selection().selectionBounds());
}

#if ENABLE(VIBRATION)
bool Internals::isVibrating()
{
    Page* page = contextDocument()->page();
    ASSERT(page);

    return Vibration::from(page)->isVibrating();
}
#endif

bool Internals::isPluginUnavailabilityIndicatorObscured(Element* element, ExceptionCode& ec)
{
    if (!element) {
        ec = INVALID_ACCESS_ERR;
        return false;
    }

    auto* renderer = element->renderer();
    if (!is<RenderEmbeddedObject>(renderer)) {
        ec = INVALID_ACCESS_ERR;
        return false;
    }

    return downcast<RenderEmbeddedObject>(*renderer).isReplacementObscured();
}
    
bool Internals::isPluginSnapshotted(Element* element, ExceptionCode& ec)
{
    if (!element) {
        ec = INVALID_ACCESS_ERR;
        return false;
    }
    HTMLPlugInElement* pluginElement = downcast<HTMLPlugInElement>(element);
    return pluginElement->displayState() <= HTMLPlugInElement::DisplayingSnapshot;
}
    
#if ENABLE(MEDIA_SOURCE)
void Internals::initializeMockMediaSource()
{
#if USE(AVFOUNDATION)
    WebCore::Settings::setAVFoundationEnabled(false);
#endif
    MediaPlayerFactorySupport::callRegisterMediaEngine(MockMediaPlayerMediaSource::registerMediaEngine);
}

Vector<String> Internals::bufferedSamplesForTrackID(SourceBuffer* buffer, const AtomicString& trackID)
{
    if (!buffer)
        return Vector<String>();

    return buffer->bufferedSamplesForTrackID(trackID);
}
    
void Internals::setShouldGenerateTimestamps(SourceBuffer* buffer, bool flag)
{
    if (buffer)
        buffer->setShouldGenerateTimestamps(flag);
}
#endif

#if ENABLE(VIDEO)
void Internals::beginMediaSessionInterruption()
{
    PlatformMediaSessionManager::sharedManager().beginInterruption(PlatformMediaSession::SystemInterruption);
}

void Internals::endMediaSessionInterruption(const String& flagsString)
{
    PlatformMediaSession::EndInterruptionFlags flags = PlatformMediaSession::NoFlags;

    if (equalIgnoringCase(flagsString, "MayResumePlaying"))
        flags = PlatformMediaSession::MayResumePlaying;
    
    PlatformMediaSessionManager::sharedManager().endInterruption(flags);
}

void Internals::applicationWillEnterForeground() const
{
    PlatformMediaSessionManager::sharedManager().applicationWillEnterForeground();
}

void Internals::applicationWillEnterBackground() const
{
    PlatformMediaSessionManager::sharedManager().applicationWillEnterBackground();
}

void Internals::setMediaSessionRestrictions(const String& mediaTypeString, const String& restrictionsString, ExceptionCode& ec)
{
    PlatformMediaSession::MediaType mediaType = PlatformMediaSession::None;
    if (equalIgnoringCase(mediaTypeString, "Video"))
        mediaType = PlatformMediaSession::Video;
    else if (equalIgnoringCase(mediaTypeString, "Audio"))
        mediaType = PlatformMediaSession::Audio;
    else if (equalIgnoringCase(mediaTypeString, "WebAudio"))
        mediaType = PlatformMediaSession::WebAudio;
    else {
        ec = INVALID_ACCESS_ERR;
        return;
    }

    PlatformMediaSessionManager::SessionRestrictions restrictions = PlatformMediaSessionManager::sharedManager().restrictions(mediaType);
    PlatformMediaSessionManager::sharedManager().removeRestriction(mediaType, restrictions);

    restrictions = PlatformMediaSessionManager::NoRestrictions;

    Vector<String> restrictionsArray;
    restrictionsString.split(',', false, restrictionsArray);
    for (auto& restrictionString : restrictionsArray) {
        if (equalIgnoringCase(restrictionString, "ConcurrentPlaybackNotPermitted"))
            restrictions |= PlatformMediaSessionManager::ConcurrentPlaybackNotPermitted;
        if (equalIgnoringCase(restrictionString, "InlineVideoPlaybackRestricted"))
            restrictions |= PlatformMediaSessionManager::InlineVideoPlaybackRestricted;
        if (equalIgnoringCase(restrictionString, "MetadataPreloadingNotPermitted"))
            restrictions |= PlatformMediaSessionManager::MetadataPreloadingNotPermitted;
        if (equalIgnoringCase(restrictionString, "AutoPreloadingNotPermitted"))
            restrictions |= PlatformMediaSessionManager::AutoPreloadingNotPermitted;
        if (equalIgnoringCase(restrictionString, "BackgroundProcessPlaybackRestricted"))
            restrictions |= PlatformMediaSessionManager::BackgroundProcessPlaybackRestricted;
        if (equalIgnoringCase(restrictionString, "BackgroundTabPlaybackRestricted"))
            restrictions |= PlatformMediaSessionManager::BackgroundTabPlaybackRestricted;
        if (equalIgnoringCase(restrictionString, "InterruptedPlaybackNotPermitted"))
            restrictions |= PlatformMediaSessionManager::InterruptedPlaybackNotPermitted;
    }
    PlatformMediaSessionManager::sharedManager().addRestriction(mediaType, restrictions);
}

void Internals::setMediaElementRestrictions(HTMLMediaElement* element, const String& restrictionsString, ExceptionCode& ec)
{
    if (!element) {
        ec = INVALID_ACCESS_ERR;
        return;
    }

    MediaElementSession::BehaviorRestrictions restrictions = element->mediaSession().behaviorRestrictions();
    element->mediaSession().removeBehaviorRestriction(restrictions);

    restrictions = MediaElementSession::NoRestrictions;

    Vector<String> restrictionsArray;
    restrictionsString.split(',', false, restrictionsArray);
    for (auto& restrictionString : restrictionsArray) {
        if (equalIgnoringCase(restrictionString, "NoRestrictions"))
            restrictions |= MediaElementSession::NoRestrictions;
        if (equalIgnoringCase(restrictionString, "RequireUserGestureForLoad"))
            restrictions |= MediaElementSession::RequireUserGestureForLoad;
        if (equalIgnoringCase(restrictionString, "RequireUserGestureForRateChange"))
            restrictions |= MediaElementSession::RequireUserGestureForRateChange;
        if (equalIgnoringCase(restrictionString, "RequireUserGestureForFullscreen"))
            restrictions |= MediaElementSession::RequireUserGestureForFullscreen;
        if (equalIgnoringCase(restrictionString, "RequirePageConsentToLoadMedia"))
            restrictions |= MediaElementSession::RequirePageConsentToLoadMedia;
        if (equalIgnoringCase(restrictionString, "RequirePageConsentToResumeMedia"))
            restrictions |= MediaElementSession::RequirePageConsentToResumeMedia;
#if ENABLE(WIRELESS_PLAYBACK_TARGET)
        if (equalIgnoringCase(restrictionString, "RequireUserGestureToShowPlaybackTargetPicker"))
            restrictions |= MediaElementSession::RequireUserGestureToShowPlaybackTargetPicker;
        if (equalIgnoringCase(restrictionString, "WirelessVideoPlaybackDisabled"))
            restrictions |= MediaElementSession::WirelessVideoPlaybackDisabled;
#endif
        if (equalIgnoringCase(restrictionString, "RequireUserGestureForAudioRateChange"))
            restrictions |= MediaElementSession::RequireUserGestureForAudioRateChange;
    }
    element->mediaSession().addBehaviorRestriction(restrictions);
}

void Internals::postRemoteControlCommand(const String& commandString, ExceptionCode& ec)
{
    PlatformMediaSession::RemoteControlCommandType command;
    
    if (equalIgnoringCase(commandString, "Play"))
        command = PlatformMediaSession::PlayCommand;
    else if (equalIgnoringCase(commandString, "Pause"))
        command = PlatformMediaSession::PauseCommand;
    else if (equalIgnoringCase(commandString, "Stop"))
        command = PlatformMediaSession::StopCommand;
    else if (equalIgnoringCase(commandString, "TogglePlayPause"))
        command = PlatformMediaSession::TogglePlayPauseCommand;
    else if (equalIgnoringCase(commandString, "BeginSeekingBackward"))
        command = PlatformMediaSession::BeginSeekingBackwardCommand;
    else if (equalIgnoringCase(commandString, "EndSeekingBackward"))
        command = PlatformMediaSession::EndSeekingBackwardCommand;
    else if (equalIgnoringCase(commandString, "BeginSeekingForward"))
        command = PlatformMediaSession::BeginSeekingForwardCommand;
    else if (equalIgnoringCase(commandString, "EndSeekingForward"))
        command = PlatformMediaSession::EndSeekingForwardCommand;
    else {
        ec = INVALID_ACCESS_ERR;
        return;
    }
    
    PlatformMediaSessionManager::sharedManager().didReceiveRemoteControlCommand(command);
}

bool Internals::elementIsBlockingDisplaySleep(Element* element) const
{
    HTMLMediaElement* mediaElement = downcast<HTMLMediaElement>(element);
    return mediaElement ? mediaElement->isDisablingSleep() : false;
}

#endif // ENABLE(VIDEO)

#if ENABLE(MEDIA_SESSION)
static MediaSessionInterruptingCategory interruptingCategoryFromString(const String& interruptingCategoryString)
{
    if (interruptingCategoryString == "content")
        return MediaSessionInterruptingCategory::Content;
    if (interruptingCategoryString == "transient")
        return MediaSessionInterruptingCategory::Transient;
    if (interruptingCategoryString == "transient-solo")
        return MediaSessionInterruptingCategory::TransientSolo;
    ASSERT_NOT_REACHED();
    return MediaSessionInterruptingCategory::Content;
}

void Internals::sendMediaSessionStartOfInterruptionNotification(const String& interruptingCategoryString)
{
    MediaSessionManager::singleton().didReceiveStartOfInterruptionNotification(interruptingCategoryFromString(interruptingCategoryString));
}

void Internals::sendMediaSessionEndOfInterruptionNotification(const String& interruptingCategoryString)
{
    MediaSessionManager::singleton().didReceiveEndOfInterruptionNotification(interruptingCategoryFromString(interruptingCategoryString));
}

String Internals::mediaSessionCurrentState(MediaSession* session) const
{
    switch (session->currentState()) {
    case MediaSession::State::Active:
        return "active";
    case MediaSession::State::Interrupted:
        return "interrupted";
    case MediaSession::State::Idle:
        return "idle";
    }
}

double Internals::mediaElementPlayerVolume(HTMLMediaElement* element) const
{
    ASSERT_ARG(element, element);
    return element->playerVolume();
}

void Internals::sendMediaControlEvent(const String& event)
{
    if (event == "play-pause")
        MediaSessionManager::singleton().togglePlayback();
    else if (event == "next-track")
        MediaSessionManager::singleton().skipToNextTrack();
    else if (event == "previous-track")
        MediaSessionManager::singleton().skipToPreviousTrack();
    else
        ASSERT_NOT_REACHED();
}
#endif // ENABLE(MEDIA_SESSION)

#if ENABLE(WEB_AUDIO)
void Internals::setAudioContextRestrictions(AudioContext* context, const String &restrictionsString, ExceptionCode &ec)
{
    if (!context) {
        ec = INVALID_ACCESS_ERR;
        return;
    }

    AudioContext::BehaviorRestrictions restrictions = context->behaviorRestrictions();
    context->removeBehaviorRestriction(restrictions);

    restrictions = MediaElementSession::NoRestrictions;

    Vector<String> restrictionsArray;
    restrictionsString.split(',', false, restrictionsArray);
    for (auto& restrictionString : restrictionsArray) {
        if (equalIgnoringCase(restrictionString, "NoRestrictions"))
            restrictions |= AudioContext::NoRestrictions;
        if (equalIgnoringCase(restrictionString, "RequireUserGestureForAudioStart"))
            restrictions |= AudioContext::RequireUserGestureForAudioStartRestriction;
        if (equalIgnoringCase(restrictionString, "RequirePageConsentForAudioStart"))
            restrictions |= AudioContext::RequirePageConsentForAudioStartRestriction;
    }
    context->addBehaviorRestriction(restrictions);
}
#endif

void Internals::simulateSystemSleep() const
{
#if ENABLE(VIDEO)
    PlatformMediaSessionManager::sharedManager().systemWillSleep();
#endif
}

void Internals::simulateSystemWake() const
{
#if ENABLE(VIDEO)
    PlatformMediaSessionManager::sharedManager().systemDidWake();
#endif
}


void Internals::installMockPageOverlay(const String& overlayType, ExceptionCode& ec)
{
    Document* document = contextDocument();
    if (!document || !document->frame()) {
        ec = INVALID_ACCESS_ERR;
        return;
    }

    MockPageOverlayClient::singleton().installOverlay(document->frame()->mainFrame(), overlayType == "view" ? PageOverlay::OverlayType::View : PageOverlay::OverlayType::Document);
}

String Internals::pageOverlayLayerTreeAsText(ExceptionCode& ec) const
{
    Document* document = contextDocument();
    if (!document || !document->frame()) {
        ec = INVALID_ACCESS_ERR;
        return String();
    }

    document->updateLayout();

    return MockPageOverlayClient::singleton().layerTreeAsText(document->frame()->mainFrame());
}

void Internals::setPageMuted(bool muted)
{
    Document* document = contextDocument();
    if (!document)
        return;

    if (Page* page = document->page())
        page->setMuted(muted);
}

bool Internals::isPagePlayingAudio()
{
    Document* document = contextDocument();
    if (!document || !document->page())
        return false;

    return !!(document->page()->mediaState() & MediaProducer::IsPlayingAudio);
}

RefPtr<File> Internals::createFile(const String& path)
{
    Document* document = contextDocument();
    if (!document)
        return nullptr;

    URL url = document->completeURL(path);
    if (!url.isLocalFile())
        return nullptr;

    return File::create(url.fileSystemPath());
}

void Internals::queueMicroTask(int testNumber)
{
    if (contextDocument())
        MicroTaskQueue::singleton().queueMicroTask(std::make_unique<MicroTaskTest>(contextDocument()->createWeakPtr(), testNumber));
}

#if ENABLE(CONTENT_FILTERING)
MockContentFilterSettings& Internals::mockContentFilterSettings()
{
    return MockContentFilterSettings::singleton();
}
#endif

#if ENABLE(CSS_SCROLL_SNAP)
static void appendOffsets(StringBuilder& builder, const Vector<LayoutUnit>& snapOffsets)
{
    bool justStarting = true;

    builder.append("{ ");
    for (auto& coordinate : snapOffsets) {
        if (!justStarting)
            builder.append(", ");
        else
            justStarting = false;
        
        builder.append(String::number(coordinate.toUnsigned()));
    }
    builder.append(" }");
}
    
String Internals::scrollSnapOffsets(Element* element, ExceptionCode& ec)
{
    if (!element) {
        ec = INVALID_ACCESS_ERR;
        return String();
    }

    if (!element->renderBox())
        return String();

    RenderBox& box = *element->renderBox();
    ScrollableArea* scrollableArea;
    
    if (box.isBody()) {
        FrameView* frameView = box.frame().mainFrame().view();
        if (!frameView || !frameView->isScrollable()) {
            ec = INVALID_ACCESS_ERR;
            return String();
        }
        scrollableArea = frameView;
        
    } else {
        if (!box.canBeScrolledAndHasScrollableArea()) {
            ec = INVALID_ACCESS_ERR;
            return String();
        }
        scrollableArea = box.layer();
    }

    if (!scrollableArea)
        return String();
    
    StringBuilder result;

    if (scrollableArea->horizontalSnapOffsets()) {
        result.append("horizontal = ");
        appendOffsets(result, *scrollableArea->horizontalSnapOffsets());
    }

    if (scrollableArea->verticalSnapOffsets()) {
        if (result.length())
            result.append(", ");

        result.append("vertical = ");
        appendOffsets(result, *scrollableArea->verticalSnapOffsets());
    }

    return result.toString();
}
#endif

bool Internals::testPreloaderSettingViewport()
{
    return testPreloadScannerViewportSupport(contextDocument());
}

String Internals::pathStringWithShrinkWrappedRects(Vector<double> rectComponents, double radius, ExceptionCode& ec)
{
    if (rectComponents.size() % 4) {
        ec = INVALID_ACCESS_ERR;
        return String();
    }

    Vector<FloatRect> rects;
    while (!rectComponents.isEmpty()) {
        double height = rectComponents.takeLast();
        double width = rectComponents.takeLast();
        double y = rectComponents.takeLast();
        double x = rectComponents.takeLast();

        rects.append(FloatRect(x, y, width, height));
    }

    rects.reverse();

    Path path = PathUtilities::pathWithShrinkWrappedRects(rects, radius);

    String pathString;
    buildStringFromPath(path, pathString);

    return pathString;
}


String Internals::getCurrentMediaControlsStatusForElement(HTMLMediaElement* mediaElement)
{
#if !ENABLE(MEDIA_CONTROLS_SCRIPT)
    UNUSED_PARAM(mediaElement);
    return String();
#else
    if (!mediaElement)
        return String();

    return mediaElement->getCurrentMediaControlsStatus();
#endif
}

}
