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