/*
 * Copyright (C) 2013 Google Inc. All rights reserved.
 * Copyright (C) 2013-2016 Apple Inc. All rights reserved.
 * Copyright (C) 2014 University of Washington. 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 INC. 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 INC. 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.
 */

// DO NOT EDIT THIS FILE. It is automatically generated from CombinedDomains.json
// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py

#include "config.h"
#include "InspectorFrontendDispatchers.h"

#include "InspectorFrontendRouter.h"
#include <wtf/text/CString.h>

namespace Inspector {

void ApplicationCacheFrontendDispatcher::applicationCacheStatusUpdated(const Inspector::Protocol::Network::FrameId& frameId, const String& manifestURL, int status)
{
    Ref<InspectorObject> jsonMessage = InspectorObject::create();
    jsonMessage->setString(ASCIILiteral("method"), ASCIILiteral("ApplicationCache.applicationCacheStatusUpdated"));
    Ref<InspectorObject> paramsObject = InspectorObject::create();
    paramsObject->setString(ASCIILiteral("frameId"), frameId);
    paramsObject->setString(ASCIILiteral("manifestURL"), manifestURL);
    paramsObject->setInteger(ASCIILiteral("status"), status);
    jsonMessage->setObject(ASCIILiteral("params"), WTFMove(paramsObject));

    m_frontendRouter.sendEvent(jsonMessage->toJSONString());
}

void ApplicationCacheFrontendDispatcher::networkStateUpdated(bool isNowOnline)
{
    Ref<InspectorObject> jsonMessage = InspectorObject::create();
    jsonMessage->setString(ASCIILiteral("method"), ASCIILiteral("ApplicationCache.networkStateUpdated"));
    Ref<InspectorObject> paramsObject = InspectorObject::create();
    paramsObject->setBoolean(ASCIILiteral("isNowOnline"), isNowOnline);
    jsonMessage->setObject(ASCIILiteral("params"), WTFMove(paramsObject));

    m_frontendRouter.sendEvent(jsonMessage->toJSONString());
}

void CSSFrontendDispatcher::mediaQueryResultChanged()
{
    Ref<InspectorObject> jsonMessage = InspectorObject::create();
    jsonMessage->setString(ASCIILiteral("method"), ASCIILiteral("CSS.mediaQueryResultChanged"));

    m_frontendRouter.sendEvent(jsonMessage->toJSONString());
}

void CSSFrontendDispatcher::styleSheetChanged(const Inspector::Protocol::CSS::StyleSheetId& styleSheetId)
{
    Ref<InspectorObject> jsonMessage = InspectorObject::create();
    jsonMessage->setString(ASCIILiteral("method"), ASCIILiteral("CSS.styleSheetChanged"));
    Ref<InspectorObject> paramsObject = InspectorObject::create();
    paramsObject->setString(ASCIILiteral("styleSheetId"), styleSheetId);
    jsonMessage->setObject(ASCIILiteral("params"), WTFMove(paramsObject));

    m_frontendRouter.sendEvent(jsonMessage->toJSONString());
}

void CSSFrontendDispatcher::styleSheetAdded(RefPtr<Inspector::Protocol::CSS::CSSStyleSheetHeader> header)
{
    Ref<InspectorObject> jsonMessage = InspectorObject::create();
    jsonMessage->setString(ASCIILiteral("method"), ASCIILiteral("CSS.styleSheetAdded"));
    Ref<InspectorObject> paramsObject = InspectorObject::create();
    paramsObject->setObject(ASCIILiteral("header"), header);
    jsonMessage->setObject(ASCIILiteral("params"), WTFMove(paramsObject));

    m_frontendRouter.sendEvent(jsonMessage->toJSONString());
}

void CSSFrontendDispatcher::styleSheetRemoved(const Inspector::Protocol::CSS::StyleSheetId& styleSheetId)
{
    Ref<InspectorObject> jsonMessage = InspectorObject::create();
    jsonMessage->setString(ASCIILiteral("method"), ASCIILiteral("CSS.styleSheetRemoved"));
    Ref<InspectorObject> paramsObject = InspectorObject::create();
    paramsObject->setString(ASCIILiteral("styleSheetId"), styleSheetId);
    jsonMessage->setObject(ASCIILiteral("params"), WTFMove(paramsObject));

    m_frontendRouter.sendEvent(jsonMessage->toJSONString());
}

void CSSFrontendDispatcher::namedFlowCreated(RefPtr<Inspector::Protocol::CSS::NamedFlow> namedFlow)
{
    Ref<InspectorObject> jsonMessage = InspectorObject::create();
    jsonMessage->setString(ASCIILiteral("method"), ASCIILiteral("CSS.namedFlowCreated"));
    Ref<InspectorObject> paramsObject = InspectorObject::create();
    paramsObject->setObject(ASCIILiteral("namedFlow"), namedFlow);
    jsonMessage->setObject(ASCIILiteral("params"), WTFMove(paramsObject));

    m_frontendRouter.sendEvent(jsonMessage->toJSONString());
}

void CSSFrontendDispatcher::namedFlowRemoved(int documentNodeId, const String& flowName)
{
    Ref<InspectorObject> jsonMessage = InspectorObject::create();
    jsonMessage->setString(ASCIILiteral("method"), ASCIILiteral("CSS.namedFlowRemoved"));
    Ref<InspectorObject> paramsObject = InspectorObject::create();
    paramsObject->setInteger(ASCIILiteral("documentNodeId"), documentNodeId);
    paramsObject->setString(ASCIILiteral("flowName"), flowName);
    jsonMessage->setObject(ASCIILiteral("params"), WTFMove(paramsObject));

    m_frontendRouter.sendEvent(jsonMessage->toJSONString());
}

void CSSFrontendDispatcher::regionOversetChanged(RefPtr<Inspector::Protocol::CSS::NamedFlow> namedFlow)
{
    Ref<InspectorObject> jsonMessage = InspectorObject::create();
    jsonMessage->setString(ASCIILiteral("method"), ASCIILiteral("CSS.regionOversetChanged"));
    Ref<InspectorObject> paramsObject = InspectorObject::create();
    paramsObject->setObject(ASCIILiteral("namedFlow"), namedFlow);
    jsonMessage->setObject(ASCIILiteral("params"), WTFMove(paramsObject));

    m_frontendRouter.sendEvent(jsonMessage->toJSONString());
}

void CSSFrontendDispatcher::registeredNamedFlowContentElement(int documentNodeId, const String& flowName, int contentNodeId, int nextContentNodeId)
{
    Ref<InspectorObject> jsonMessage = InspectorObject::create();
    jsonMessage->setString(ASCIILiteral("method"), ASCIILiteral("CSS.registeredNamedFlowContentElement"));
    Ref<InspectorObject> paramsObject = InspectorObject::create();
    paramsObject->setInteger(ASCIILiteral("documentNodeId"), documentNodeId);
    paramsObject->setString(ASCIILiteral("flowName"), flowName);
    paramsObject->setInteger(ASCIILiteral("contentNodeId"), contentNodeId);
    paramsObject->setInteger(ASCIILiteral("nextContentNodeId"), nextContentNodeId);
    jsonMessage->setObject(ASCIILiteral("params"), WTFMove(paramsObject));

    m_frontendRouter.sendEvent(jsonMessage->toJSONString());
}

void CSSFrontendDispatcher::unregisteredNamedFlowContentElement(int documentNodeId, const String& flowName, int contentNodeId)
{
    Ref<InspectorObject> jsonMessage = InspectorObject::create();
    jsonMessage->setString(ASCIILiteral("method"), ASCIILiteral("CSS.unregisteredNamedFlowContentElement"));
    Ref<InspectorObject> paramsObject = InspectorObject::create();
    paramsObject->setInteger(ASCIILiteral("documentNodeId"), documentNodeId);
    paramsObject->setString(ASCIILiteral("flowName"), flowName);
    paramsObject->setInteger(ASCIILiteral("contentNodeId"), contentNodeId);
    jsonMessage->setObject(ASCIILiteral("params"), WTFMove(paramsObject));

    m_frontendRouter.sendEvent(jsonMessage->toJSONString());
}

void ConsoleFrontendDispatcher::messageAdded(RefPtr<Inspector::Protocol::Console::ConsoleMessage> message)
{
    Ref<InspectorObject> jsonMessage = InspectorObject::create();
    jsonMessage->setString(ASCIILiteral("method"), ASCIILiteral("Console.messageAdded"));
    Ref<InspectorObject> paramsObject = InspectorObject::create();
    paramsObject->setObject(ASCIILiteral("message"), message);
    jsonMessage->setObject(ASCIILiteral("params"), WTFMove(paramsObject));

    m_frontendRouter.sendEvent(jsonMessage->toJSONString());
}

void ConsoleFrontendDispatcher::messageRepeatCountUpdated(int count)
{
    Ref<InspectorObject> jsonMessage = InspectorObject::create();
    jsonMessage->setString(ASCIILiteral("method"), ASCIILiteral("Console.messageRepeatCountUpdated"));
    Ref<InspectorObject> paramsObject = InspectorObject::create();
    paramsObject->setInteger(ASCIILiteral("count"), count);
    jsonMessage->setObject(ASCIILiteral("params"), WTFMove(paramsObject));

    m_frontendRouter.sendEvent(jsonMessage->toJSONString());
}

void ConsoleFrontendDispatcher::messagesCleared()
{
    Ref<InspectorObject> jsonMessage = InspectorObject::create();
    jsonMessage->setString(ASCIILiteral("method"), ASCIILiteral("Console.messagesCleared"));

    m_frontendRouter.sendEvent(jsonMessage->toJSONString());
}

void ConsoleFrontendDispatcher::heapSnapshot(double timestamp, const Inspector::Protocol::Heap::HeapSnapshotData& snapshotData, const String* const title)
{
    Ref<InspectorObject> jsonMessage = InspectorObject::create();
    jsonMessage->setString(ASCIILiteral("method"), ASCIILiteral("Console.heapSnapshot"));
    Ref<InspectorObject> paramsObject = InspectorObject::create();
    paramsObject->setDouble(ASCIILiteral("timestamp"), timestamp);
    paramsObject->setString(ASCIILiteral("snapshotData"), snapshotData);
    if (title)
        paramsObject->setString(ASCIILiteral("title"), *title);
    jsonMessage->setObject(ASCIILiteral("params"), WTFMove(paramsObject));

    m_frontendRouter.sendEvent(jsonMessage->toJSONString());
}

void DOMFrontendDispatcher::documentUpdated()
{
    Ref<InspectorObject> jsonMessage = InspectorObject::create();
    jsonMessage->setString(ASCIILiteral("method"), ASCIILiteral("DOM.documentUpdated"));

    m_frontendRouter.sendEvent(jsonMessage->toJSONString());
}

void DOMFrontendDispatcher::setChildNodes(int parentId, RefPtr<Inspector::Protocol::Array<Inspector::Protocol::DOM::Node>> nodes)
{
    Ref<InspectorObject> jsonMessage = InspectorObject::create();
    jsonMessage->setString(ASCIILiteral("method"), ASCIILiteral("DOM.setChildNodes"));
    Ref<InspectorObject> paramsObject = InspectorObject::create();
    paramsObject->setInteger(ASCIILiteral("parentId"), parentId);
    paramsObject->setArray(ASCIILiteral("nodes"), nodes);
    jsonMessage->setObject(ASCIILiteral("params"), WTFMove(paramsObject));

    m_frontendRouter.sendEvent(jsonMessage->toJSONString());
}

void DOMFrontendDispatcher::attributeModified(int nodeId, const String& name, const String& value)
{
    Ref<InspectorObject> jsonMessage = InspectorObject::create();
    jsonMessage->setString(ASCIILiteral("method"), ASCIILiteral("DOM.attributeModified"));
    Ref<InspectorObject> paramsObject = InspectorObject::create();
    paramsObject->setInteger(ASCIILiteral("nodeId"), nodeId);
    paramsObject->setString(ASCIILiteral("name"), name);
    paramsObject->setString(ASCIILiteral("value"), value);
    jsonMessage->setObject(ASCIILiteral("params"), WTFMove(paramsObject));

    m_frontendRouter.sendEvent(jsonMessage->toJSONString());
}

void DOMFrontendDispatcher::attributeRemoved(int nodeId, const String& name)
{
    Ref<InspectorObject> jsonMessage = InspectorObject::create();
    jsonMessage->setString(ASCIILiteral("method"), ASCIILiteral("DOM.attributeRemoved"));
    Ref<InspectorObject> paramsObject = InspectorObject::create();
    paramsObject->setInteger(ASCIILiteral("nodeId"), nodeId);
    paramsObject->setString(ASCIILiteral("name"), name);
    jsonMessage->setObject(ASCIILiteral("params"), WTFMove(paramsObject));

    m_frontendRouter.sendEvent(jsonMessage->toJSONString());
}

void DOMFrontendDispatcher::inlineStyleInvalidated(RefPtr<Inspector::Protocol::Array<Inspector::Protocol::DOM::NodeId>> nodeIds)
{
    Ref<InspectorObject> jsonMessage = InspectorObject::create();
    jsonMessage->setString(ASCIILiteral("method"), ASCIILiteral("DOM.inlineStyleInvalidated"));
    Ref<InspectorObject> paramsObject = InspectorObject::create();
    paramsObject->setArray(ASCIILiteral("nodeIds"), nodeIds);
    jsonMessage->setObject(ASCIILiteral("params"), WTFMove(paramsObject));

    m_frontendRouter.sendEvent(jsonMessage->toJSONString());
}

void DOMFrontendDispatcher::characterDataModified(int nodeId, const String& characterData)
{
    Ref<InspectorObject> jsonMessage = InspectorObject::create();
    jsonMessage->setString(ASCIILiteral("method"), ASCIILiteral("DOM.characterDataModified"));
    Ref<InspectorObject> paramsObject = InspectorObject::create();
    paramsObject->setInteger(ASCIILiteral("nodeId"), nodeId);
    paramsObject->setString(ASCIILiteral("characterData"), characterData);
    jsonMessage->setObject(ASCIILiteral("params"), WTFMove(paramsObject));

    m_frontendRouter.sendEvent(jsonMessage->toJSONString());
}

void DOMFrontendDispatcher::childNodeCountUpdated(int nodeId, int childNodeCount)
{
    Ref<InspectorObject> jsonMessage = InspectorObject::create();
    jsonMessage->setString(ASCIILiteral("method"), ASCIILiteral("DOM.childNodeCountUpdated"));
    Ref<InspectorObject> paramsObject = InspectorObject::create();
    paramsObject->setInteger(ASCIILiteral("nodeId"), nodeId);
    paramsObject->setInteger(ASCIILiteral("childNodeCount"), childNodeCount);
    jsonMessage->setObject(ASCIILiteral("params"), WTFMove(paramsObject));

    m_frontendRouter.sendEvent(jsonMessage->toJSONString());
}

void DOMFrontendDispatcher::childNodeInserted(int parentNodeId, int previousNodeId, RefPtr<Inspector::Protocol::DOM::Node> node)
{
    Ref<InspectorObject> jsonMessage = InspectorObject::create();
    jsonMessage->setString(ASCIILiteral("method"), ASCIILiteral("DOM.childNodeInserted"));
    Ref<InspectorObject> paramsObject = InspectorObject::create();
    paramsObject->setInteger(ASCIILiteral("parentNodeId"), parentNodeId);
    paramsObject->setInteger(ASCIILiteral("previousNodeId"), previousNodeId);
    paramsObject->setObject(ASCIILiteral("node"), node);
    jsonMessage->setObject(ASCIILiteral("params"), WTFMove(paramsObject));

    m_frontendRouter.sendEvent(jsonMessage->toJSONString());
}

void DOMFrontendDispatcher::childNodeRemoved(int parentNodeId, int nodeId)
{
    Ref<InspectorObject> jsonMessage = InspectorObject::create();
    jsonMessage->setString(ASCIILiteral("method"), ASCIILiteral("DOM.childNodeRemoved"));
    Ref<InspectorObject> paramsObject = InspectorObject::create();
    paramsObject->setInteger(ASCIILiteral("parentNodeId"), parentNodeId);
    paramsObject->setInteger(ASCIILiteral("nodeId"), nodeId);
    jsonMessage->setObject(ASCIILiteral("params"), WTFMove(paramsObject));

    m_frontendRouter.sendEvent(jsonMessage->toJSONString());
}

void DOMFrontendDispatcher::shadowRootPushed(int hostId, RefPtr<Inspector::Protocol::DOM::Node> root)
{
    Ref<InspectorObject> jsonMessage = InspectorObject::create();
    jsonMessage->setString(ASCIILiteral("method"), ASCIILiteral("DOM.shadowRootPushed"));
    Ref<InspectorObject> paramsObject = InspectorObject::create();
    paramsObject->setInteger(ASCIILiteral("hostId"), hostId);
    paramsObject->setObject(ASCIILiteral("root"), root);
    jsonMessage->setObject(ASCIILiteral("params"), WTFMove(paramsObject));

    m_frontendRouter.sendEvent(jsonMessage->toJSONString());
}

void DOMFrontendDispatcher::shadowRootPopped(int hostId, int rootId)
{
    Ref<InspectorObject> jsonMessage = InspectorObject::create();
    jsonMessage->setString(ASCIILiteral("method"), ASCIILiteral("DOM.shadowRootPopped"));
    Ref<InspectorObject> paramsObject = InspectorObject::create();
    paramsObject->setInteger(ASCIILiteral("hostId"), hostId);
    paramsObject->setInteger(ASCIILiteral("rootId"), rootId);
    jsonMessage->setObject(ASCIILiteral("params"), WTFMove(paramsObject));

    m_frontendRouter.sendEvent(jsonMessage->toJSONString());
}

void DOMFrontendDispatcher::pseudoElementAdded(int parentId, RefPtr<Inspector::Protocol::DOM::Node> pseudoElement)
{
    Ref<InspectorObject> jsonMessage = InspectorObject::create();
    jsonMessage->setString(ASCIILiteral("method"), ASCIILiteral("DOM.pseudoElementAdded"));
    Ref<InspectorObject> paramsObject = InspectorObject::create();
    paramsObject->setInteger(ASCIILiteral("parentId"), parentId);
    paramsObject->setObject(ASCIILiteral("pseudoElement"), pseudoElement);
    jsonMessage->setObject(ASCIILiteral("params"), WTFMove(paramsObject));

    m_frontendRouter.sendEvent(jsonMessage->toJSONString());
}

void DOMFrontendDispatcher::pseudoElementRemoved(int parentId, int pseudoElementId)
{
    Ref<InspectorObject> jsonMessage = InspectorObject::create();
    jsonMessage->setString(ASCIILiteral("method"), ASCIILiteral("DOM.pseudoElementRemoved"));
    Ref<InspectorObject> paramsObject = InspectorObject::create();
    paramsObject->setInteger(ASCIILiteral("parentId"), parentId);
    paramsObject->setInteger(ASCIILiteral("pseudoElementId"), pseudoElementId);
    jsonMessage->setObject(ASCIILiteral("params"), WTFMove(paramsObject));

    m_frontendRouter.sendEvent(jsonMessage->toJSONString());
}

void DOMStorageFrontendDispatcher::domStorageItemsCleared(RefPtr<Inspector::Protocol::DOMStorage::StorageId> storageId)
{
    Ref<InspectorObject> jsonMessage = InspectorObject::create();
    jsonMessage->setString(ASCIILiteral("method"), ASCIILiteral("DOMStorage.domStorageItemsCleared"));
    Ref<InspectorObject> paramsObject = InspectorObject::create();
    paramsObject->setObject(ASCIILiteral("storageId"), storageId);
    jsonMessage->setObject(ASCIILiteral("params"), WTFMove(paramsObject));

    m_frontendRouter.sendEvent(jsonMessage->toJSONString());
}

void DOMStorageFrontendDispatcher::domStorageItemRemoved(RefPtr<Inspector::Protocol::DOMStorage::StorageId> storageId, const String& key)
{
    Ref<InspectorObject> jsonMessage = InspectorObject::create();
    jsonMessage->setString(ASCIILiteral("method"), ASCIILiteral("DOMStorage.domStorageItemRemoved"));
    Ref<InspectorObject> paramsObject = InspectorObject::create();
    paramsObject->setObject(ASCIILiteral("storageId"), storageId);
    paramsObject->setString(ASCIILiteral("key"), key);
    jsonMessage->setObject(ASCIILiteral("params"), WTFMove(paramsObject));

    m_frontendRouter.sendEvent(jsonMessage->toJSONString());
}

void DOMStorageFrontendDispatcher::domStorageItemAdded(RefPtr<Inspector::Protocol::DOMStorage::StorageId> storageId, const String& key, const String& newValue)
{
    Ref<InspectorObject> jsonMessage = InspectorObject::create();
    jsonMessage->setString(ASCIILiteral("method"), ASCIILiteral("DOMStorage.domStorageItemAdded"));
    Ref<InspectorObject> paramsObject = InspectorObject::create();
    paramsObject->setObject(ASCIILiteral("storageId"), storageId);
    paramsObject->setString(ASCIILiteral("key"), key);
    paramsObject->setString(ASCIILiteral("newValue"), newValue);
    jsonMessage->setObject(ASCIILiteral("params"), WTFMove(paramsObject));

    m_frontendRouter.sendEvent(jsonMessage->toJSONString());
}

void DOMStorageFrontendDispatcher::domStorageItemUpdated(RefPtr<Inspector::Protocol::DOMStorage::StorageId> storageId, const String& key, const String& oldValue, const String& newValue)
{
    Ref<InspectorObject> jsonMessage = InspectorObject::create();
    jsonMessage->setString(ASCIILiteral("method"), ASCIILiteral("DOMStorage.domStorageItemUpdated"));
    Ref<InspectorObject> paramsObject = InspectorObject::create();
    paramsObject->setObject(ASCIILiteral("storageId"), storageId);
    paramsObject->setString(ASCIILiteral("key"), key);
    paramsObject->setString(ASCIILiteral("oldValue"), oldValue);
    paramsObject->setString(ASCIILiteral("newValue"), newValue);
    jsonMessage->setObject(ASCIILiteral("params"), WTFMove(paramsObject));

    m_frontendRouter.sendEvent(jsonMessage->toJSONString());
}

void DatabaseFrontendDispatcher::addDatabase(RefPtr<Inspector::Protocol::Database::Database> database)
{
    Ref<InspectorObject> jsonMessage = InspectorObject::create();
    jsonMessage->setString(ASCIILiteral("method"), ASCIILiteral("Database.addDatabase"));
    Ref<InspectorObject> paramsObject = InspectorObject::create();
    paramsObject->setObject(ASCIILiteral("database"), database);
    jsonMessage->setObject(ASCIILiteral("params"), WTFMove(paramsObject));

    m_frontendRouter.sendEvent(jsonMessage->toJSONString());
}

void DebuggerFrontendDispatcher::globalObjectCleared()
{
    Ref<InspectorObject> jsonMessage = InspectorObject::create();
    jsonMessage->setString(ASCIILiteral("method"), ASCIILiteral("Debugger.globalObjectCleared"));

    m_frontendRouter.sendEvent(jsonMessage->toJSONString());
}

void DebuggerFrontendDispatcher::scriptParsed(const Inspector::Protocol::Debugger::ScriptId& scriptId, const String& url, int startLine, int startColumn, int endLine, int endColumn, const bool* const isContentScript, const String* const sourceURL, const String* const sourceMapURL)
{
    Ref<InspectorObject> jsonMessage = InspectorObject::create();
    jsonMessage->setString(ASCIILiteral("method"), ASCIILiteral("Debugger.scriptParsed"));
    Ref<InspectorObject> paramsObject = InspectorObject::create();
    paramsObject->setString(ASCIILiteral("scriptId"), scriptId);
    paramsObject->setString(ASCIILiteral("url"), url);
    paramsObject->setInteger(ASCIILiteral("startLine"), startLine);
    paramsObject->setInteger(ASCIILiteral("startColumn"), startColumn);
    paramsObject->setInteger(ASCIILiteral("endLine"), endLine);
    paramsObject->setInteger(ASCIILiteral("endColumn"), endColumn);
    if (isContentScript)
        paramsObject->setBoolean(ASCIILiteral("isContentScript"), *isContentScript);
    if (sourceURL)
        paramsObject->setString(ASCIILiteral("sourceURL"), *sourceURL);
    if (sourceMapURL)
        paramsObject->setString(ASCIILiteral("sourceMapURL"), *sourceMapURL);
    jsonMessage->setObject(ASCIILiteral("params"), WTFMove(paramsObject));

    m_frontendRouter.sendEvent(jsonMessage->toJSONString());
}

void DebuggerFrontendDispatcher::scriptFailedToParse(const String& url, const String& scriptSource, int startLine, int errorLine, const String& errorMessage)
{
    Ref<InspectorObject> jsonMessage = InspectorObject::create();
    jsonMessage->setString(ASCIILiteral("method"), ASCIILiteral("Debugger.scriptFailedToParse"));
    Ref<InspectorObject> paramsObject = InspectorObject::create();
    paramsObject->setString(ASCIILiteral("url"), url);
    paramsObject->setString(ASCIILiteral("scriptSource"), scriptSource);
    paramsObject->setInteger(ASCIILiteral("startLine"), startLine);
    paramsObject->setInteger(ASCIILiteral("errorLine"), errorLine);
    paramsObject->setString(ASCIILiteral("errorMessage"), errorMessage);
    jsonMessage->setObject(ASCIILiteral("params"), WTFMove(paramsObject));

    m_frontendRouter.sendEvent(jsonMessage->toJSONString());
}

void DebuggerFrontendDispatcher::breakpointResolved(const Inspector::Protocol::Debugger::BreakpointId& breakpointId, RefPtr<Inspector::Protocol::Debugger::Location> location)
{
    Ref<InspectorObject> jsonMessage = InspectorObject::create();
    jsonMessage->setString(ASCIILiteral("method"), ASCIILiteral("Debugger.breakpointResolved"));
    Ref<InspectorObject> paramsObject = InspectorObject::create();
    paramsObject->setString(ASCIILiteral("breakpointId"), breakpointId);
    paramsObject->setObject(ASCIILiteral("location"), location);
    jsonMessage->setObject(ASCIILiteral("params"), WTFMove(paramsObject));

    m_frontendRouter.sendEvent(jsonMessage->toJSONString());
}

void DebuggerFrontendDispatcher::paused(RefPtr<Inspector::Protocol::Array<Inspector::Protocol::Debugger::CallFrame>> callFrames, Reason reason, RefPtr<Inspector::InspectorObject> data)
{
    Ref<InspectorObject> jsonMessage = InspectorObject::create();
    jsonMessage->setString(ASCIILiteral("method"), ASCIILiteral("Debugger.paused"));
    Ref<InspectorObject> paramsObject = InspectorObject::create();
    paramsObject->setArray(ASCIILiteral("callFrames"), callFrames);
    paramsObject->setString(ASCIILiteral("reason"), Inspector::Protocol::InspectorHelpers::getEnumConstantValue(reason));
    if (data)
        paramsObject->setObject(ASCIILiteral("data"), data);
    jsonMessage->setObject(ASCIILiteral("params"), WTFMove(paramsObject));

    m_frontendRouter.sendEvent(jsonMessage->toJSONString());
}

void DebuggerFrontendDispatcher::resumed()
{
    Ref<InspectorObject> jsonMessage = InspectorObject::create();
    jsonMessage->setString(ASCIILiteral("method"), ASCIILiteral("Debugger.resumed"));

    m_frontendRouter.sendEvent(jsonMessage->toJSONString());
}

void DebuggerFrontendDispatcher::didSampleProbe(RefPtr<Inspector::Protocol::Debugger::ProbeSample> sample)
{
    Ref<InspectorObject> jsonMessage = InspectorObject::create();
    jsonMessage->setString(ASCIILiteral("method"), ASCIILiteral("Debugger.didSampleProbe"));
    Ref<InspectorObject> paramsObject = InspectorObject::create();
    paramsObject->setObject(ASCIILiteral("sample"), sample);
    jsonMessage->setObject(ASCIILiteral("params"), WTFMove(paramsObject));

    m_frontendRouter.sendEvent(jsonMessage->toJSONString());
}

void DebuggerFrontendDispatcher::playBreakpointActionSound(int breakpointActionId)
{
    Ref<InspectorObject> jsonMessage = InspectorObject::create();
    jsonMessage->setString(ASCIILiteral("method"), ASCIILiteral("Debugger.playBreakpointActionSound"));
    Ref<InspectorObject> paramsObject = InspectorObject::create();
    paramsObject->setInteger(ASCIILiteral("breakpointActionId"), breakpointActionId);
    jsonMessage->setObject(ASCIILiteral("params"), WTFMove(paramsObject));

    m_frontendRouter.sendEvent(jsonMessage->toJSONString());
}

void HeapFrontendDispatcher::garbageCollected(RefPtr<Inspector::Protocol::Heap::GarbageCollection> collection)
{
    Ref<InspectorObject> jsonMessage = InspectorObject::create();
    jsonMessage->setString(ASCIILiteral("method"), ASCIILiteral("Heap.garbageCollected"));
    Ref<InspectorObject> paramsObject = InspectorObject::create();
    paramsObject->setObject(ASCIILiteral("collection"), collection);
    jsonMessage->setObject(ASCIILiteral("params"), WTFMove(paramsObject));

    m_frontendRouter.sendEvent(jsonMessage->toJSONString());
}

void HeapFrontendDispatcher::trackingStart(double timestamp, const Inspector::Protocol::Heap::HeapSnapshotData& snapshotData)
{
    Ref<InspectorObject> jsonMessage = InspectorObject::create();
    jsonMessage->setString(ASCIILiteral("method"), ASCIILiteral("Heap.trackingStart"));
    Ref<InspectorObject> paramsObject = InspectorObject::create();
    paramsObject->setDouble(ASCIILiteral("timestamp"), timestamp);
    paramsObject->setString(ASCIILiteral("snapshotData"), snapshotData);
    jsonMessage->setObject(ASCIILiteral("params"), WTFMove(paramsObject));

    m_frontendRouter.sendEvent(jsonMessage->toJSONString());
}

void HeapFrontendDispatcher::trackingComplete(double timestamp, const Inspector::Protocol::Heap::HeapSnapshotData& snapshotData)
{
    Ref<InspectorObject> jsonMessage = InspectorObject::create();
    jsonMessage->setString(ASCIILiteral("method"), ASCIILiteral("Heap.trackingComplete"));
    Ref<InspectorObject> paramsObject = InspectorObject::create();
    paramsObject->setDouble(ASCIILiteral("timestamp"), timestamp);
    paramsObject->setString(ASCIILiteral("snapshotData"), snapshotData);
    jsonMessage->setObject(ASCIILiteral("params"), WTFMove(paramsObject));

    m_frontendRouter.sendEvent(jsonMessage->toJSONString());
}

void InspectorFrontendDispatcher::evaluateForTestInFrontend(const String& script)
{
    Ref<InspectorObject> jsonMessage = InspectorObject::create();
    jsonMessage->setString(ASCIILiteral("method"), ASCIILiteral("Inspector.evaluateForTestInFrontend"));
    Ref<InspectorObject> paramsObject = InspectorObject::create();
    paramsObject->setString(ASCIILiteral("script"), script);
    jsonMessage->setObject(ASCIILiteral("params"), WTFMove(paramsObject));

    m_frontendRouter.sendEvent(jsonMessage->toJSONString());
}

void InspectorFrontendDispatcher::inspect(RefPtr<Inspector::Protocol::Runtime::RemoteObject> object, RefPtr<Inspector::InspectorObject> hints)
{
    Ref<InspectorObject> jsonMessage = InspectorObject::create();
    jsonMessage->setString(ASCIILiteral("method"), ASCIILiteral("Inspector.inspect"));
    Ref<InspectorObject> paramsObject = InspectorObject::create();
    paramsObject->setObject(ASCIILiteral("object"), object);
    paramsObject->setObject(ASCIILiteral("hints"), hints);
    jsonMessage->setObject(ASCIILiteral("params"), WTFMove(paramsObject));

    m_frontendRouter.sendEvent(jsonMessage->toJSONString());
}

void InspectorFrontendDispatcher::detached(const String& reason)
{
    Ref<InspectorObject> jsonMessage = InspectorObject::create();
    jsonMessage->setString(ASCIILiteral("method"), ASCIILiteral("Inspector.detached"));
    Ref<InspectorObject> paramsObject = InspectorObject::create();
    paramsObject->setString(ASCIILiteral("reason"), reason);
    jsonMessage->setObject(ASCIILiteral("params"), WTFMove(paramsObject));

    m_frontendRouter.sendEvent(jsonMessage->toJSONString());
}

void InspectorFrontendDispatcher::activateExtraDomains(RefPtr<Inspector::Protocol::Array<String>> domains)
{
    Ref<InspectorObject> jsonMessage = InspectorObject::create();
    jsonMessage->setString(ASCIILiteral("method"), ASCIILiteral("Inspector.activateExtraDomains"));
    Ref<InspectorObject> paramsObject = InspectorObject::create();
    paramsObject->setArray(ASCIILiteral("domains"), domains);
    jsonMessage->setObject(ASCIILiteral("params"), WTFMove(paramsObject));

    m_frontendRouter.sendEvent(jsonMessage->toJSONString());
}

void InspectorFrontendDispatcher::targetCrashed()
{
    Ref<InspectorObject> jsonMessage = InspectorObject::create();
    jsonMessage->setString(ASCIILiteral("method"), ASCIILiteral("Inspector.targetCrashed"));

    m_frontendRouter.sendEvent(jsonMessage->toJSONString());
}

void LayerTreeFrontendDispatcher::layerTreeDidChange()
{
    Ref<InspectorObject> jsonMessage = InspectorObject::create();
    jsonMessage->setString(ASCIILiteral("method"), ASCIILiteral("LayerTree.layerTreeDidChange"));

    m_frontendRouter.sendEvent(jsonMessage->toJSONString());
}

void NetworkFrontendDispatcher::requestWillBeSent(const Inspector::Protocol::Network::RequestId& requestId, const Inspector::Protocol::Network::FrameId& frameId, const Inspector::Protocol::Network::LoaderId& loaderId, const String& documentURL, RefPtr<Inspector::Protocol::Network::Request> request, double timestamp, RefPtr<Inspector::Protocol::Network::Initiator> initiator, RefPtr<Inspector::Protocol::Network::Response> redirectResponse, Inspector::Protocol::Page::ResourceType* type)
{
    Ref<InspectorObject> jsonMessage = InspectorObject::create();
    jsonMessage->setString(ASCIILiteral("method"), ASCIILiteral("Network.requestWillBeSent"));
    Ref<InspectorObject> paramsObject = InspectorObject::create();
    paramsObject->setString(ASCIILiteral("requestId"), requestId);
    paramsObject->setString(ASCIILiteral("frameId"), frameId);
    paramsObject->setString(ASCIILiteral("loaderId"), loaderId);
    paramsObject->setString(ASCIILiteral("documentURL"), documentURL);
    paramsObject->setObject(ASCIILiteral("request"), request);
    paramsObject->setDouble(ASCIILiteral("timestamp"), timestamp);
    paramsObject->setObject(ASCIILiteral("initiator"), initiator);
    if (redirectResponse)
        paramsObject->setObject(ASCIILiteral("redirectResponse"), redirectResponse);
    if (type)
        paramsObject->setString(ASCIILiteral("type"), Inspector::Protocol::InspectorHelpers::getEnumConstantValue(*type));
    jsonMessage->setObject(ASCIILiteral("params"), WTFMove(paramsObject));

    m_frontendRouter.sendEvent(jsonMessage->toJSONString());
}

void NetworkFrontendDispatcher::requestServedFromCache(const Inspector::Protocol::Network::RequestId& requestId)
{
    Ref<InspectorObject> jsonMessage = InspectorObject::create();
    jsonMessage->setString(ASCIILiteral("method"), ASCIILiteral("Network.requestServedFromCache"));
    Ref<InspectorObject> paramsObject = InspectorObject::create();
    paramsObject->setString(ASCIILiteral("requestId"), requestId);
    jsonMessage->setObject(ASCIILiteral("params"), WTFMove(paramsObject));

    m_frontendRouter.sendEvent(jsonMessage->toJSONString());
}

void NetworkFrontendDispatcher::responseReceived(const Inspector::Protocol::Network::RequestId& requestId, const Inspector::Protocol::Network::FrameId& frameId, const Inspector::Protocol::Network::LoaderId& loaderId, double timestamp, Inspector::Protocol::Page::ResourceType type, RefPtr<Inspector::Protocol::Network::Response> response)
{
    Ref<InspectorObject> jsonMessage = InspectorObject::create();
    jsonMessage->setString(ASCIILiteral("method"), ASCIILiteral("Network.responseReceived"));
    Ref<InspectorObject> paramsObject = InspectorObject::create();
    paramsObject->setString(ASCIILiteral("requestId"), requestId);
    paramsObject->setString(ASCIILiteral("frameId"), frameId);
    paramsObject->setString(ASCIILiteral("loaderId"), loaderId);
    paramsObject->setDouble(ASCIILiteral("timestamp"), timestamp);
    paramsObject->setString(ASCIILiteral("type"), Inspector::Protocol::InspectorHelpers::getEnumConstantValue(type));
    paramsObject->setObject(ASCIILiteral("response"), response);
    jsonMessage->setObject(ASCIILiteral("params"), WTFMove(paramsObject));

    m_frontendRouter.sendEvent(jsonMessage->toJSONString());
}

void NetworkFrontendDispatcher::dataReceived(const Inspector::Protocol::Network::RequestId& requestId, double timestamp, int dataLength, int encodedDataLength)
{
    Ref<InspectorObject> jsonMessage = InspectorObject::create();
    jsonMessage->setString(ASCIILiteral("method"), ASCIILiteral("Network.dataReceived"));
    Ref<InspectorObject> paramsObject = InspectorObject::create();
    paramsObject->setString(ASCIILiteral("requestId"), requestId);
    paramsObject->setDouble(ASCIILiteral("timestamp"), timestamp);
    paramsObject->setInteger(ASCIILiteral("dataLength"), dataLength);
    paramsObject->setInteger(ASCIILiteral("encodedDataLength"), encodedDataLength);
    jsonMessage->setObject(ASCIILiteral("params"), WTFMove(paramsObject));

    m_frontendRouter.sendEvent(jsonMessage->toJSONString());
}

void NetworkFrontendDispatcher::loadingFinished(const Inspector::Protocol::Network::RequestId& requestId, double timestamp, const String* const sourceMapURL)
{
    Ref<InspectorObject> jsonMessage = InspectorObject::create();
    jsonMessage->setString(ASCIILiteral("method"), ASCIILiteral("Network.loadingFinished"));
    Ref<InspectorObject> paramsObject = InspectorObject::create();
    paramsObject->setString(ASCIILiteral("requestId"), requestId);
    paramsObject->setDouble(ASCIILiteral("timestamp"), timestamp);
    if (sourceMapURL)
        paramsObject->setString(ASCIILiteral("sourceMapURL"), *sourceMapURL);
    jsonMessage->setObject(ASCIILiteral("params"), WTFMove(paramsObject));

    m_frontendRouter.sendEvent(jsonMessage->toJSONString());
}

void NetworkFrontendDispatcher::loadingFailed(const Inspector::Protocol::Network::RequestId& requestId, double timestamp, const String& errorText, const bool* const canceled)
{
    Ref<InspectorObject> jsonMessage = InspectorObject::create();
    jsonMessage->setString(ASCIILiteral("method"), ASCIILiteral("Network.loadingFailed"));
    Ref<InspectorObject> paramsObject = InspectorObject::create();
    paramsObject->setString(ASCIILiteral("requestId"), requestId);
    paramsObject->setDouble(ASCIILiteral("timestamp"), timestamp);
    paramsObject->setString(ASCIILiteral("errorText"), errorText);
    if (canceled)
        paramsObject->setBoolean(ASCIILiteral("canceled"), *canceled);
    jsonMessage->setObject(ASCIILiteral("params"), WTFMove(paramsObject));

    m_frontendRouter.sendEvent(jsonMessage->toJSONString());
}

void NetworkFrontendDispatcher::requestServedFromMemoryCache(const Inspector::Protocol::Network::RequestId& requestId, const Inspector::Protocol::Network::FrameId& frameId, const Inspector::Protocol::Network::LoaderId& loaderId, const String& documentURL, double timestamp, RefPtr<Inspector::Protocol::Network::Initiator> initiator, RefPtr<Inspector::Protocol::Network::CachedResource> resource)
{
    Ref<InspectorObject> jsonMessage = InspectorObject::create();
    jsonMessage->setString(ASCIILiteral("method"), ASCIILiteral("Network.requestServedFromMemoryCache"));
    Ref<InspectorObject> paramsObject = InspectorObject::create();
    paramsObject->setString(ASCIILiteral("requestId"), requestId);
    paramsObject->setString(ASCIILiteral("frameId"), frameId);
    paramsObject->setString(ASCIILiteral("loaderId"), loaderId);
    paramsObject->setString(ASCIILiteral("documentURL"), documentURL);
    paramsObject->setDouble(ASCIILiteral("timestamp"), timestamp);
    paramsObject->setObject(ASCIILiteral("initiator"), initiator);
    paramsObject->setObject(ASCIILiteral("resource"), resource);
    jsonMessage->setObject(ASCIILiteral("params"), WTFMove(paramsObject));

    m_frontendRouter.sendEvent(jsonMessage->toJSONString());
}

void NetworkFrontendDispatcher::webSocketWillSendHandshakeRequest(const Inspector::Protocol::Network::RequestId& requestId, double timestamp, RefPtr<Inspector::Protocol::Network::WebSocketRequest> request)
{
    Ref<InspectorObject> jsonMessage = InspectorObject::create();
    jsonMessage->setString(ASCIILiteral("method"), ASCIILiteral("Network.webSocketWillSendHandshakeRequest"));
    Ref<InspectorObject> paramsObject = InspectorObject::create();
    paramsObject->setString(ASCIILiteral("requestId"), requestId);
    paramsObject->setDouble(ASCIILiteral("timestamp"), timestamp);
    paramsObject->setObject(ASCIILiteral("request"), request);
    jsonMessage->setObject(ASCIILiteral("params"), WTFMove(paramsObject));

    m_frontendRouter.sendEvent(jsonMessage->toJSONString());
}

void NetworkFrontendDispatcher::webSocketHandshakeResponseReceived(const Inspector::Protocol::Network::RequestId& requestId, double timestamp, RefPtr<Inspector::Protocol::Network::WebSocketResponse> response)
{
    Ref<InspectorObject> jsonMessage = InspectorObject::create();
    jsonMessage->setString(ASCIILiteral("method"), ASCIILiteral("Network.webSocketHandshakeResponseReceived"));
    Ref<InspectorObject> paramsObject = InspectorObject::create();
    paramsObject->setString(ASCIILiteral("requestId"), requestId);
    paramsObject->setDouble(ASCIILiteral("timestamp"), timestamp);
    paramsObject->setObject(ASCIILiteral("response"), response);
    jsonMessage->setObject(ASCIILiteral("params"), WTFMove(paramsObject));

    m_frontendRouter.sendEvent(jsonMessage->toJSONString());
}

void NetworkFrontendDispatcher::webSocketCreated(const Inspector::Protocol::Network::RequestId& requestId, const String& url)
{
    Ref<InspectorObject> jsonMessage = InspectorObject::create();
    jsonMessage->setString(ASCIILiteral("method"), ASCIILiteral("Network.webSocketCreated"));
    Ref<InspectorObject> paramsObject = InspectorObject::create();
    paramsObject->setString(ASCIILiteral("requestId"), requestId);
    paramsObject->setString(ASCIILiteral("url"), url);
    jsonMessage->setObject(ASCIILiteral("params"), WTFMove(paramsObject));

    m_frontendRouter.sendEvent(jsonMessage->toJSONString());
}

void NetworkFrontendDispatcher::webSocketClosed(const Inspector::Protocol::Network::RequestId& requestId, double timestamp)
{
    Ref<InspectorObject> jsonMessage = InspectorObject::create();
    jsonMessage->setString(ASCIILiteral("method"), ASCIILiteral("Network.webSocketClosed"));
    Ref<InspectorObject> paramsObject = InspectorObject::create();
    paramsObject->setString(ASCIILiteral("requestId"), requestId);
    paramsObject->setDouble(ASCIILiteral("timestamp"), timestamp);
    jsonMessage->setObject(ASCIILiteral("params"), WTFMove(paramsObject));

    m_frontendRouter.sendEvent(jsonMessage->toJSONString());
}

void NetworkFrontendDispatcher::webSocketFrameReceived(const Inspector::Protocol::Network::RequestId& requestId, double timestamp, RefPtr<Inspector::Protocol::Network::WebSocketFrame> response)
{
    Ref<InspectorObject> jsonMessage = InspectorObject::create();
    jsonMessage->setString(ASCIILiteral("method"), ASCIILiteral("Network.webSocketFrameReceived"));
    Ref<InspectorObject> paramsObject = InspectorObject::create();
    paramsObject->setString(ASCIILiteral("requestId"), requestId);
    paramsObject->setDouble(ASCIILiteral("timestamp"), timestamp);
    paramsObject->setObject(ASCIILiteral("response"), response);
    jsonMessage->setObject(ASCIILiteral("params"), WTFMove(paramsObject));

    m_frontendRouter.sendEvent(jsonMessage->toJSONString());
}

void NetworkFrontendDispatcher::webSocketFrameError(const Inspector::Protocol::Network::RequestId& requestId, double timestamp, const String& errorMessage)
{
    Ref<InspectorObject> jsonMessage = InspectorObject::create();
    jsonMessage->setString(ASCIILiteral("method"), ASCIILiteral("Network.webSocketFrameError"));
    Ref<InspectorObject> paramsObject = InspectorObject::create();
    paramsObject->setString(ASCIILiteral("requestId"), requestId);
    paramsObject->setDouble(ASCIILiteral("timestamp"), timestamp);
    paramsObject->setString(ASCIILiteral("errorMessage"), errorMessage);
    jsonMessage->setObject(ASCIILiteral("params"), WTFMove(paramsObject));

    m_frontendRouter.sendEvent(jsonMessage->toJSONString());
}

void NetworkFrontendDispatcher::webSocketFrameSent(const Inspector::Protocol::Network::RequestId& requestId, double timestamp, RefPtr<Inspector::Protocol::Network::WebSocketFrame> response)
{
    Ref<InspectorObject> jsonMessage = InspectorObject::create();
    jsonMessage->setString(ASCIILiteral("method"), ASCIILiteral("Network.webSocketFrameSent"));
    Ref<InspectorObject> paramsObject = InspectorObject::create();
    paramsObject->setString(ASCIILiteral("requestId"), requestId);
    paramsObject->setDouble(ASCIILiteral("timestamp"), timestamp);
    paramsObject->setObject(ASCIILiteral("response"), response);
    jsonMessage->setObject(ASCIILiteral("params"), WTFMove(paramsObject));

    m_frontendRouter.sendEvent(jsonMessage->toJSONString());
}

void PageFrontendDispatcher::domContentEventFired(double timestamp)
{
    Ref<InspectorObject> jsonMessage = InspectorObject::create();
    jsonMessage->setString(ASCIILiteral("method"), ASCIILiteral("Page.domContentEventFired"));
    Ref<InspectorObject> paramsObject = InspectorObject::create();
    paramsObject->setDouble(ASCIILiteral("timestamp"), timestamp);
    jsonMessage->setObject(ASCIILiteral("params"), WTFMove(paramsObject));

    m_frontendRouter.sendEvent(jsonMessage->toJSONString());
}

void PageFrontendDispatcher::loadEventFired(double timestamp)
{
    Ref<InspectorObject> jsonMessage = InspectorObject::create();
    jsonMessage->setString(ASCIILiteral("method"), ASCIILiteral("Page.loadEventFired"));
    Ref<InspectorObject> paramsObject = InspectorObject::create();
    paramsObject->setDouble(ASCIILiteral("timestamp"), timestamp);
    jsonMessage->setObject(ASCIILiteral("params"), WTFMove(paramsObject));

    m_frontendRouter.sendEvent(jsonMessage->toJSONString());
}

void PageFrontendDispatcher::frameNavigated(RefPtr<Inspector::Protocol::Page::Frame> frame)
{
    Ref<InspectorObject> jsonMessage = InspectorObject::create();
    jsonMessage->setString(ASCIILiteral("method"), ASCIILiteral("Page.frameNavigated"));
    Ref<InspectorObject> paramsObject = InspectorObject::create();
    paramsObject->setObject(ASCIILiteral("frame"), frame);
    jsonMessage->setObject(ASCIILiteral("params"), WTFMove(paramsObject));

    m_frontendRouter.sendEvent(jsonMessage->toJSONString());
}

void PageFrontendDispatcher::frameDetached(const Inspector::Protocol::Network::FrameId& frameId)
{
    Ref<InspectorObject> jsonMessage = InspectorObject::create();
    jsonMessage->setString(ASCIILiteral("method"), ASCIILiteral("Page.frameDetached"));
    Ref<InspectorObject> paramsObject = InspectorObject::create();
    paramsObject->setString(ASCIILiteral("frameId"), frameId);
    jsonMessage->setObject(ASCIILiteral("params"), WTFMove(paramsObject));

    m_frontendRouter.sendEvent(jsonMessage->toJSONString());
}

void PageFrontendDispatcher::frameStartedLoading(const Inspector::Protocol::Network::FrameId& frameId)
{
    Ref<InspectorObject> jsonMessage = InspectorObject::create();
    jsonMessage->setString(ASCIILiteral("method"), ASCIILiteral("Page.frameStartedLoading"));
    Ref<InspectorObject> paramsObject = InspectorObject::create();
    paramsObject->setString(ASCIILiteral("frameId"), frameId);
    jsonMessage->setObject(ASCIILiteral("params"), WTFMove(paramsObject));

    m_frontendRouter.sendEvent(jsonMessage->toJSONString());
}

void PageFrontendDispatcher::frameStoppedLoading(const Inspector::Protocol::Network::FrameId& frameId)
{
    Ref<InspectorObject> jsonMessage = InspectorObject::create();
    jsonMessage->setString(ASCIILiteral("method"), ASCIILiteral("Page.frameStoppedLoading"));
    Ref<InspectorObject> paramsObject = InspectorObject::create();
    paramsObject->setString(ASCIILiteral("frameId"), frameId);
    jsonMessage->setObject(ASCIILiteral("params"), WTFMove(paramsObject));

    m_frontendRouter.sendEvent(jsonMessage->toJSONString());
}

void PageFrontendDispatcher::frameScheduledNavigation(const Inspector::Protocol::Network::FrameId& frameId, double delay)
{
    Ref<InspectorObject> jsonMessage = InspectorObject::create();
    jsonMessage->setString(ASCIILiteral("method"), ASCIILiteral("Page.frameScheduledNavigation"));
    Ref<InspectorObject> paramsObject = InspectorObject::create();
    paramsObject->setString(ASCIILiteral("frameId"), frameId);
    paramsObject->setDouble(ASCIILiteral("delay"), delay);
    jsonMessage->setObject(ASCIILiteral("params"), WTFMove(paramsObject));

    m_frontendRouter.sendEvent(jsonMessage->toJSONString());
}

void PageFrontendDispatcher::frameClearedScheduledNavigation(const Inspector::Protocol::Network::FrameId& frameId)
{
    Ref<InspectorObject> jsonMessage = InspectorObject::create();
    jsonMessage->setString(ASCIILiteral("method"), ASCIILiteral("Page.frameClearedScheduledNavigation"));
    Ref<InspectorObject> paramsObject = InspectorObject::create();
    paramsObject->setString(ASCIILiteral("frameId"), frameId);
    jsonMessage->setObject(ASCIILiteral("params"), WTFMove(paramsObject));

    m_frontendRouter.sendEvent(jsonMessage->toJSONString());
}

void PageFrontendDispatcher::javascriptDialogOpening(const String& message)
{
    Ref<InspectorObject> jsonMessage = InspectorObject::create();
    jsonMessage->setString(ASCIILiteral("method"), ASCIILiteral("Page.javascriptDialogOpening"));
    Ref<InspectorObject> paramsObject = InspectorObject::create();
    paramsObject->setString(ASCIILiteral("message"), message);
    jsonMessage->setObject(ASCIILiteral("params"), WTFMove(paramsObject));

    m_frontendRouter.sendEvent(jsonMessage->toJSONString());
}

void PageFrontendDispatcher::javascriptDialogClosed()
{
    Ref<InspectorObject> jsonMessage = InspectorObject::create();
    jsonMessage->setString(ASCIILiteral("method"), ASCIILiteral("Page.javascriptDialogClosed"));

    m_frontendRouter.sendEvent(jsonMessage->toJSONString());
}

void PageFrontendDispatcher::scriptsEnabled(bool isEnabled)
{
    Ref<InspectorObject> jsonMessage = InspectorObject::create();
    jsonMessage->setString(ASCIILiteral("method"), ASCIILiteral("Page.scriptsEnabled"));
    Ref<InspectorObject> paramsObject = InspectorObject::create();
    paramsObject->setBoolean(ASCIILiteral("isEnabled"), isEnabled);
    jsonMessage->setObject(ASCIILiteral("params"), WTFMove(paramsObject));

    m_frontendRouter.sendEvent(jsonMessage->toJSONString());
}

void RuntimeFrontendDispatcher::executionContextCreated(RefPtr<Inspector::Protocol::Runtime::ExecutionContextDescription> context)
{
    Ref<InspectorObject> jsonMessage = InspectorObject::create();
    jsonMessage->setString(ASCIILiteral("method"), ASCIILiteral("Runtime.executionContextCreated"));
    Ref<InspectorObject> paramsObject = InspectorObject::create();
    paramsObject->setObject(ASCIILiteral("context"), context);
    jsonMessage->setObject(ASCIILiteral("params"), WTFMove(paramsObject));

    m_frontendRouter.sendEvent(jsonMessage->toJSONString());
}

void ScriptProfilerFrontendDispatcher::trackingStart(double timestamp)
{
    Ref<InspectorObject> jsonMessage = InspectorObject::create();
    jsonMessage->setString(ASCIILiteral("method"), ASCIILiteral("ScriptProfiler.trackingStart"));
    Ref<InspectorObject> paramsObject = InspectorObject::create();
    paramsObject->setDouble(ASCIILiteral("timestamp"), timestamp);
    jsonMessage->setObject(ASCIILiteral("params"), WTFMove(paramsObject));

    m_frontendRouter.sendEvent(jsonMessage->toJSONString());
}

void ScriptProfilerFrontendDispatcher::trackingUpdate(RefPtr<Inspector::Protocol::ScriptProfiler::Event> event)
{
    Ref<InspectorObject> jsonMessage = InspectorObject::create();
    jsonMessage->setString(ASCIILiteral("method"), ASCIILiteral("ScriptProfiler.trackingUpdate"));
    Ref<InspectorObject> paramsObject = InspectorObject::create();
    paramsObject->setObject(ASCIILiteral("event"), event);
    jsonMessage->setObject(ASCIILiteral("params"), WTFMove(paramsObject));

    m_frontendRouter.sendEvent(jsonMessage->toJSONString());
}

void ScriptProfilerFrontendDispatcher::trackingComplete(RefPtr<Inspector::Protocol::ScriptProfiler::Samples> samples)
{
    Ref<InspectorObject> jsonMessage = InspectorObject::create();
    jsonMessage->setString(ASCIILiteral("method"), ASCIILiteral("ScriptProfiler.trackingComplete"));
    Ref<InspectorObject> paramsObject = InspectorObject::create();
    if (samples)
        paramsObject->setObject(ASCIILiteral("samples"), samples);
    jsonMessage->setObject(ASCIILiteral("params"), WTFMove(paramsObject));

    m_frontendRouter.sendEvent(jsonMessage->toJSONString());
}

void ScriptProfilerFrontendDispatcher::programmaticCaptureStarted()
{
    Ref<InspectorObject> jsonMessage = InspectorObject::create();
    jsonMessage->setString(ASCIILiteral("method"), ASCIILiteral("ScriptProfiler.programmaticCaptureStarted"));

    m_frontendRouter.sendEvent(jsonMessage->toJSONString());
}

void ScriptProfilerFrontendDispatcher::programmaticCaptureStopped()
{
    Ref<InspectorObject> jsonMessage = InspectorObject::create();
    jsonMessage->setString(ASCIILiteral("method"), ASCIILiteral("ScriptProfiler.programmaticCaptureStopped"));

    m_frontendRouter.sendEvent(jsonMessage->toJSONString());
}

void TimelineFrontendDispatcher::eventRecorded(RefPtr<Inspector::Protocol::Timeline::TimelineEvent> record)
{
    Ref<InspectorObject> jsonMessage = InspectorObject::create();
    jsonMessage->setString(ASCIILiteral("method"), ASCIILiteral("Timeline.eventRecorded"));
    Ref<InspectorObject> paramsObject = InspectorObject::create();
    paramsObject->setObject(ASCIILiteral("record"), record);
    jsonMessage->setObject(ASCIILiteral("params"), WTFMove(paramsObject));

    m_frontendRouter.sendEvent(jsonMessage->toJSONString());
}

void TimelineFrontendDispatcher::recordingStarted(double startTime)
{
    Ref<InspectorObject> jsonMessage = InspectorObject::create();
    jsonMessage->setString(ASCIILiteral("method"), ASCIILiteral("Timeline.recordingStarted"));
    Ref<InspectorObject> paramsObject = InspectorObject::create();
    paramsObject->setDouble(ASCIILiteral("startTime"), startTime);
    jsonMessage->setObject(ASCIILiteral("params"), WTFMove(paramsObject));

    m_frontendRouter.sendEvent(jsonMessage->toJSONString());
}

void TimelineFrontendDispatcher::recordingStopped(double endTime)
{
    Ref<InspectorObject> jsonMessage = InspectorObject::create();
    jsonMessage->setString(ASCIILiteral("method"), ASCIILiteral("Timeline.recordingStopped"));
    Ref<InspectorObject> paramsObject = InspectorObject::create();
    paramsObject->setDouble(ASCIILiteral("endTime"), endTime);
    jsonMessage->setObject(ASCIILiteral("params"), WTFMove(paramsObject));

    m_frontendRouter.sendEvent(jsonMessage->toJSONString());
}

void TimelineFrontendDispatcher::autoCaptureStarted()
{
    Ref<InspectorObject> jsonMessage = InspectorObject::create();
    jsonMessage->setString(ASCIILiteral("method"), ASCIILiteral("Timeline.autoCaptureStarted"));

    m_frontendRouter.sendEvent(jsonMessage->toJSONString());
}

void TimelineFrontendDispatcher::programmaticCaptureStarted()
{
    Ref<InspectorObject> jsonMessage = InspectorObject::create();
    jsonMessage->setString(ASCIILiteral("method"), ASCIILiteral("Timeline.programmaticCaptureStarted"));

    m_frontendRouter.sendEvent(jsonMessage->toJSONString());
}

void TimelineFrontendDispatcher::programmaticCaptureStopped()
{
    Ref<InspectorObject> jsonMessage = InspectorObject::create();
    jsonMessage->setString(ASCIILiteral("method"), ASCIILiteral("Timeline.programmaticCaptureStopped"));

    m_frontendRouter.sendEvent(jsonMessage->toJSONString());
}

} // namespace Inspector
