| /* |
| * Copyright (C) 2018 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 INC. ``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 |
| * 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 "WebPageInspectorController.h" |
| |
| #include "WebFrameProxy.h" |
| #include "WebPageInspectorTargetAgent.h" |
| #include "WebPageProxy.h" |
| #include <JavaScriptCore/InspectorAgentBase.h> |
| #include <JavaScriptCore/InspectorBackendDispatcher.h> |
| #include <JavaScriptCore/InspectorBackendDispatchers.h> |
| #include <JavaScriptCore/InspectorFrontendRouter.h> |
| |
| namespace WebKit { |
| |
| using namespace Inspector; |
| |
| WebPageInspectorController::WebPageInspectorController(WebPageProxy& page) |
| : m_page(page) |
| , m_frontendRouter(FrontendRouter::create()) |
| , m_backendDispatcher(BackendDispatcher::create(m_frontendRouter.copyRef())) |
| { |
| auto targetAgent = makeUnique<WebPageInspectorTargetAgent>(m_frontendRouter.get(), m_backendDispatcher.get()); |
| |
| m_targetAgent = targetAgent.get(); |
| |
| m_agents.append(WTFMove(targetAgent)); |
| } |
| |
| void WebPageInspectorController::pageClosed() |
| { |
| disconnectAllFrontends(); |
| |
| m_agents.discardValues(); |
| } |
| |
| bool WebPageInspectorController::hasLocalFrontend() const |
| { |
| return m_frontendRouter->hasLocalFrontend(); |
| } |
| |
| void WebPageInspectorController::connectFrontend(Inspector::FrontendChannel& frontendChannel, bool, bool) |
| { |
| bool connectingFirstFrontend = !m_frontendRouter->hasFrontends(); |
| |
| m_frontendRouter->connectFrontend(frontendChannel); |
| |
| if (connectingFirstFrontend) |
| m_agents.didCreateFrontendAndBackend(&m_frontendRouter.get(), &m_backendDispatcher.get()); |
| |
| m_page.didChangeInspectorFrontendCount(m_frontendRouter->frontendCount()); |
| |
| #if ENABLE(REMOTE_INSPECTOR) |
| if (hasLocalFrontend()) |
| m_page.remoteInspectorInformationDidChange(); |
| #endif |
| } |
| |
| void WebPageInspectorController::disconnectFrontend(FrontendChannel& frontendChannel) |
| { |
| m_frontendRouter->disconnectFrontend(frontendChannel); |
| |
| bool disconnectingLastFrontend = !m_frontendRouter->hasFrontends(); |
| if (disconnectingLastFrontend) |
| m_agents.willDestroyFrontendAndBackend(DisconnectReason::InspectorDestroyed); |
| |
| m_page.didChangeInspectorFrontendCount(m_frontendRouter->frontendCount()); |
| |
| #if ENABLE(REMOTE_INSPECTOR) |
| if (disconnectingLastFrontend) |
| m_page.remoteInspectorInformationDidChange(); |
| #endif |
| } |
| |
| void WebPageInspectorController::disconnectAllFrontends() |
| { |
| // FIXME: Handle a local inspector client. |
| |
| if (!m_frontendRouter->hasFrontends()) |
| return; |
| |
| // Notify agents first, since they may need to use InspectorClient. |
| m_agents.willDestroyFrontendAndBackend(DisconnectReason::InspectedTargetDestroyed); |
| |
| // Disconnect any remaining remote frontends. |
| m_frontendRouter->disconnectAllFrontends(); |
| |
| m_page.didChangeInspectorFrontendCount(m_frontendRouter->frontendCount()); |
| |
| #if ENABLE(REMOTE_INSPECTOR) |
| m_page.remoteInspectorInformationDidChange(); |
| #endif |
| } |
| |
| void WebPageInspectorController::dispatchMessageFromFrontend(const String& message) |
| { |
| m_backendDispatcher->dispatch(message); |
| } |
| |
| #if ENABLE(REMOTE_INSPECTOR) |
| void WebPageInspectorController::setIndicating(bool indicating) |
| { |
| #if !PLATFORM(IOS_FAMILY) |
| m_page.setIndicating(indicating); |
| #else |
| if (indicating) |
| m_page.showInspectorIndication(); |
| else |
| m_page.hideInspectorIndication(); |
| #endif |
| } |
| #endif |
| |
| void WebPageInspectorController::clearTargets() |
| { |
| for (auto& target : m_targets) |
| m_targetAgent->targetDestroyed(*target.get()); |
| |
| m_targets.clear(); |
| } |
| |
| void WebPageInspectorController::createInspectorTarget(const String& targetId, Inspector::InspectorTargetType type) |
| { |
| auto target = InspectorTargetProxy::create(m_page, targetId, type); |
| m_targets.append(target.copyRef()); |
| |
| m_targetAgent->targetCreated(target.get()); |
| } |
| |
| void WebPageInspectorController::destroyInspectorTarget(const String& targetId) |
| { |
| auto position = m_targets.findMatching([&](const auto& item) { return item->identifier() == targetId; }); |
| if (position == notFound) |
| return; |
| |
| auto& target = m_targets[position]; |
| m_targetAgent->targetDestroyed(*target.get()); |
| |
| m_targets.remove(position); |
| } |
| |
| void WebPageInspectorController::sendMessageToInspectorFrontend(const String& targetId, const String& message) |
| { |
| m_targetAgent->sendMessageFromTargetToFrontend(targetId, message); |
| } |
| |
| } // namespace WebKit |