6b0ae5f1180287c3aaa2b280e8df808e0990767a
[WebKit-https.git] / WebKitTools / Drosera / win / ServerConnection.cpp
1 /*
2  * Copyright (C) 2007 Apple Inc.  All rights reserved.
3  * Copyright (C) 2006, 2007 Vladimir Olexa (vladimir.olexa@gmail.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 #include "ServerConnection.h"
32
33 #include "DebuggerDocument.h"
34
35 #include <JavaScriptCore/JSContextRef.h>
36 #include <JavaScriptCore/JSRetainPtr.h>
37 #include <JavaScriptCore/JSStringRefBSTR.h>
38 #include <JavaScriptCore/RetainPtr.h>
39 #include <WebKit/WebKit.h>
40
41 ServerConnection::ServerConnection()
42     : m_globalContext(0)
43 {
44     HRESULT serverCreated = CoCreateInstance(CLSID_WebScriptDebugServer, 0, CLSCTX_LOCAL_SERVER, IID_IWebScriptDebugServer, (void**)&m_server);
45     if (!FAILED(serverCreated))
46         m_server->addListener(this);
47 }
48
49 ServerConnection::~ServerConnection()
50 {
51     if (m_server)
52         m_server->removeListener(this);
53
54     if (m_globalContext)
55         JSGlobalContextRelease(m_globalContext);
56 }
57
58 void ServerConnection::setGlobalContext(JSGlobalContextRef globalContextRef)
59 {
60     m_globalContext = JSGlobalContextRetain(globalContextRef);
61 }
62
63 void ServerConnection::pause()
64 {
65     if (m_server)
66         m_server->pause();
67 }
68
69 void ServerConnection::resume()
70 {
71     if (m_server)
72         m_server->resume();
73 }
74
75 void ServerConnection::stepInto()
76 {
77     if (m_server)
78         m_server->step();
79 }
80
81 // Connection Handling
82
83 void ServerConnection::applicationTerminating()
84 {
85     if (m_server)
86         m_server->removeListener(this);
87 }
88
89 void ServerConnection::serverConnectionDidDie()
90 {
91     if (m_server)
92         m_server->removeListener(this);
93 }
94
95 // Stack & Variables
96
97 IWebScriptCallFrame* ServerConnection::currentFrame() const
98 {
99     return m_currentFrame;
100 }
101
102 IWebScriptCallFrame* ServerConnection::getCallerFrame(int callFrame) const
103 {
104     COMPtr<IWebScriptCallFrame> cframe = currentFrame();
105     COMPtr<IWebScriptCallFrame> callerFrame;
106     for (int count = 0; count < callFrame; count++) {
107         if (FAILED(cframe->caller(&callerFrame)))
108             return 0;
109
110         cframe = callerFrame;
111     }
112
113     return cframe.get();
114 }
115
116
117 // IUnknown --------------------------------------------------
118 HRESULT STDMETHODCALLTYPE ServerConnection::QueryInterface(REFIID riid, void** ppvObject)
119 {
120     *ppvObject = 0;
121     if (IsEqualGUID(riid, IID_IUnknown))
122         *ppvObject = this;
123     else if (IsEqualGUID(riid, IID_IWebScriptDebugListener))
124         *ppvObject = static_cast<IWebScriptDebugListener*>(this);
125     else
126         return E_NOINTERFACE;
127
128     AddRef();
129     return S_OK;
130 }
131
132 ULONG STDMETHODCALLTYPE ServerConnection::AddRef(void)
133 {
134     // COM ref-counting isn't useful to us because we're in charge of the lifetime of the WebView.
135     return 1;
136 }
137
138 ULONG STDMETHODCALLTYPE ServerConnection::Release(void)
139 {
140     // COM ref-counting isn't useful to us because we're in charge of the lifetime of the WebView.
141     return 1;
142 }
143 // IWebScriptDebugListener -----------------------------------
144 HRESULT STDMETHODCALLTYPE ServerConnection::didLoadMainResourceForDataSource(
145     /* [in] */ IWebView*,
146     /* [in] */ IWebDataSource* dataSource)
147 {
148     // Get document source
149     COMPtr<IWebDocumentRepresentation> rep;
150     HRESULT ret = dataSource->representation(&rep);
151     if (FAILED(ret))
152         return ret;
153
154     BOOL canProvideDocumentSource = FALSE;
155     ret = rep->canProvideDocumentSource(&canProvideDocumentSource);
156     if (FAILED(ret))
157         return ret;
158
159     BSTR documentSource = 0;
160     if (canProvideDocumentSource)
161         ret = rep->documentSource(&documentSource);
162
163     if (FAILED(ret) || !documentSource)
164         return ret;
165
166     JSRetainPtr<JSStringRef> documentSourceJS(Adopt, JSStringCreateWithBSTR(documentSource));
167     SysFreeString(documentSource);
168
169     // Get URL
170     COMPtr<IWebURLResponse> response;
171     ret = dataSource->response(&response);
172     if (FAILED(ret))
173         return ret;
174
175     BSTR url = 0;
176     ret = response->URL(&url);
177     if (FAILED(ret))
178         return ret;
179
180     JSRetainPtr<JSStringRef> urlJS(Adopt, JSStringCreateWithBSTR(url));
181     SysFreeString(url);
182
183     DebuggerDocument::updateFileSource(m_globalContext, documentSourceJS.get(), urlJS.get());
184
185     return S_OK;
186 }
187
188 HRESULT STDMETHODCALLTYPE ServerConnection::didParseSource(
189     /* [in] */ IWebView*,
190     /* [in] */ BSTR sourceCode,
191     /* [in] */ UINT baseLineNumber,
192     /* [in] */ BSTR url,
193     /* [in] */ int sourceID,
194     /* [in] */ IWebFrame* webFrame)
195 {
196     HRESULT ret = S_OK;
197     if (!m_globalContext || !sourceCode)
198         return ret;
199
200     COMPtr<IWebDataSource> dataSource;
201     ret = webFrame->dataSource(&dataSource);
202     if (FAILED(ret))
203         return ret;
204
205     COMPtr<IWebURLResponse> response;
206     ret = dataSource->response(&response);
207     if (FAILED(ret))
208         return ret;
209
210     BSTR responseURL;
211     ret = response->URL(&responseURL);
212     if (FAILED(ret))
213         return ret;
214
215     BSTR documentSource = 0;
216     if (!url || !wcscmp(responseURL, url)) {
217         COMPtr<IWebDocumentRepresentation> rep;
218         ret = dataSource->representation(&rep);
219         if (FAILED(ret))
220             return ret;
221
222         BOOL canProvideDocumentSource;
223         rep->canProvideDocumentSource(&canProvideDocumentSource);
224         if (FAILED(ret))
225             return ret;
226
227         if (canProvideDocumentSource) {
228             ret = rep->documentSource(&documentSource);
229             if (FAILED(ret))
230                 return ret;
231         }
232
233         if (!url) {
234             ret = response->URL(&url);
235             if (FAILED(ret))
236                 return ret;
237         }
238     }
239     SysFreeString(responseURL);
240
241     JSRetainPtr<JSStringRef> sourceJS(Adopt, JSStringCreateWithBSTR(sourceCode));
242     JSRetainPtr<JSStringRef> documentSourceJS(Adopt, JSStringCreateWithBSTR(documentSource));
243     SysFreeString(documentSource);
244     JSRetainPtr<JSStringRef> urlJS(Adopt, JSStringCreateWithBSTR(url));
245     JSValueRef sidJS = JSValueMakeNumber(m_globalContext, sourceID);
246     JSValueRef baseLineJS = JSValueMakeNumber(m_globalContext, baseLineNumber);
247
248     DebuggerDocument::didParseScript(m_globalContext, sourceJS.get(), documentSourceJS.get(), urlJS.get(), sidJS, baseLineJS);
249
250     return S_OK;
251 }
252
253 HRESULT STDMETHODCALLTYPE ServerConnection::failedToParseSource(
254     /* [in] */ IWebView*,
255     /* [in] */ BSTR,
256     /* [in] */ UINT,
257     /* [in] */ BSTR,
258     /* [in] */ BSTR,
259     /* [in] */ IWebFrame*)
260 {
261     return S_OK;
262 }
263
264 HRESULT STDMETHODCALLTYPE ServerConnection::didEnterCallFrame(
265     /* [in] */ IWebView*,
266     /* [in] */ IWebScriptCallFrame* frame,
267     /* [in] */ int sourceID,
268     /* [in] */ int lineNumber,
269     /* [in] */ IWebFrame*)
270 {
271     HRESULT ret = S_OK;
272     if (!m_globalContext)
273         return ret;
274
275     // FIXME: This won't be relevant until IWebScriptCallFrame is implemented on Windows
276     m_currentFrame = frame;
277
278     JSValueRef sidJS = JSValueMakeNumber(m_globalContext, sourceID);
279     JSValueRef linenoJS = JSValueMakeNumber(m_globalContext, lineNumber);
280
281     DebuggerDocument::didEnterCallFrame(m_globalContext, sidJS, linenoJS);
282
283     return ret;
284 }
285
286 HRESULT STDMETHODCALLTYPE ServerConnection::willExecuteStatement(
287     /* [in] */ IWebView*,
288     /* [in] */ IWebScriptCallFrame*,
289     /* [in] */ int sourceID,
290     /* [in] */ int lineNumber,
291     /* [in] */ IWebFrame*)
292 {
293     HRESULT ret = S_OK;
294     if (!m_globalContext)
295         return ret;
296
297     JSValueRef sidJS = JSValueMakeNumber(m_globalContext, sourceID);
298     JSValueRef linenoJS = JSValueMakeNumber(m_globalContext, lineNumber);
299
300     DebuggerDocument::willExecuteStatement(m_globalContext, sidJS, linenoJS);
301     return ret;
302 }
303
304 HRESULT STDMETHODCALLTYPE ServerConnection::willLeaveCallFrame(
305     /* [in] */ IWebView*,
306     /* [in] */ IWebScriptCallFrame* frame,
307     /* [in] */ int sourceID,
308     /* [in] */ int lineNumber,
309     /* [in] */ IWebFrame*)
310 {
311     HRESULT ret = S_OK;
312     if (!m_globalContext)
313         return ret;
314
315     JSValueRef sidJS = JSValueMakeNumber(m_globalContext, sourceID);
316     JSValueRef linenoJS = JSValueMakeNumber(m_globalContext, lineNumber);
317
318     DebuggerDocument::willLeaveCallFrame(m_globalContext, sidJS, linenoJS);
319
320     // FIXME: This won't be relevant until IWebScriptCallFrame is implemented on Windows
321     m_currentFrame = frame;
322
323     return S_OK;
324 }
325
326 HRESULT STDMETHODCALLTYPE ServerConnection::exceptionWasRaised(
327     /* [in] */ IWebView*,
328     /* [in] */ IWebScriptCallFrame*,
329     /* [in] */ int sourceID,
330     /* [in] */ int lineNumber,
331     /* [in] */ IWebFrame*)
332 {
333     HRESULT ret = S_OK;
334     if (!m_globalContext)
335         return ret;
336
337     JSValueRef sidJS = JSValueMakeNumber(m_globalContext, sourceID);
338     JSValueRef linenoJS = JSValueMakeNumber(m_globalContext, lineNumber);
339
340     DebuggerDocument::exceptionWasRaised(m_globalContext, sidJS, linenoJS);
341
342     return ret;
343 }