Web Inspector: "Reload Web Inspector" button no longer partially works
[WebKit-https.git] / Source / WebKit / UIProcess / WebPageInspectorController.cpp
1 /*
2  * Copyright (C) 2018 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27 #include "WebPageInspectorController.h"
28
29 #include "WebFrameProxy.h"
30 #include "WebPageInspectorTargetAgent.h"
31 #include "WebPageProxy.h"
32 #include <JavaScriptCore/InspectorAgentBase.h>
33 #include <JavaScriptCore/InspectorBackendDispatcher.h>
34 #include <JavaScriptCore/InspectorBackendDispatchers.h>
35 #include <JavaScriptCore/InspectorFrontendRouter.h>
36
37 namespace WebKit {
38
39 using namespace Inspector;
40
41 WebPageInspectorController::WebPageInspectorController(WebPageProxy& page)
42     : m_page(page)
43     , m_frontendRouter(FrontendRouter::create())
44     , m_backendDispatcher(BackendDispatcher::create(m_frontendRouter.copyRef()))
45 {
46     auto targetAgent = std::make_unique<WebPageInspectorTargetAgent>(m_frontendRouter.get(), m_backendDispatcher.get());
47
48     m_targetAgent = targetAgent.get();
49
50     m_agents.append(WTFMove(targetAgent));
51 }
52
53 void WebPageInspectorController::pageClosed()
54 {
55     disconnectAllFrontends();
56
57     m_agents.discardValues();
58 }
59
60 bool WebPageInspectorController::hasLocalFrontend() const
61 {
62     return m_frontendRouter->hasLocalFrontend();
63 }
64
65 void WebPageInspectorController::connectFrontend(Inspector::FrontendChannel& frontendChannel, bool, bool)
66 {
67     bool connectingFirstFrontend = !m_frontendRouter->hasFrontends();
68
69     m_frontendRouter->connectFrontend(frontendChannel);
70
71     if (connectingFirstFrontend)
72         m_agents.didCreateFrontendAndBackend(&m_frontendRouter.get(), &m_backendDispatcher.get());
73
74     m_page.didChangeInspectorFrontendCount(m_frontendRouter->frontendCount());
75
76 #if ENABLE(REMOTE_INSPECTOR)
77     if (hasLocalFrontend())
78         m_page.remoteInspectorInformationDidChange();
79 #endif
80 }
81
82 void WebPageInspectorController::disconnectFrontend(FrontendChannel& frontendChannel)
83 {
84     m_frontendRouter->disconnectFrontend(frontendChannel);
85
86     bool disconnectingLastFrontend = !m_frontendRouter->hasFrontends();
87     if (disconnectingLastFrontend)
88         m_agents.willDestroyFrontendAndBackend(DisconnectReason::InspectorDestroyed);
89
90     m_page.didChangeInspectorFrontendCount(m_frontendRouter->frontendCount());
91
92 #if ENABLE(REMOTE_INSPECTOR)
93     if (disconnectingLastFrontend)
94         m_page.remoteInspectorInformationDidChange();
95 #endif
96 }
97
98 void WebPageInspectorController::disconnectAllFrontends()
99 {
100     // FIXME: Handle a local inspector client.
101
102     if (!m_frontendRouter->hasFrontends())
103         return;
104
105     // Notify agents first, since they may need to use InspectorClient.
106     m_agents.willDestroyFrontendAndBackend(DisconnectReason::InspectedTargetDestroyed);
107
108     // Disconnect any remaining remote frontends.
109     m_frontendRouter->disconnectAllFrontends();
110
111     m_page.didChangeInspectorFrontendCount(m_frontendRouter->frontendCount());
112
113 #if ENABLE(REMOTE_INSPECTOR)
114     m_page.remoteInspectorInformationDidChange();
115 #endif
116 }
117
118 void WebPageInspectorController::dispatchMessageFromFrontend(const String& message)
119 {
120     m_backendDispatcher->dispatch(message);
121 }
122
123 #if ENABLE(REMOTE_INSPECTOR)
124 void WebPageInspectorController::setIndicating(bool indicating)
125 {
126 #if !PLATFORM(IOS_FAMILY)
127     m_page.setIndicating(indicating);
128 #else
129     if (indicating)
130         m_page.showInspectorIndication();
131     else
132         m_page.hideInspectorIndication();
133 #endif
134 }
135 #endif
136
137 void WebPageInspectorController::clearTargets()
138 {
139     for (auto& target : m_targets)
140         m_targetAgent->targetDestroyed(*target.get());
141
142     m_targets.clear();
143 }
144
145 void WebPageInspectorController::createInspectorTarget(const String& targetId, Inspector::InspectorTargetType type)
146 {
147     auto target = InspectorTargetProxy::create(m_page, targetId, type);
148     m_targets.append(target.copyRef());
149
150     m_targetAgent->targetCreated(target.get());
151 }
152
153 void WebPageInspectorController::destroyInspectorTarget(const String& targetId)
154 {
155     auto position = m_targets.findMatching([&](const auto& item) { return item->identifier() == targetId; });
156     if (position == notFound)
157         return;
158
159     auto& target = m_targets[position];
160     m_targetAgent->targetDestroyed(*target.get());
161
162     m_targets.remove(position);
163 }
164
165 void WebPageInspectorController::sendMessageToInspectorFrontend(const String& targetId, const String& message)
166 {
167     m_targetAgent->sendMessageFromTargetToFrontend(targetId, message);
168 }
169
170 } // namespace WebKit