diff options
Diffstat (limited to 'WebKitTools/Drosera/win/ServerConnection.cpp')
-rw-r--r-- | WebKitTools/Drosera/win/ServerConnection.cpp | 368 |
1 files changed, 368 insertions, 0 deletions
diff --git a/WebKitTools/Drosera/win/ServerConnection.cpp b/WebKitTools/Drosera/win/ServerConnection.cpp new file mode 100644 index 0000000..de2b416 --- /dev/null +++ b/WebKitTools/Drosera/win/ServerConnection.cpp @@ -0,0 +1,368 @@ +/* + * Copyright (C) 2007 Apple Inc. All rights reserved. + * Copyright (C) 2006, 2007 Vladimir Olexa (vladimir.olexa@gmail.com) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "ServerConnection.h" + +#include "DebuggerDocument.h" + +#include <JavaScriptCore/JSContextRef.h> +#include <JavaScriptCore/JSRetainPtr.h> +#include <JavaScriptCore/JSStringRefBSTR.h> +#include <JavaScriptCore/RetainPtr.h> +#include <WebKit/ForEachCoClass.h> +#include <WebKit/WebKit.h> + +#include <iostream> + +ServerConnection::ServerConnection() + : m_globalContext(0) + , m_serverConnected(false) +{ + OleInitialize(0); + attemptToCreateServerConnection(); +} + +ServerConnection::~ServerConnection() +{ + if (m_server) + m_server->removeListener(this); + + if (m_globalContext) + JSGlobalContextRelease(m_globalContext); +} + +void ServerConnection::attemptToCreateServerConnection(JSGlobalContextRef globalContextRef) +{ + COMPtr<IWebScriptDebugServer> tempServer; + + CLSID clsid = CLSID_NULL; + if (FAILED(CLSIDFromProgID(PROGID(WebScriptDebugServer), &clsid))) + return; + + if (FAILED(CoCreateInstance(clsid, 0, CLSCTX_LOCAL_SERVER, IID_IWebScriptDebugServer, (void**)&tempServer))) + return; + + if (FAILED(tempServer->sharedWebScriptDebugServer(&m_server))) + return; + + if (FAILED(m_server->addListener(this))) { + m_server = 0; + return; + } + + m_serverConnected = true; + + if (globalContextRef) + m_globalContext = JSGlobalContextRetain(globalContextRef); +} + +void ServerConnection::setGlobalContext(JSGlobalContextRef globalContextRef) +{ + m_globalContext = JSGlobalContextRetain(globalContextRef); +} + +// Pause & Step + +void ServerConnection::pause() +{ + if (m_server) + m_server->pause(); +} + +void ServerConnection::resume() +{ + if (m_server) + m_server->resume(); +} + +void ServerConnection::stepInto() +{ + if (m_server) + m_server->step(); +} + +// IUnknown -------------------------------------------------- +HRESULT STDMETHODCALLTYPE ServerConnection::QueryInterface(REFIID riid, void** ppvObject) +{ + *ppvObject = 0; + if (IsEqualGUID(riid, IID_IUnknown)) + *ppvObject = this; + else if (IsEqualGUID(riid, IID_IWebScriptDebugListener)) + *ppvObject = static_cast<IWebScriptDebugListener*>(this); + else + return E_NOINTERFACE; + + AddRef(); + return S_OK; +} + +ULONG STDMETHODCALLTYPE ServerConnection::AddRef(void) +{ + // COM ref-counting isn't useful to us because we're in charge of the lifetime of the WebView. + return 1; +} + +ULONG STDMETHODCALLTYPE ServerConnection::Release(void) +{ + // COM ref-counting isn't useful to us because we're in charge of the lifetime of the WebView. + return 1; +} +// IWebScriptDebugListener ----------------------------------- +HRESULT STDMETHODCALLTYPE ServerConnection::didLoadMainResourceForDataSource( + /* [in] */ IWebView*, + /* [in] */ IWebDataSource* dataSource) +{ + HRESULT ret = S_OK; + if (!m_globalContext || !dataSource) + return ret; + + // Get document source + COMPtr<IWebDocumentRepresentation> rep; + ret = dataSource->representation(&rep); + if (FAILED(ret)) + return ret; + + BOOL canProvideDocumentSource = FALSE; + ret = rep->canProvideDocumentSource(&canProvideDocumentSource); + if (FAILED(ret)) + return ret; + + BSTR documentSource = 0; + if (canProvideDocumentSource) + ret = rep->documentSource(&documentSource); + + if (FAILED(ret) || !documentSource) + return ret; + + JSRetainPtr<JSStringRef> documentSourceJS(Adopt, JSStringCreateWithBSTR(documentSource)); + SysFreeString(documentSource); + + // Get URL + COMPtr<IWebURLResponse> response; + ret = dataSource->response(&response); + if (FAILED(ret)) + return ret; + + BSTR url = 0; + ret = response->URL(&url); + if (FAILED(ret)) + return ret; + + JSRetainPtr<JSStringRef> urlJS(Adopt, JSStringCreateWithBSTR(url)); + SysFreeString(url); + + DebuggerDocument::updateFileSource(m_globalContext, documentSourceJS.get(), urlJS.get()); + + return S_OK; +} + +HRESULT STDMETHODCALLTYPE ServerConnection::didParseSource( + /* [in] */ IWebView*, + /* [in] */ BSTR sourceCode, + /* [in] */ UINT baseLineNumber, + /* [in] */ BSTR url, + /* [in] */ int sourceID, + /* [in] */ IWebFrame* webFrame) +{ + HRESULT ret = S_OK; + if (!m_globalContext || !sourceCode) + return ret; + + COMPtr<IWebDataSource> dataSource; + ret = webFrame->dataSource(&dataSource); + if (FAILED(ret)) + return ret; + + COMPtr<IWebURLResponse> response; + ret = dataSource->response(&response); + if (FAILED(ret)) + return ret; + + BSTR responseURL; + ret = response->URL(&responseURL); + if (FAILED(ret)) + return ret; + + BSTR documentSource = 0; + if (!url || !wcscmp(responseURL, url)) { + COMPtr<IWebDocumentRepresentation> rep; + ret = dataSource->representation(&rep); + if (FAILED(ret)) + return ret; + + BOOL canProvideDocumentSource; + rep->canProvideDocumentSource(&canProvideDocumentSource); + if (FAILED(ret)) + return ret; + + if (canProvideDocumentSource) { + ret = rep->documentSource(&documentSource); + if (FAILED(ret)) + return ret; + } + + if (!url) { + ret = response->URL(&url); + if (FAILED(ret)) + return ret; + } + } + SysFreeString(responseURL); + + JSRetainPtr<JSStringRef> sourceJS(Adopt, JSStringCreateWithBSTR(sourceCode)); + JSRetainPtr<JSStringRef> documentSourceJS(Adopt, JSStringCreateWithBSTR(documentSource)); + SysFreeString(documentSource); + JSRetainPtr<JSStringRef> urlJS(Adopt, JSStringCreateWithBSTR(url)); + JSValueRef sidJS = JSValueMakeNumber(m_globalContext, sourceID); + JSValueRef baseLineJS = JSValueMakeNumber(m_globalContext, baseLineNumber); + + DebuggerDocument::didParseScript(m_globalContext, sourceJS.get(), documentSourceJS.get(), urlJS.get(), sidJS, baseLineJS); + + return S_OK; +} + +HRESULT STDMETHODCALLTYPE ServerConnection::failedToParseSource( + /* [in] */ IWebView*, + /* [in] */ BSTR, + /* [in] */ UINT, + /* [in] */ BSTR, + /* [in] */ BSTR, + /* [in] */ IWebFrame*) +{ + return S_OK; +} + +HRESULT STDMETHODCALLTYPE ServerConnection::didEnterCallFrame( + /* [in] */ IWebView*, + /* [in] */ IWebScriptCallFrame* frame, + /* [in] */ int sourceID, + /* [in] */ int lineNumber, + /* [in] */ IWebFrame*) +{ + HRESULT ret = S_OK; + if (!m_globalContext) + return ret; + + m_currentFrame = frame; + + JSValueRef sidJS = JSValueMakeNumber(m_globalContext, sourceID); + JSValueRef linenoJS = JSValueMakeNumber(m_globalContext, lineNumber); + + DebuggerDocument::didEnterCallFrame(m_globalContext, sidJS, linenoJS); + + return ret; +} + +HRESULT STDMETHODCALLTYPE ServerConnection::willExecuteStatement( + /* [in] */ IWebView*, + /* [in] */ IWebScriptCallFrame*, + /* [in] */ int sourceID, + /* [in] */ int lineNumber, + /* [in] */ IWebFrame*) +{ + HRESULT ret = S_OK; + if (!m_globalContext) + return ret; + + JSValueRef sidJS = JSValueMakeNumber(m_globalContext, sourceID); + JSValueRef linenoJS = JSValueMakeNumber(m_globalContext, lineNumber); + + DebuggerDocument::willExecuteStatement(m_globalContext, sidJS, linenoJS); + return ret; +} + +HRESULT STDMETHODCALLTYPE ServerConnection::willLeaveCallFrame( + /* [in] */ IWebView*, + /* [in] */ IWebScriptCallFrame* frame, + /* [in] */ int sourceID, + /* [in] */ int lineNumber, + /* [in] */ IWebFrame*) +{ + HRESULT ret = S_OK; + if (!m_globalContext) + return ret; + + JSValueRef sidJS = JSValueMakeNumber(m_globalContext, sourceID); + JSValueRef linenoJS = JSValueMakeNumber(m_globalContext, lineNumber); + + DebuggerDocument::willLeaveCallFrame(m_globalContext, sidJS, linenoJS); + + m_currentFrame = frame; + + return S_OK; +} + +HRESULT STDMETHODCALLTYPE ServerConnection::exceptionWasRaised( + /* [in] */ IWebView*, + /* [in] */ IWebScriptCallFrame*, + /* [in] */ int sourceID, + /* [in] */ int lineNumber, + /* [in] */ IWebFrame*) +{ + HRESULT ret = S_OK; + if (!m_globalContext) + return ret; + + JSValueRef sidJS = JSValueMakeNumber(m_globalContext, sourceID); + JSValueRef linenoJS = JSValueMakeNumber(m_globalContext, lineNumber); + + DebuggerDocument::exceptionWasRaised(m_globalContext, sidJS, linenoJS); + + return ret; +} + +HRESULT STDMETHODCALLTYPE ServerConnection::serverDidDie() +{ + m_server = 0; + m_currentFrame = 0; + m_serverConnected = false; + return S_OK; +} + +// Stack & Variables + +IWebScriptCallFrame* ServerConnection::currentFrame() const +{ + return m_currentFrame.get(); +} + +COMPtr<IWebScriptCallFrame> ServerConnection::getCallerFrame(int callFrame) const +{ + COMPtr<IWebScriptCallFrame> cframe = currentFrame(); + for (int count = 0; count < callFrame; count++) { + COMPtr<IWebScriptCallFrame> callerFrame; + if (FAILED(cframe->caller(&callerFrame))) + return 0; + + cframe = callerFrame; + } + + return cframe; +} |