a01edb370ce271175a270d97c1bc5d995687129e
[WebKit-https.git] / Source / WebKit / WebProcess / WebPage / WebInspectorUI.cpp
1 /*
2  * Copyright (C) 2014, 2016 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 "WebInspectorUI.h"
28
29 #include "WebInspectorMessages.h"
30 #include "WebInspectorProxyMessages.h"
31 #include "WebPage.h"
32 #include "WebProcess.h"
33 #include <WebCore/Chrome.h>
34 #include <WebCore/DOMWrapperWorld.h>
35 #include <WebCore/InspectorController.h>
36 #include <WebCore/NotImplemented.h>
37 #include <WebCore/ScriptGlobalObject.h>
38 #include <WebCore/ScriptState.h>
39
40 using namespace WebCore;
41
42 namespace WebKit {
43
44 Ref<WebInspectorUI> WebInspectorUI::create(WebPage& page)
45 {
46     return adoptRef(*new WebInspectorUI(page));
47 }
48
49 WebInspectorUI::WebInspectorUI(WebPage& page)
50     : m_page(page)
51     , m_frontendAPIDispatcher(page)
52 {
53 }
54
55 void WebInspectorUI::establishConnection(IPC::Attachment encodedConnectionIdentifier, uint64_t inspectedPageIdentifier, bool underTest, unsigned inspectionLevel)
56 {
57 #if USE(UNIX_DOMAIN_SOCKETS)
58     IPC::Connection::Identifier connectionIdentifier(encodedConnectionIdentifier.releaseFileDescriptor());
59 #elif OS(DARWIN)
60     IPC::Connection::Identifier connectionIdentifier(encodedConnectionIdentifier.port());
61 #else
62     notImplemented();
63     return;
64 #endif
65
66     if (IPC::Connection::identifierIsNull(connectionIdentifier))
67         return;
68
69     m_inspectedPageIdentifier = inspectedPageIdentifier;
70     m_frontendAPIDispatcher.reset();
71     m_underTest = underTest;
72     m_inspectionLevel = inspectionLevel;
73
74     m_frontendController = &m_page.corePage()->inspectorController();
75     m_frontendController->setInspectorFrontendClient(this);
76
77     m_backendConnection = IPC::Connection::createClientConnection(connectionIdentifier, *this);
78     m_backendConnection->open();
79 }
80
81 void WebInspectorUI::windowObjectCleared()
82 {
83     if (m_frontendHost)
84         m_frontendHost->disconnectClient();
85
86     m_frontendHost = InspectorFrontendHost::create(this, m_page.corePage());
87     ScriptGlobalObject::set(*execStateFromPage(mainThreadNormalWorld(), m_page.corePage()), ASCIILiteral("InspectorFrontendHost"), *m_frontendHost);
88 }
89
90 void WebInspectorUI::frontendLoaded()
91 {
92     m_frontendAPIDispatcher.frontendLoaded();
93
94     // Tell the new frontend about the current dock state. If the window object
95     // cleared due to a reload, the dock state won't be resent from UIProcess.
96     setDockingUnavailable(m_dockingUnavailable);
97     setDockSide(m_dockSide);
98     setIsVisible(m_isVisible);
99
100     WebProcess::singleton().parentProcessConnection()->send(Messages::WebInspectorProxy::FrontendLoaded(), m_inspectedPageIdentifier);
101
102     bringToFront();
103 }
104
105 void WebInspectorUI::startWindowDrag()
106 {
107     WebProcess::singleton().parentProcessConnection()->send(Messages::WebInspectorProxy::StartWindowDrag(), m_inspectedPageIdentifier);
108 }
109
110 void WebInspectorUI::moveWindowBy(float x, float y)
111 {
112     FloatRect frameRect = m_page.corePage()->chrome().windowRect();
113     frameRect.move(x, y);
114     m_page.corePage()->chrome().setWindowRect(frameRect);
115 }
116
117 void WebInspectorUI::bringToFront()
118 {
119     WebProcess::singleton().parentProcessConnection()->send(Messages::WebInspectorProxy::BringToFront(), m_inspectedPageIdentifier);
120 }
121
122 void WebInspectorUI::closeWindow()
123 {
124     WebProcess::singleton().parentProcessConnection()->send(Messages::WebInspectorProxy::DidClose(), m_inspectedPageIdentifier);
125
126     if (m_backendConnection)
127         m_backendConnection->invalidate();
128     m_backendConnection = nullptr;
129
130     if (m_frontendController)
131         m_frontendController->setInspectorFrontendClient(nullptr);
132     m_frontendController = nullptr;
133
134     if (m_frontendHost)
135         m_frontendHost->disconnectClient();
136
137     m_inspectedPageIdentifier = 0;
138     m_underTest = false;
139 }
140
141 WebCore::UserInterfaceLayoutDirection WebInspectorUI::userInterfaceLayoutDirection() const
142 {
143     return m_page.corePage()->userInterfaceLayoutDirection();
144 }
145
146 void WebInspectorUI::requestSetDockSide(DockSide side)
147 {
148     auto& webProcess = WebProcess::singleton();
149     switch (side) {
150     case DockSide::Undocked:
151         webProcess.parentProcessConnection()->send(Messages::WebInspectorProxy::Detach(), m_inspectedPageIdentifier);
152         break;
153     case DockSide::Right:
154         webProcess.parentProcessConnection()->send(Messages::WebInspectorProxy::AttachRight(), m_inspectedPageIdentifier);
155         break;
156     case DockSide::Left:
157         webProcess.parentProcessConnection()->send(Messages::WebInspectorProxy::AttachLeft(), m_inspectedPageIdentifier);
158         break;
159     case DockSide::Bottom:
160         webProcess.parentProcessConnection()->send(Messages::WebInspectorProxy::AttachBottom(), m_inspectedPageIdentifier);
161         break;
162     }
163 }
164
165 void WebInspectorUI::setDockSide(DockSide side)
166 {
167     const char* sideString;
168
169     switch (side) {
170     case DockSide::Undocked:
171         sideString = "undocked";
172         break;
173
174     case DockSide::Right:
175         sideString = "right";
176         break;
177
178     case DockSide::Left:
179         sideString = "left";
180         break;
181
182     case DockSide::Bottom:
183         sideString = "bottom";
184         break;
185     }
186
187     m_dockSide = side;
188
189     m_frontendAPIDispatcher.dispatchCommand(ASCIILiteral("setDockSide"), String(ASCIILiteral(sideString)));
190 }
191
192 void WebInspectorUI::setDockingUnavailable(bool unavailable)
193 {
194     m_dockingUnavailable = unavailable;
195
196     m_frontendAPIDispatcher.dispatchCommand(ASCIILiteral("setDockingUnavailable"), unavailable);
197 }
198
199 void WebInspectorUI::setIsVisible(bool visible)
200 {
201     m_isVisible = visible;
202
203     m_frontendAPIDispatcher.dispatchCommand(ASCIILiteral("setIsVisible"), visible);
204 }
205
206 void WebInspectorUI::changeAttachedWindowHeight(unsigned height)
207 {
208     WebProcess::singleton().parentProcessConnection()->send(Messages::WebInspectorProxy::SetAttachedWindowHeight(height), m_inspectedPageIdentifier);
209 }
210
211 void WebInspectorUI::changeAttachedWindowWidth(unsigned width)
212 {
213     WebProcess::singleton().parentProcessConnection()->send(Messages::WebInspectorProxy::SetAttachedWindowWidth(width), m_inspectedPageIdentifier);
214 }
215
216 void WebInspectorUI::openInNewTab(const String& url)
217 {
218     if (m_backendConnection)
219         m_backendConnection->send(Messages::WebInspector::OpenInNewTab(url), 0);
220 }
221
222 void WebInspectorUI::save(const WTF::String& filename, const WTF::String& content, bool base64Encoded, bool forceSaveAs)
223 {
224     WebProcess::singleton().parentProcessConnection()->send(Messages::WebInspectorProxy::Save(filename, content, base64Encoded, forceSaveAs), m_inspectedPageIdentifier);
225 }
226
227 void WebInspectorUI::append(const WTF::String& filename, const WTF::String& content)
228 {
229     WebProcess::singleton().parentProcessConnection()->send(Messages::WebInspectorProxy::Append(filename, content), m_inspectedPageIdentifier);
230 }
231
232 void WebInspectorUI::inspectedURLChanged(const String& urlString)
233 {
234     WebProcess::singleton().parentProcessConnection()->send(Messages::WebInspectorProxy::InspectedURLChanged(urlString), m_inspectedPageIdentifier);
235 }
236
237 void WebInspectorUI::showConsole()
238 {
239     m_frontendAPIDispatcher.dispatchCommand(ASCIILiteral("showConsole"));
240 }
241
242 void WebInspectorUI::showResources()
243 {
244     m_frontendAPIDispatcher.dispatchCommand(ASCIILiteral("showResources"));
245 }
246
247 void WebInspectorUI::showTimelines()
248 {
249     m_frontendAPIDispatcher.dispatchCommand(ASCIILiteral("showTimelines"));
250 }
251
252 void WebInspectorUI::showMainResourceForFrame(const String& frameIdentifier)
253 {
254     m_frontendAPIDispatcher.dispatchCommand(ASCIILiteral("showMainResourceForFrame"), frameIdentifier);
255 }
256
257 void WebInspectorUI::startPageProfiling()
258 {
259     m_frontendAPIDispatcher.dispatchCommand(ASCIILiteral("setTimelineProfilingEnabled"), true);
260 }
261
262 void WebInspectorUI::stopPageProfiling()
263 {
264     m_frontendAPIDispatcher.dispatchCommand(ASCIILiteral("setTimelineProfilingEnabled"), false);
265 }
266
267 void WebInspectorUI::startElementSelection()
268 {
269     m_frontendAPIDispatcher.dispatchCommand(ASCIILiteral("setElementSelectionEnabled"), true);
270 }
271
272 void WebInspectorUI::stopElementSelection()
273 {
274     m_frontendAPIDispatcher.dispatchCommand(ASCIILiteral("setElementSelectionEnabled"), false);
275 }
276
277 void WebInspectorUI::didSave(const String& url)
278 {
279     m_frontendAPIDispatcher.dispatchCommand(ASCIILiteral("savedURL"), url);
280 }
281
282 void WebInspectorUI::didAppend(const String& url)
283 {
284     m_frontendAPIDispatcher.dispatchCommand(ASCIILiteral("appendedToURL"), url);
285 }
286
287 void WebInspectorUI::sendMessageToFrontend(const String& message)
288 {
289     m_frontendAPIDispatcher.dispatchMessageAsync(message);
290 }
291
292 void WebInspectorUI::pagePaused()
293 {
294     m_frontendAPIDispatcher.suspend();
295 }
296
297 void WebInspectorUI::pageUnpaused()
298 {
299     m_frontendAPIDispatcher.unsuspend();
300 }
301
302 void WebInspectorUI::sendMessageToBackend(const String& message)
303 {
304     if (m_backendConnection)
305         m_backendConnection->send(Messages::WebInspector::SendMessageToBackend(message), 0);
306 }
307
308 } // namespace WebKit