Modernize WebCore/inspector with nullptr
[WebKit-https.git] / Source / WebCore / inspector / InspectorFrontendHost.cpp
1 /*
2  * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
3  * Copyright (C) 2008 Matt Lilek <webkit@mattlilek.com>
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1.  Redistributions of source code must retain the above copyright
10  *     notice, this list of conditions and the following disclaimer.
11  * 2.  Redistributions in binary form must reproduce the above copyright
12  *     notice, this list of conditions and the following disclaimer in the
13  *     documentation and/or other materials provided with the distribution.
14  * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
15  *     its contributors may be used to endorse or promote products derived
16  *     from this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
19  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
22  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29
30 #include "config.h"
31
32 #if ENABLE(INSPECTOR)
33
34 #include "InspectorFrontendHost.h"
35
36 #include "ContextMenu.h"
37 #include "ContextMenuItem.h"
38 #include "ContextMenuController.h"
39 #include "ContextMenuProvider.h"
40 #include "DOMWrapperWorld.h"
41 #include "Element.h"
42 #include "Event.h"
43 #include "FrameLoader.h"
44 #include "HitTestResult.h"
45 #include "HTMLFrameOwnerElement.h"
46 #include "InspectorFrontendClient.h"
47 #include "JSMainThreadExecState.h"
48 #include "MainFrame.h"
49 #include "MouseEvent.h"
50 #include "Page.h"
51 #include "Pasteboard.h"
52 #include "ResourceError.h"
53 #include "ResourceRequest.h"
54 #include "ResourceResponse.h"
55 #include "ScriptGlobalObject.h"
56 #include "ScriptState.h"
57 #include "Sound.h"
58 #include "UserGestureIndicator.h"
59 #include <bindings/ScriptFunctionCall.h>
60 #include <wtf/StdLibExtras.h>
61
62 using namespace Inspector;
63
64 namespace WebCore {
65
66 #if ENABLE(CONTEXT_MENUS)
67 class FrontendMenuProvider : public ContextMenuProvider {
68 public:
69     static PassRefPtr<FrontendMenuProvider> create(InspectorFrontendHost* frontendHost, Deprecated::ScriptObject frontendApiObject, const Vector<ContextMenuItem>& items)
70     {
71         return adoptRef(new FrontendMenuProvider(frontendHost, frontendApiObject, items));
72     }
73     
74     void disconnect()
75     {
76         m_frontendApiObject = Deprecated::ScriptObject();
77         m_frontendHost = nullptr;
78     }
79     
80 private:
81     FrontendMenuProvider(InspectorFrontendHost* frontendHost, Deprecated::ScriptObject frontendApiObject, const Vector<ContextMenuItem>& items)
82         : m_frontendHost(frontendHost)
83         , m_frontendApiObject(frontendApiObject)
84         , m_items(items)
85     {
86     }
87
88     virtual ~FrontendMenuProvider()
89     {
90         contextMenuCleared();
91     }
92     
93     virtual void populateContextMenu(ContextMenu* menu) override
94     {
95         for (size_t i = 0; i < m_items.size(); ++i)
96             menu->appendItem(m_items[i]);
97     }
98     
99     virtual void contextMenuItemSelected(ContextMenuItem* item) override
100     {
101         if (m_frontendHost) {
102             UserGestureIndicator gestureIndicator(DefinitelyProcessingUserGesture);
103             int itemNumber = item->action() - ContextMenuItemBaseCustomTag;
104
105             Deprecated::ScriptFunctionCall function(m_frontendApiObject, "contextMenuItemSelected", WebCore::functionCallHandlerFromAnyThread);
106             function.appendArgument(itemNumber);
107             function.call();
108         }
109     }
110     
111     virtual void contextMenuCleared() override
112     {
113         if (m_frontendHost) {
114             Deprecated::ScriptFunctionCall function(m_frontendApiObject, "contextMenuCleared", WebCore::functionCallHandlerFromAnyThread);
115             function.call();
116
117             m_frontendHost->m_menuProvider = nullptr;
118         }
119         m_items.clear();
120     }
121
122     InspectorFrontendHost* m_frontendHost;
123     Deprecated::ScriptObject m_frontendApiObject;
124     Vector<ContextMenuItem> m_items;
125 };
126 #endif
127
128 InspectorFrontendHost::InspectorFrontendHost(InspectorFrontendClient* client, Page* frontendPage)
129     : m_client(client)
130     , m_frontendPage(frontendPage)
131 #if ENABLE(CONTEXT_MENUS)
132     , m_menuProvider(nullptr)
133 #endif
134 {
135 }
136
137 InspectorFrontendHost::~InspectorFrontendHost()
138 {
139     ASSERT(!m_client);
140 }
141
142 void InspectorFrontendHost::disconnectClient()
143 {
144     m_client = nullptr;
145 #if ENABLE(CONTEXT_MENUS)
146     if (m_menuProvider)
147         m_menuProvider->disconnect();
148 #endif
149     m_frontendPage = nullptr;
150 }
151
152 void InspectorFrontendHost::loaded()
153 {
154     if (m_client)
155         m_client->frontendLoaded();
156 }
157
158 void InspectorFrontendHost::requestSetDockSide(const String& side)
159 {
160     if (!m_client)
161         return;
162     if (side == "undocked")
163         m_client->requestSetDockSide(InspectorFrontendClient::UNDOCKED);
164     else if (side == "right")
165         m_client->requestSetDockSide(InspectorFrontendClient::DOCKED_TO_RIGHT);
166     else if (side == "bottom")
167         m_client->requestSetDockSide(InspectorFrontendClient::DOCKED_TO_BOTTOM);
168 }
169
170 void InspectorFrontendHost::closeWindow()
171 {
172     if (m_client) {
173         m_client->closeWindow();
174         disconnectClient(); // Disconnect from client.
175     }
176 }
177
178 void InspectorFrontendHost::bringToFront()
179 {
180     if (m_client)
181         m_client->bringToFront();
182 }
183
184 void InspectorFrontendHost::setZoomFactor(float zoom)
185 {
186     m_frontendPage->mainFrame().setPageAndTextZoomFactors(zoom, 1);
187 }
188
189 void InspectorFrontendHost::inspectedURLChanged(const String& newURL)
190 {
191     if (m_client)
192         m_client->inspectedURLChanged(newURL);
193 }
194
195 void InspectorFrontendHost::setAttachedWindowHeight(unsigned height)
196 {
197     if (m_client)
198         m_client->changeAttachedWindowHeight(height);
199 }
200
201 void InspectorFrontendHost::setAttachedWindowWidth(unsigned width)
202 {
203     if (m_client)
204         m_client->changeAttachedWindowWidth(width);
205 }
206
207 void InspectorFrontendHost::setToolbarHeight(unsigned height)
208 {
209     if (m_client)
210         m_client->setToolbarHeight(height);
211 }
212
213 void InspectorFrontendHost::moveWindowBy(float x, float y) const
214 {
215     if (m_client)
216         m_client->moveWindowBy(x, y);
217 }
218
219 String InspectorFrontendHost::localizedStringsURL()
220 {
221     return m_client ? m_client->localizedStringsURL() : "";
222 }
223
224 String InspectorFrontendHost::debuggableType()
225 {
226     return ASCIILiteral("web");
227 }
228
229 void InspectorFrontendHost::copyText(const String& text)
230 {
231     Pasteboard::createForCopyAndPaste()->writePlainText(text, Pasteboard::CannotSmartReplace);
232 }
233
234 void InspectorFrontendHost::openInNewTab(const String& url)
235 {
236     if (m_client)
237         m_client->openInNewTab(url);
238 }
239
240 bool InspectorFrontendHost::canSave()
241 {
242     if (m_client)
243         return m_client->canSave();
244     return false;
245 }
246
247 void InspectorFrontendHost::save(const String& url, const String& content, bool base64Encoded, bool forceSaveAs)
248 {
249     if (m_client)
250         m_client->save(url, content, base64Encoded, forceSaveAs);
251 }
252
253 void InspectorFrontendHost::append(const String& url, const String& content)
254 {
255     if (m_client)
256         m_client->append(url, content);
257 }
258
259 void InspectorFrontendHost::close(const String&)
260 {
261 }
262
263 void InspectorFrontendHost::sendMessageToBackend(const String& message)
264 {
265     if (m_client)
266         m_client->sendMessageToBackend(message);
267 }
268
269 #if ENABLE(CONTEXT_MENUS)
270 void InspectorFrontendHost::showContextMenu(Event* event, const Vector<ContextMenuItem>& items)
271 {
272     if (!event)
273         return;
274
275     ASSERT(m_frontendPage);
276     JSC::ExecState* frontendExecState = execStateFromPage(debuggerWorld(), m_frontendPage);
277     Deprecated::ScriptObject frontendApiObject;
278     if (!ScriptGlobalObject::get(frontendExecState, "InspectorFrontendAPI", frontendApiObject)) {
279         ASSERT_NOT_REACHED();
280         return;
281     }
282     RefPtr<FrontendMenuProvider> menuProvider = FrontendMenuProvider::create(this, frontendApiObject, items);
283     m_frontendPage->contextMenuController().showContextMenu(event, menuProvider);
284     m_menuProvider = menuProvider.get();
285 }
286 #endif
287
288 void InspectorFrontendHost::dispatchEventAsContextMenuEvent(Event* event)
289 {
290 #if ENABLE(CONTEXT_MENUS) && USE(ACCESSIBILITY_CONTEXT_MENUS)
291     if (!event || !event->isMouseEvent())
292         return;
293
294     Frame* frame = event->target()->toNode()->document().frame();
295     MouseEvent* mouseEvent = toMouseEvent(event);
296     IntPoint mousePoint = IntPoint(mouseEvent->clientX(), mouseEvent->clientY());
297
298     m_frontendPage->contextMenuController().showContextMenuAt(frame, mousePoint);
299 #else
300     UNUSED_PARAM(event);
301 #endif
302 }
303
304 String InspectorFrontendHost::loadResourceSynchronously(const String& url)
305 {
306     ResourceRequest request(url);
307     request.setHTTPMethod("GET");
308
309     Vector<char> data;
310     ResourceError error;
311     ResourceResponse response;
312     m_frontendPage->mainFrame().loader().loadResourceSynchronously(request, DoNotAllowStoredCredentials, DoNotAskClientForCrossOriginCredentials, error, response, data);
313     return String::fromUTF8(data.data(), data.size());
314 }
315
316 bool InspectorFrontendHost::isUnderTest()
317 {
318     return m_client && m_client->isUnderTest();
319 }
320
321 void InspectorFrontendHost::beep()
322 {
323     systemBeep();
324 }
325
326 bool InspectorFrontendHost::canSaveAs()
327 {
328     return false;
329 }
330
331 bool InspectorFrontendHost::canInspectWorkers()
332 {
333     return false;
334 }
335
336 } // namespace WebCore
337
338 #endif // ENABLE(INSPECTOR)