Part 2 of removing PlatformString.h, remove PlatformString.h
[WebKit-https.git] / Source / WebKit / gtk / WebCoreSupport / InspectorClientGtk.cpp
1 /*
2  * Copyright (C) 2008, 2012 Gustavo Noronha Silva
3  * Copyright (C) 2010 Collabora Ltd.
4  *
5  *  This library is free software; you can redistribute it and/or
6  *  modify it under the terms of the GNU Lesser General Public
7  *  License as published by the Free Software Foundation; either
8  *  version 2 of the License, or (at your option) any later version.
9  *
10  *  This library is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  *  Lesser General Public License for more details.
14  *
15  *  You should have received a copy of the GNU Lesser General Public
16  *  License along with this library; if not, write to the Free Software
17  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
18  */
19
20 #include "config.h"
21 #include "InspectorClientGtk.h"
22
23 #include "FileSystem.h"
24 #include "Frame.h"
25 #include "InspectorController.h"
26 #include "NotImplemented.h"
27 #include "Page.h"
28 #include "webkitversion.h"
29 #include "webkitwebinspector.h"
30 #include "webkitwebinspectorprivate.h"
31 #include "webkitwebview.h"
32 #include "webkitwebviewprivate.h"
33 #include <wtf/text/CString.h>
34 #include <wtf/text/WTFString.h>
35
36 using namespace WebCore;
37
38 namespace WebKit {
39
40 static void notifyWebViewDestroyed(WebKitWebView* webView, InspectorFrontendClient* inspectorFrontendClient)
41 {
42     inspectorFrontendClient->destroyInspectorWindow(true);
43 }
44
45 namespace {
46
47 class InspectorFrontendSettingsGtk : public InspectorFrontendClientLocal::Settings {
48 public:
49     virtual ~InspectorFrontendSettingsGtk() { }
50
51 private:
52     virtual String getProperty(const String& name)
53     {
54         notImplemented();
55         return String();
56     }
57
58     virtual void setProperty(const String& name, const String& value)
59     {
60         notImplemented();
61     }
62 };
63
64 } // namespace
65
66 InspectorClient::InspectorClient(WebKitWebView* webView)
67     : m_inspectedWebView(webView)
68     , m_frontendPage(0)
69     , m_frontendClient(0)
70 {}
71
72 InspectorClient::~InspectorClient()
73 {
74     if (m_frontendClient) {
75         m_frontendClient->disconnectInspectorClient();
76         m_frontendClient = 0;
77     }
78 }
79
80 void InspectorClient::inspectorDestroyed()
81 {
82     closeInspectorFrontend();
83     delete this;
84 }
85
86 InspectorFrontendChannel* InspectorClient::openInspectorFrontend(InspectorController* controller)
87 {
88     // This g_object_get will ref the inspector. We're not doing an
89     // unref if this method succeeds because the inspector object must
90     // be alive even after the inspected WebView is destroyed - the
91     // close-window and destroy signals still need to be
92     // emitted.
93     WebKitWebInspector* webInspector = 0;
94     g_object_get(m_inspectedWebView, "web-inspector", &webInspector, NULL);
95     ASSERT(webInspector);
96
97     WebKitWebView* inspectorWebView = 0;
98     g_signal_emit_by_name(webInspector, "inspect-web-view", m_inspectedWebView, &inspectorWebView);
99
100     if (!inspectorWebView) {
101         g_object_unref(webInspector);
102         return 0;
103     }
104
105     webkit_web_inspector_set_web_view(webInspector, inspectorWebView);
106  
107     GOwnPtr<gchar> inspectorPath(g_build_filename(inspectorFilesPath(), "inspector.html", NULL));
108     GOwnPtr<gchar> inspectorURI(g_filename_to_uri(inspectorPath.get(), 0, 0));
109     webkit_web_view_load_uri(inspectorWebView, inspectorURI.get());
110
111     gtk_widget_show(GTK_WIDGET(inspectorWebView));
112
113     m_frontendPage = core(inspectorWebView);
114     OwnPtr<InspectorFrontendClient> frontendClient = adoptPtr(new InspectorFrontendClient(m_inspectedWebView, inspectorWebView, webInspector, m_frontendPage, this));
115     m_frontendClient = frontendClient.get();
116     m_frontendPage->inspectorController()->setInspectorFrontendClient(frontendClient.release());
117
118     // The inspector must be in it's own PageGroup to avoid deadlock while debugging.
119     m_frontendPage->setGroupName("");
120     
121     return this;
122 }
123
124 void InspectorClient::closeInspectorFrontend()
125 {
126     if (m_frontendClient)
127         m_frontendClient->destroyInspectorWindow(false);
128 }
129
130 void InspectorClient::bringFrontendToFront()
131 {
132     m_frontendClient->bringToFront();
133 }
134
135 void InspectorClient::releaseFrontendPage()
136 {
137     m_frontendPage = 0;
138     m_frontendClient = 0;
139 }
140
141 void InspectorClient::highlight()
142 {
143     hideHighlight();
144 }
145
146 void InspectorClient::hideHighlight()
147 {
148     // FIXME: we should be able to only invalidate the actual rects of
149     // the new and old nodes. We need to track the nodes, and take the
150     // actual highlight size into account when calculating the damage
151     // rect.
152     gtk_widget_queue_draw(GTK_WIDGET(m_inspectedWebView));
153 }
154
155 bool InspectorClient::sendMessageToFrontend(const String& message)
156 {
157     return doDispatchMessageOnFrontendPage(m_frontendPage, message);
158 }
159
160 const char* InspectorClient::inspectorFilesPath()
161 {
162     if (m_inspectorFilesPath)
163         m_inspectorFilesPath.get();
164
165     const char* environmentPath = getenv("WEBKIT_INSPECTOR_PATH");
166     if (environmentPath && g_file_test(environmentPath, G_FILE_TEST_IS_DIR))
167         m_inspectorFilesPath.set(g_strdup(environmentPath));
168     else
169         m_inspectorFilesPath.set(g_build_filename(sharedResourcesPath().data(), "webinspector", NULL));
170
171     return m_inspectorFilesPath.get();
172 }
173
174 InspectorFrontendClient::InspectorFrontendClient(WebKitWebView* inspectedWebView, WebKitWebView* inspectorWebView, WebKitWebInspector* webInspector, Page* inspectorPage, InspectorClient* inspectorClient)
175     : InspectorFrontendClientLocal(core(inspectedWebView)->inspectorController(), inspectorPage, adoptPtr(new InspectorFrontendSettingsGtk()))
176     , m_inspectorWebView(inspectorWebView)
177     , m_inspectedWebView(inspectedWebView)
178     , m_webInspector(webInspector)
179     , m_inspectorClient(inspectorClient)
180 {
181     g_signal_connect(m_inspectorWebView, "destroy",
182                      G_CALLBACK(notifyWebViewDestroyed), (gpointer)this);
183 }
184
185 InspectorFrontendClient::~InspectorFrontendClient()
186 {
187     if (m_inspectorClient) {
188         m_inspectorClient->releaseFrontendPage();
189         m_inspectorClient = 0;
190     }
191
192     ASSERT(!m_webInspector);
193 }
194
195 void InspectorFrontendClient::destroyInspectorWindow(bool notifyInspectorController)
196 {
197     if (!m_webInspector)
198         return;
199
200     GRefPtr<WebKitWebInspector> webInspector = adoptGRef(m_webInspector.leakRef());
201
202     if (m_inspectorWebView) {
203         g_signal_handlers_disconnect_by_func(m_inspectorWebView, reinterpret_cast<gpointer>(notifyWebViewDestroyed), this);
204         m_inspectorWebView = 0;
205     }
206
207     if (notifyInspectorController)
208         core(m_inspectedWebView)->inspectorController()->disconnectFrontend();
209
210     if (m_inspectorClient)
211         m_inspectorClient->releaseFrontendPage();
212
213     gboolean handled = FALSE;
214     g_signal_emit_by_name(webInspector.get(), "close-window", &handled);
215     ASSERT(handled);
216
217     // Please do not use member variables here because InspectorFrontendClient object pointed by 'this'
218     // has been implicitly deleted by "close-window" function.
219 }
220
221 String InspectorFrontendClient::localizedStringsURL()
222 {
223     GOwnPtr<gchar> stringsPath(g_build_filename(m_inspectorClient->inspectorFilesPath(), "localizedStrings.js", NULL));
224     GOwnPtr<gchar> stringsURI(g_filename_to_uri(stringsPath.get(), 0, 0));
225
226     // FIXME: support l10n of localizedStrings.js
227     return String::fromUTF8(stringsURI.get());
228 }
229
230 String InspectorFrontendClient::hiddenPanels()
231 {
232     notImplemented();
233     return String();
234 }
235
236 void InspectorFrontendClient::bringToFront()
237 {
238     if (!m_inspectorWebView)
239         return;
240
241     gboolean handled = FALSE;
242     g_signal_emit_by_name(m_webInspector.get(), "show-window", &handled);
243 }
244
245 void InspectorFrontendClient::closeWindow()
246 {
247     destroyInspectorWindow(true);
248 }
249
250 void InspectorFrontendClient::attachWindow()
251 {
252     if (!m_inspectorWebView)
253         return;
254
255     gboolean handled = FALSE;
256     g_signal_emit_by_name(m_webInspector.get(), "attach-window", &handled);
257 }
258
259 void InspectorFrontendClient::detachWindow()
260 {
261     if (!m_inspectorWebView)
262         return;
263
264     gboolean handled = FALSE;
265     g_signal_emit_by_name(m_webInspector.get(), "detach-window", &handled);
266 }
267
268 void InspectorFrontendClient::setAttachedWindowHeight(unsigned height)
269 {
270     notImplemented();
271 }
272
273 void InspectorFrontendClient::inspectedURLChanged(const String& newURL)
274 {
275     if (!m_inspectorWebView)
276         return;
277
278     webkit_web_inspector_set_inspected_uri(m_webInspector.get(), newURL.utf8().data());
279 }
280
281 }
282