430522bbda9e3981f4cd530a741ee5ebb91e30bc
[WebKit-https.git] / Source / WebKit2 / WebProcess / WebPage / WebInspector.cpp
1 /*
2  * Copyright (C) 2010 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. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27 #include "WebInspector.h"
28
29 #if ENABLE(INSPECTOR)
30 #include "WebFrame.h"
31 #include "WebInspectorFrontendClient.h"
32 #include "WebInspectorProxyMessages.h"
33 #include "WebPage.h"
34 #include "WebPageCreationParameters.h"
35 #include "WebProcess.h"
36 #include <WebCore/InspectorController.h>
37 #include <WebCore/InspectorFrontendClient.h>
38 #include <WebCore/MainFrame.h>
39 #include <WebCore/Page.h>
40 #include <WebCore/ScriptController.h>
41 #include <bindings/ScriptValue.h>
42 #include <wtf/text/StringConcatenate.h>
43
44 using namespace WebCore;
45
46 namespace WebKit {
47
48 PassRefPtr<WebInspector> WebInspector::create(WebPage* page, InspectorFrontendChannel* frontendChannel)
49 {
50     return adoptRef(new WebInspector(page, frontendChannel));
51 }
52
53 WebInspector::WebInspector(WebPage* page, InspectorFrontendChannel* frontendChannel)
54     : m_page(page)
55     , m_inspectorPage(0)
56     , m_frontendClient(0)
57     , m_frontendChannel(frontendChannel)
58 #if PLATFORM(MAC)
59     , m_hasLocalizedStringsURL(false)
60 #endif
61 #if ENABLE(INSPECTOR_SERVER)
62     , m_remoteFrontendConnected(false)
63 #endif
64 {
65 }
66
67 // Called from WebInspectorClient
68 WebPage* WebInspector::createInspectorPage()
69 {
70     if (!m_page)
71         return 0;
72
73     ASSERT(!m_inspectorPage);
74     ASSERT(!m_frontendClient);
75
76     uint64_t inspectorPageID = 0;
77     WebPageCreationParameters parameters;
78
79     if (!WebProcess::shared().parentProcessConnection()->sendSync(Messages::WebInspectorProxy::CreateInspectorPage(),
80             Messages::WebInspectorProxy::CreateInspectorPage::Reply(inspectorPageID, parameters),
81             m_page->pageID(), std::chrono::milliseconds::max())) {
82         return 0;
83     }
84
85     if (!inspectorPageID)
86         return 0;
87
88     WebProcess::shared().createWebPage(inspectorPageID, parameters);
89     m_inspectorPage = WebProcess::shared().webPage(inspectorPageID);
90     ASSERT(m_inspectorPage);
91
92     auto frontendClient = std::make_unique<WebInspectorFrontendClient>(m_page, m_inspectorPage);
93     m_frontendClient = frontendClient.get();
94     m_inspectorPage->corePage()->inspectorController().setInspectorFrontendClient(std::move(frontendClient));
95     return m_inspectorPage;
96 }
97
98 void WebInspector::destroyInspectorPage()
99 {
100     m_inspectorPage = 0;
101     m_frontendClient = 0;
102     m_frontendChannel = 0;
103 }
104
105 // Called from WebInspectorFrontendClient
106 void WebInspector::didClose()
107 {
108     WebProcess::shared().parentProcessConnection()->send(Messages::WebInspectorProxy::DidClose(), m_page->pageID());
109     destroyInspectorPage();
110 }
111
112 void WebInspector::bringToFront()
113 {
114     WebProcess::shared().parentProcessConnection()->send(Messages::WebInspectorProxy::BringToFront(), m_page->pageID());
115 }
116
117 void WebInspector::inspectedURLChanged(const String& urlString)
118 {
119     WebProcess::shared().parentProcessConnection()->send(Messages::WebInspectorProxy::InspectedURLChanged(urlString), m_page->pageID());
120 }
121
122 void WebInspector::save(const String& filename, const String& content, bool base64Encoded, bool forceSaveAs)
123 {
124     WebProcess::shared().parentProcessConnection()->send(Messages::WebInspectorProxy::Save(filename, content, base64Encoded, forceSaveAs), m_page->pageID());
125 }
126
127 void WebInspector::append(const String& filename, const String& content)
128 {
129     WebProcess::shared().parentProcessConnection()->send(Messages::WebInspectorProxy::Append(filename, content), m_page->pageID());
130 }
131
132 void WebInspector::attachBottom()
133 {
134     WebProcess::shared().parentProcessConnection()->send(Messages::WebInspectorProxy::AttachBottom(), m_page->pageID());
135 }
136
137 void WebInspector::attachRight()
138 {
139     WebProcess::shared().parentProcessConnection()->send(Messages::WebInspectorProxy::AttachRight(), m_page->pageID());
140 }
141
142 void WebInspector::detach()
143 {
144     WebProcess::shared().parentProcessConnection()->send(Messages::WebInspectorProxy::Detach(), m_page->pageID());
145 }
146
147 void WebInspector::setAttachedWindowHeight(unsigned height)
148 {
149     WebProcess::shared().parentProcessConnection()->send(Messages::WebInspectorProxy::SetAttachedWindowHeight(height), m_page->pageID());
150 }
151
152 void WebInspector::setAttachedWindowWidth(unsigned width)
153 {
154     WebProcess::shared().parentProcessConnection()->send(Messages::WebInspectorProxy::SetAttachedWindowWidth(width), m_page->pageID());
155 }
156
157 void WebInspector::setToolbarHeight(unsigned height)
158 {
159     WebProcess::shared().parentProcessConnection()->send(Messages::WebInspectorProxy::SetToolbarHeight(height), m_page->pageID());
160 }
161
162 // Called by WebInspector messages
163 void WebInspector::show()
164 {
165     m_page->corePage()->inspectorController().show();
166 }
167
168 void WebInspector::close()
169 {
170     m_page->corePage()->inspectorController().close();
171 }
172
173 void WebInspector::didSave(const String& url)
174 {
175     ASSERT(m_inspectorPage);
176     m_inspectorPage->corePage()->mainFrame().script().executeScript(makeString("InspectorFrontendAPI.savedURL(\"", url, "\")"));
177 }
178
179 void WebInspector::didAppend(const String& url)
180 {
181     ASSERT(m_inspectorPage);
182     m_inspectorPage->corePage()->mainFrame().script().executeScript(makeString("InspectorFrontendAPI.appendedToURL(\"", url, "\")"));
183 }
184
185 void WebInspector::attachedBottom()
186 {
187     if (m_frontendClient)
188         m_frontendClient->setAttachedWindow(InspectorFrontendClient::DOCKED_TO_BOTTOM);
189 }
190
191 void WebInspector::attachedRight()
192 {
193     if (m_frontendClient)
194         m_frontendClient->setAttachedWindow(InspectorFrontendClient::DOCKED_TO_RIGHT);
195 }
196
197 void WebInspector::detached()
198 {
199     if (m_frontendClient)
200         m_frontendClient->setAttachedWindow(InspectorFrontendClient::UNDOCKED);
201 }
202
203 void WebInspector::evaluateScriptForTest(long callID, const String& script)
204 {
205     m_page->corePage()->inspectorController().evaluateForTestInFrontend(callID, script);
206 }
207
208 void WebInspector::showConsole()
209 {
210     m_page->corePage()->inspectorController().show();
211     if (m_frontendClient)
212         m_frontendClient->showConsole();
213 }
214
215 void WebInspector::showResources()
216 {
217     m_page->corePage()->inspectorController().show();
218     if (m_frontendClient)
219         m_frontendClient->showResources();
220 }
221
222 void WebInspector::showMainResourceForFrame(uint64_t frameID)
223 {
224     WebFrame* frame = WebProcess::shared().webFrame(frameID);
225     if (!frame)
226         return;
227
228     m_page->corePage()->inspectorController().show();
229     if (m_frontendClient)
230         m_frontendClient->showMainResourceForFrame(frame->coreFrame());
231 }
232
233 void WebInspector::startJavaScriptDebugging()
234 {
235 #if ENABLE(JAVASCRIPT_DEBUGGER)
236     m_page->corePage()->inspectorController().show();
237     if (m_frontendClient)
238         m_frontendClient->setDebuggingEnabled(true);
239 #endif
240 }
241
242 void WebInspector::stopJavaScriptDebugging()
243 {
244 #if ENABLE(JAVASCRIPT_DEBUGGER)
245     m_page->corePage()->inspectorController().show();
246     if (m_frontendClient)
247         m_frontendClient->setDebuggingEnabled(false);
248 #endif
249 }
250
251 void WebInspector::setJavaScriptProfilingEnabled(bool enabled)
252 {
253 #if ENABLE(JAVASCRIPT_DEBUGGER)
254     m_page->corePage()->inspectorController().show();
255     if (!m_frontendClient)
256         return;
257
258     m_page->corePage()->inspectorController().setProfilerEnabled(enabled);
259 #endif
260 }
261
262 void WebInspector::startJavaScriptProfiling()
263 {
264 #if ENABLE(JAVASCRIPT_DEBUGGER)
265     m_page->corePage()->inspectorController().show();
266     if (m_frontendClient)
267         m_frontendClient->startProfilingJavaScript();
268 #endif
269 }
270
271 void WebInspector::stopJavaScriptProfiling()
272 {
273 #if ENABLE(JAVASCRIPT_DEBUGGER)
274     m_page->corePage()->inspectorController().show();
275     if (m_frontendClient)
276         m_frontendClient->stopProfilingJavaScript();
277 #endif
278 }
279
280 void WebInspector::startPageProfiling()
281 {
282     m_page->corePage()->inspectorController().show();
283     if (m_frontendClient)
284         m_frontendClient->setTimelineProfilingEnabled(true);
285 }
286
287 void WebInspector::stopPageProfiling()
288 {
289     m_page->corePage()->inspectorController().show();
290     if (m_frontendClient)
291         m_frontendClient->setTimelineProfilingEnabled(false);
292 }
293
294 void WebInspector::updateDockingAvailability()
295 {
296     if (!m_frontendClient)
297         return;
298
299     bool canAttachWindow = m_frontendClient->canAttachWindow();
300     WebProcess::shared().parentProcessConnection()->send(Messages::WebInspectorProxy::AttachAvailabilityChanged(canAttachWindow), m_page->pageID());
301     m_frontendClient->setDockingUnavailable(!canAttachWindow);
302 }
303
304 #if ENABLE(INSPECTOR_SERVER)
305 void WebInspector::sendMessageToRemoteFrontend(const String& message)
306 {
307     ASSERT(m_remoteFrontendConnected);
308     WebProcess::shared().parentProcessConnection()->send(Messages::WebInspectorProxy::SendMessageToRemoteFrontend(message), m_page->pageID());
309 }
310
311 void WebInspector::dispatchMessageFromRemoteFrontend(const String& message)
312 {
313     m_page->corePage()->inspectorController().dispatchMessageFromFrontend(message);
314 }
315
316 void WebInspector::remoteFrontendConnected()
317 {
318     ASSERT(!m_remoteFrontendConnected);
319     // Switching between in-process and remote inspectors isn't supported yet.
320     ASSERT(!m_inspectorPage);
321     
322     m_page->corePage()->inspectorController().connectFrontend(m_frontendChannel);
323     m_remoteFrontendConnected = true;
324 }
325
326 void WebInspector::remoteFrontendDisconnected()
327 {
328     ASSERT(m_remoteFrontendConnected);
329     m_page->corePage()->inspectorController().disconnectFrontend();
330     m_remoteFrontendConnected = false;
331 }
332 #endif
333
334 } // namespace WebKit
335
336 #endif // ENABLE(INSPECTOR)