summaryrefslogtreecommitdiffstats
path: root/chrome/browser/debugger
diff options
context:
space:
mode:
authorinitial.commit <initial.commit@0039d316-1c4b-4281-b951-d872f2087c98>2008-07-26 23:55:29 +0000
committerinitial.commit <initial.commit@0039d316-1c4b-4281-b951-d872f2087c98>2008-07-26 23:55:29 +0000
commit09911bf300f1a419907a9412154760efd0b7abc3 (patch)
treef131325fb4e2ad12c6d3504ab75b16dd92facfed /chrome/browser/debugger
parent586acc5fe142f498261f52c66862fa417c3d52d2 (diff)
downloadchromium_src-09911bf300f1a419907a9412154760efd0b7abc3.zip
chromium_src-09911bf300f1a419907a9412154760efd0b7abc3.tar.gz
chromium_src-09911bf300f1a419907a9412154760efd0b7abc3.tar.bz2
Add chrome to the repository.
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@15 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/debugger')
-rw-r--r--chrome/browser/debugger/SConscript59
-rw-r--r--chrome/browser/debugger/debugger.vcproj183
-rw-r--r--chrome/browser/debugger/debugger.vsprops16
-rw-r--r--chrome/browser/debugger/debugger_disabled.vcproj147
-rw-r--r--chrome/browser/debugger/debugger_disabled.vsprops12
-rw-r--r--chrome/browser/debugger/debugger_io.h72
-rw-r--r--chrome/browser/debugger/debugger_io_socket.cc157
-rw-r--r--chrome/browser/debugger/debugger_io_socket.h87
-rw-r--r--chrome/browser/debugger/debugger_node.cc409
-rw-r--r--chrome/browser/debugger/debugger_node.h261
-rw-r--r--chrome/browser/debugger/debugger_shell.cc419
-rw-r--r--chrome/browser/debugger/debugger_shell.h150
-rw-r--r--chrome/browser/debugger/debugger_view.cc135
-rw-r--r--chrome/browser/debugger/debugger_view.h110
-rw-r--r--chrome/browser/debugger/debugger_window.cc199
-rw-r--r--chrome/browser/debugger/debugger_window.h86
-rw-r--r--chrome/browser/debugger/debugger_wrapper.cc63
-rw-r--r--chrome/browser/debugger/debugger_wrapper.h68
18 files changed, 2633 insertions, 0 deletions
diff --git a/chrome/browser/debugger/SConscript b/chrome/browser/debugger/SConscript
new file mode 100644
index 0000000..601c42c
--- /dev/null
+++ b/chrome/browser/debugger/SConscript
@@ -0,0 +1,59 @@
+Import('env')
+
+env = env.Clone()
+
+
+
+env.Prepend(
+ CPPPATH = [
+ Dir("#/.."),
+ ],
+ CPPDEFINES = [
+ "CERT_CHAIN_PARA_HAS_EXTRA_FIELDS",
+ "WIN32_LEAN_AND_MEAN",
+ "LIBXML_STATIC",
+ "U_STATIC_IMPLEMENTATION",
+ "PNG_USER_CONFIG",
+ "CHROME_PNG_WRITE_SUPPORT",
+ ],
+ CCFLAGS = [
+ '/TP',
+
+ #'/Wp64',
+
+ '/wd4503',
+ '/wd4819',
+ ],
+)
+
+env.Append(
+ CPPPATH = [
+ #"C:\src\trunk\chrome\Debug\webkit"
+ Dir("#/../chrome/third_party/webkit/out"),
+
+ Dir("#/../chrome/third_party/wtl/include"),
+ Dir("#/../third_party/npapi"),
+ Dir("#/../third_party/libxml/include"),
+ Dir("#/../third_party/icu38/public/common"),
+ Dir("#/../third_party/icu38/public/i18n"),
+ Dir("#/../chrome/app"), #Dir("#/../chrome/generated_resources"),
+ #Dir("Debug/obj/localized_strings"),
+ Dir("#/../third_party/zlib"),
+ Dir("#/../skia/include"),
+ Dir("#/../skia/include/corecg"),
+ Dir("#/../skia/platform"),
+ Dir("#/../third_party/libpng"),
+ Dir("#/../breakpad/src"),
+ ],
+)
+
+input_files = [
+ "debugger_shell.cc",
+ "debugger_io_socket.cc",
+ "debugger_node.cc",
+ "debugger_view.cc",
+ "debugger_window.cc",
+ "debugger_wrapper.cc",
+]
+
+env.StaticLibrary('debugger', input_files)
diff --git a/chrome/browser/debugger/debugger.vcproj b/chrome/browser/debugger/debugger.vcproj
new file mode 100644
index 0000000..3159e6d
--- /dev/null
+++ b/chrome/browser/debugger/debugger.vcproj
@@ -0,0 +1,183 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="debugger"
+ ProjectGUID="{57823D8C-A317-4713-9125-2C91FDFD12D6}"
+ RootNamespace="debugger"
+ Keyword="Win32Proj"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ ConfigurationType="4"
+ InheritedPropertySheets=".\debugger.vsprops;$(SolutionDir)..\build\debug.vsprops"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ ConfigurationType="4"
+ InheritedPropertySheets=".\debugger.vsprops;$(SolutionDir)..\build\release.vsprops"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <File
+ RelativePath=".\debugger_io.h"
+ >
+ </File>
+ <File
+ RelativePath=".\debugger_io_socket.cc"
+ >
+ </File>
+ <File
+ RelativePath=".\debugger_io_socket.h"
+ >
+ </File>
+ <File
+ RelativePath=".\debugger_node.cc"
+ >
+ </File>
+ <File
+ RelativePath=".\debugger_node.h"
+ >
+ </File>
+ <File
+ RelativePath=".\debugger_shell.cc"
+ >
+ </File>
+ <File
+ RelativePath=".\debugger_shell.h"
+ >
+ </File>
+ <File
+ RelativePath="..\resources\debugger_shell.js"
+ >
+ </File>
+ <File
+ RelativePath=".\debugger_view.cc"
+ >
+ </File>
+ <File
+ RelativePath=".\debugger_view.h"
+ >
+ </File>
+ <File
+ RelativePath=".\debugger_window.cc"
+ >
+ </File>
+ <File
+ RelativePath=".\debugger_window.h"
+ >
+ </File>
+ <File
+ RelativePath=".\debugger_wrapper.cc"
+ >
+ </File>
+ <File
+ RelativePath=".\debugger_wrapper.h"
+ >
+ </File>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/chrome/browser/debugger/debugger.vsprops b/chrome/browser/debugger/debugger.vsprops
new file mode 100644
index 0000000..4d941fc
--- /dev/null
+++ b/chrome/browser/debugger/debugger.vsprops
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioPropertySheet
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="debugger"
+ InheritedPropertySheets="$(SolutionDir)..\build\common.vsprops;$(SolutionDir)..\breakpad\using_breakpad.vsprops;$(SolutionDir)..\third_party\libpng\using_libpng.vsprops;$(SolutionDir)..\skia\using_skia.vsprops;$(SolutionDir)..\third_party\zlib\using_zlib.vsprops;$(SolutionDir)\tools\build\win\using_generated_strings.vsprops;$(SolutionDir)..\third_party\icu38\build\using_icu.vsprops;$(SolutionDir)..\third_party\libxml\build\using_libxml.vsprops;$(SolutionDir)..\third_party\npapi\using_npapi.vsprops;$(SolutionDir)third_party\wtl\using_wtl.vsprops"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="&quot;$(OutDir)\webkit&quot;;$(SolutionDir)\third_party\webkit\out"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ AdditionalIncludeDirectories="$(IntDir)"
+ />
+</VisualStudioPropertySheet>
diff --git a/chrome/browser/debugger/debugger_disabled.vcproj b/chrome/browser/debugger/debugger_disabled.vcproj
new file mode 100644
index 0000000..6279337
--- /dev/null
+++ b/chrome/browser/debugger/debugger_disabled.vcproj
@@ -0,0 +1,147 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="debugger_disabled"
+ ProjectGUID="{369B9881-3F2C-464D-A96C-E281405DF8F6}"
+ RootNamespace="debugger_disabled"
+ Keyword="Win32Proj"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ ConfigurationType="4"
+ InheritedPropertySheets="$(SolutionDir)..\build\debug.vsprops;.\debugger_disabled.vsprops"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ ConfigurationType="4"
+ InheritedPropertySheets="$(SolutionDir)..\build\release.vsprops;.\debugger_disabled.vsprops"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <File
+ RelativePath=".\debugger.h"
+ >
+ </File>
+ <File
+ RelativePath=".\debugger_window.cc"
+ >
+ </File>
+ <File
+ RelativePath=".\debugger_window.h"
+ >
+ </File>
+ <File
+ RelativePath=".\debugger_wrapper.cc"
+ >
+ </File>
+ <File
+ RelativePath=".\debugger_wrapper.h"
+ >
+ </File>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/chrome/browser/debugger/debugger_disabled.vsprops b/chrome/browser/debugger/debugger_disabled.vsprops
new file mode 100644
index 0000000..fd949c3
--- /dev/null
+++ b/chrome/browser/debugger/debugger_disabled.vsprops
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioPropertySheet
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="debugger_disabled"
+ InheritedPropertySheets="$(SolutionDir)..\build\common.vsprops;$(SolutionDir)..\breakpad\using_breakpad.vsprops;$(SolutionDir)..\third_party\libpng\using_libpng.vsprops;$(SolutionDir)..\skia\using_skia.vsprops;$(SolutionDir)..\third_party\zlib\using_zlib.vsprops;$(SolutionDir)\tools\build\win\using_generated_strings.vsprops;$(SolutionDir)..\third_party\icu38\build\using_icu.vsprops;$(SolutionDir)..\third_party\libxml\build\using_libxml.vsprops;$(SolutionDir)..\third_party\npapi\using_npapi.vsprops;$(SolutionDir)\tools\build\win\debugger_disabled.vsprops;$(SolutionDir)third_party\wtl\using_wtl.vsprops"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="&quot;$(OutDir)\webkit&quot;;$(SolutionDir)\third_party\webkit\out"
+ />
+</VisualStudioPropertySheet>
diff --git a/chrome/browser/debugger/debugger_io.h b/chrome/browser/debugger/debugger_io.h
new file mode 100644
index 0000000..6d6e792
--- /dev/null
+++ b/chrome/browser/debugger/debugger_io.h
@@ -0,0 +1,72 @@
+// Copyright 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * 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.
+// * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
+// OWNER OR 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.
+
+#ifndef CHROME_BROWSER_DEBUGGER_DEBUGGER_IO_H__
+#define CHROME_BROWSER_DEBUGGER_DEBUGGER_IO_H__
+
+#include "base/basictypes.h"
+#include "base/ref_counted.h"
+
+class DebuggerShell;
+
+class DebuggerInputOutput: public base::RefCountedThreadSafe<DebuggerInputOutput> {
+public:
+ DebuggerInputOutput() {}
+ virtual ~DebuggerInputOutput() {}
+
+ // Called when Debugger is ready to begin.
+ virtual void Start(DebuggerShell* debugger) { debugger_ = debugger; }
+
+ // Called when Debugger is shutting down
+ virtual void Stop() {}
+
+ // Outputs a string to the connection.
+ virtual void Output(const std::string& out) = 0;
+ virtual void Output(const std::wstring& out) = 0;
+ virtual void OutputLine(const std::string& out) = 0;
+ virtual void OutputLine(const std::wstring& out) = 0;
+ virtual void OutputPrompt(const std::string& prompt) = 0;
+ virtual void OutputPrompt(const std::wstring& prompt) = 0;
+
+ // called by debugger debugger - ready is false when a command has just been
+ // entered and true when a response to that command has been received
+ virtual void SetDebuggerReady(bool ready) {}
+ // called by debugger debugger - brk is false when the web page being debugged
+ // is running, and true when the page is stopped at a breakpoint
+ virtual void SetDebuggerBreak(bool brk) {}
+
+protected:
+ DebuggerShell* debugger_;
+
+private:
+
+ DISALLOW_EVIL_CONSTRUCTORS(DebuggerInputOutput);
+};
+
+#endif // CHROME_BROWSER_DEBUGGER_DEBUGGER_IO_H__ \ No newline at end of file
diff --git a/chrome/browser/debugger/debugger_io_socket.cc b/chrome/browser/debugger/debugger_io_socket.cc
new file mode 100644
index 0000000..b3036a8
--- /dev/null
+++ b/chrome/browser/debugger/debugger_io_socket.cc
@@ -0,0 +1,157 @@
+// Copyright 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * 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.
+// * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
+// OWNER OR 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 "chrome/browser/debugger/debugger_io_socket.h"
+
+#include "base/string_util.h"
+#include "base/thread.h"
+#include "chrome/browser/browser.h"
+#include "chrome/browser/browser_list.h"
+#include "chrome/browser/browser_process.h"
+#include "chrome/browser/browser_resources.h"
+#include "chrome/browser/render_process_host.h"
+#include "chrome/browser/tab_contents.h"
+#include "chrome/browser/debugger/debugger_shell.h"
+#include "chrome/common/resource_bundle.h"
+#include "v8/public/v8.h"
+
+////////////////////////////////////////////////
+
+DebuggerInputOutputSocket::DebuggerInputOutputSocket(int port)
+ : server_(0), connection_(0), port_(port) {
+ ui_loop_ = MessageLoop::current();
+ io_loop_ = g_browser_process->io_thread()->message_loop();
+}
+
+void DebuggerInputOutputSocket::Start(DebuggerShell* debugger) {
+ DebuggerInputOutput::Start(debugger);
+ io_loop_->PostTask(FROM_HERE, NewRunnableMethod(
+ this, &DebuggerInputOutputSocket::StartListening));
+}
+
+void DebuggerInputOutputSocket::StartListening() {
+ DCHECK(MessageLoop::current() == io_loop_);
+ server_ = TelnetServer::Listen("127.0.0.1", port_, this, io_loop_);
+}
+
+DebuggerInputOutputSocket::~DebuggerInputOutputSocket() {
+ // Stop() must be called prior to this being called
+ DCHECK(connection_.get() == NULL);
+ DCHECK(server_.get() == NULL);
+}
+
+void DebuggerInputOutputSocket::Stop() {
+ io_loop_->PostTask(FROM_HERE, NewRunnableMethod(
+ this, &DebuggerInputOutputSocket::StopListening));
+}
+
+void DebuggerInputOutputSocket::StopListening() {
+ connection_ = NULL;
+ server_ = NULL;
+}
+
+void DebuggerInputOutputSocket::DidAccept(ListenSocket *server,
+ ListenSocket *connection) {
+ DCHECK(MessageLoop::current() == io_loop_);
+ if (connection_ == NULL) {
+ connection_ = connection;
+ connection_->AddRef();
+ ui_loop_->PostTask(FROM_HERE, NewRunnableMethod(
+ debugger_, &DebuggerShell::DidConnect));
+ } else {
+ delete connection;
+ }
+}
+
+void DebuggerInputOutputSocket::Output(const std::wstring& out) {
+ OutputLater(out, false);
+}
+
+void DebuggerInputOutputSocket::OutputLine(const std::wstring& out) {
+ OutputLater(out, true);
+}
+
+void DebuggerInputOutputSocket::OutputPrompt(const std::wstring& prompt) {
+ Output(prompt);
+}
+
+void DebuggerInputOutputSocket::Output(const std::string& out) {
+ OutputLater(out, false);
+}
+
+void DebuggerInputOutputSocket::OutputLine(const std::string& out) {
+ OutputLater(out, true);
+}
+
+void DebuggerInputOutputSocket::OutputPrompt(const std::string& prompt) {
+ Output(prompt);
+}
+
+void DebuggerInputOutputSocket::OutputLater(const std::wstring& out, bool lf) {
+ std::string utf8 = WideToUTF8(out);
+ OutputLater(utf8, lf);
+}
+
+void DebuggerInputOutputSocket::OutputLater(const std::string& out, bool lf) {
+ io_loop_->PostTask(FROM_HERE, NewRunnableMethod(
+ this, &DebuggerInputOutputSocket::OutputToSocket, out, lf));
+}
+
+void DebuggerInputOutputSocket::OutputToSocket(const std::string& out, bool lf) {
+ DCHECK(MessageLoop::current() == io_loop_);
+ if (connection_) {
+ if (out.length()) {
+ connection_->Send(out, lf);
+ }
+ } else {
+ logging::LogMessage("CONSOLE", 0).stream() << "V8 debugger: " << out;
+ }
+}
+
+void DebuggerInputOutputSocket::DidRead(ListenSocket *connection,
+ const std::string& data) {
+ DCHECK(MessageLoop::current() == io_loop_);
+ if (connection == connection_) {
+ ui_loop_->PostTask(FROM_HERE, NewRunnableMethod(
+ debugger_, &DebuggerShell::ProcessCommand, data));
+ } else {
+ // TODO(erikkay): assert?
+ }
+}
+
+void DebuggerInputOutputSocket::DidClose(ListenSocket *sock) {
+ DCHECK(MessageLoop::current() == io_loop_);
+ if (connection_ == sock) {
+ connection_ = NULL;
+ sock->Release();
+ } else {
+ // TODO(erikkay): assert?
+ }
+}
+
diff --git a/chrome/browser/debugger/debugger_io_socket.h b/chrome/browser/debugger/debugger_io_socket.h
new file mode 100644
index 0000000..50b1115
--- /dev/null
+++ b/chrome/browser/debugger/debugger_io_socket.h
@@ -0,0 +1,87 @@
+// Copyright 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * 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.
+// * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
+// OWNER OR 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.
+
+#ifndef CHROME_BROWSER_DEBUGGER_DEBUGGER_IO_SOCKET_H__
+#define CHROME_BROWSER_DEBUGGER_DEBUGGER_IO_SOCKET_H__
+
+#include "chrome/browser/debugger/debugger_io.h"
+#include "net/base/telnet_server.h"
+
+class DebuggerShell;
+
+// Interaction with the underlying Socket object MUST happen in the IO thread.
+// However, Debugger will call into this object from the main thread. As a result
+// we wind up having helper methods that we call with InvokeLater into the IO
+// thread.
+
+class DebuggerInputOutputSocket: public DebuggerInputOutput,
+ public ListenSocket::ListenSocketDelegate {
+public:
+ DebuggerInputOutputSocket(int port);
+ virtual ~DebuggerInputOutputSocket();
+
+ // SocketDelegate - called in IO thread by Socket
+ virtual void DidAccept(ListenSocket* server, ListenSocket* connection);
+ virtual void DidRead(ListenSocket* connection, const std::string& data);
+ virtual void DidClose(ListenSocket* sock);
+
+ // Overrides - called from the main thread by Debugger
+ // these in turn call helper methods in the IO thread.
+ virtual void Output(const std::wstring& out);
+ virtual void OutputLine(const std::wstring& out);
+ virtual void OutputPrompt(const std::wstring& prompt);
+ virtual void Output(const std::string& out);
+ virtual void OutputLine(const std::string& out);
+ virtual void OutputPrompt(const std::string& prompt);
+ virtual void Start(DebuggerShell* debugger);
+ // Stop must be called prior to this object being released, so that cleanup
+ // can happen in the IO thread.
+ virtual void Stop();
+
+private:
+
+ // The following methods are called from the IO thread.
+
+ // Creates a TelnetServer listing on 127:0.0.1:port_
+ void StartListening();
+ void StopListening();
+ void OutputLater(const std::wstring& out, bool lf);
+ void OutputLater(const std::string& out, bool lf);
+ void OutputToSocket(const std::string& out, bool lf);
+
+ scoped_refptr<ListenSocket> server_;
+ scoped_refptr<ListenSocket> connection_;
+ MessageLoop* ui_loop_;
+ MessageLoop* io_loop_;
+ int port_;
+
+ DISALLOW_EVIL_CONSTRUCTORS(DebuggerInputOutputSocket);
+};
+
+#endif // CHROME_BROWSER_DEBUGGER_DEBUGGER_IO_SOCKET_H__ \ No newline at end of file
diff --git a/chrome/browser/debugger/debugger_node.cc b/chrome/browser/debugger/debugger_node.cc
new file mode 100644
index 0000000..6ae0c49
--- /dev/null
+++ b/chrome/browser/debugger/debugger_node.cc
@@ -0,0 +1,409 @@
+// Copyright 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * 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.
+// * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
+// OWNER OR 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 "debugger_node.h"
+
+#include "base/process_util.h"
+#include "base/string_util.h"
+#include "chrome/browser/browser.h"
+#include "chrome/browser/browser_list.h"
+#include "chrome/browser/browser_process.h"
+#include "chrome/browser/render_process_host.h"
+#include "chrome/browser/render_view_host.h"
+#include "chrome/browser/debugger/debugger_shell.h"
+
+DebuggerNode::DebuggerNode() : valid_(true), observing_(false), data_(NULL) {
+}
+
+void DebuggerNode::Observe(NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details) {
+ StopObserving();
+ Invalidate();
+}
+
+DebuggerNode::~DebuggerNode() {
+}
+
+
+void DebuggerNode::StopObserving() {
+ if (observing_ && valid_) {
+ NotificationService* service = NotificationService::current();
+ DCHECK(service);
+ StopObserving(service);
+ observing_ = false;
+ }
+ data_ = NULL;
+}
+
+void DebuggerNode::StopObserving(NotificationService *service) {
+}
+
+v8::Handle<v8::Value> DebuggerNode::IndexGetter(uint32_t index,
+ const v8::AccessorInfo& info) {
+ return v8::Undefined();
+}
+
+v8::Handle<v8::Value> DebuggerNode::PropGetter(v8::Handle<v8::String> prop,
+ const v8::AccessorInfo& info) {
+ return v8::Undefined();
+}
+
+v8::Handle<v8::Value> DebuggerNode::Function(const v8::Arguments& args) {
+ return v8::Undefined();
+}
+
+v8::Handle<v8::Value> DebuggerNode::NewInstance() {
+ DebuggerNodeWrapper *wrap = new DebuggerNodeWrapper(this);
+ wrap->AddRef();
+ v8::Local<v8::External> node = v8::External::New(wrap);
+ // TODO(erikkay): cache these templates?
+ v8::Local<v8::FunctionTemplate> templ = v8::FunctionTemplate::New();
+ if (IsFunction()) {
+ templ->SetCallHandler(&DebuggerNode::NodeFunc, node);
+ v8::Local<v8::Function> f = templ->GetFunction();
+ return f;
+ }
+ v8::Local<v8::ObjectTemplate> instance = templ->InstanceTemplate();
+ if (IsObject()) {
+ instance->SetNamedPropertyHandler(&DebuggerNode::NodeGetter, 0, 0, 0, 0, node);
+ // TODO(erikkay): verify that the interceptor does not have to be
+ // behind the object
+ }
+ if (IsCollection()) {
+ instance->SetIndexedPropertyHandler(&DebuggerNode::NodeIndex, 0, 0, 0, 0, node);
+ }
+ v8::Local<v8::Object> ret = instance->NewInstance();
+ v8::Persistent<v8::Object> p = v8::Persistent<v8::Object>::New(ret);
+ p.MakeWeak(wrap, &DebuggerShell::HandleWeakReference);
+ return ret;
+}
+
+v8::Handle<v8::Value> DebuggerNode::NodeGetter(v8::Local<v8::String> prop,
+ const v8::AccessorInfo& info) {
+ DebuggerNodeWrapper* w =
+ static_cast<DebuggerNodeWrapper*>(v8::External::Cast(*info.Data())->Value());
+ DebuggerNode* n = w->node();
+ if (n->IsValid() && n->IsObject()) {
+ return n->PropGetter(prop, info);
+ } else {
+ return v8::Undefined();
+ }
+}
+
+v8::Handle<v8::Value> DebuggerNode::NodeIndex(uint32_t index,
+ const v8::AccessorInfo& info) {
+ DebuggerNodeWrapper* w =
+ static_cast<DebuggerNodeWrapper*>(v8::External::Cast(*info.Data())->Value());
+ DebuggerNode* n = w->node();
+ if (n->IsValid() && n->IsCollection()) {
+ return n->IndexGetter(index, info);
+ } else {
+ return v8::Undefined();
+ }
+}
+
+v8::Handle<v8::Value> DebuggerNode::NodeFunc(const v8::Arguments& args) {
+ DebuggerNodeWrapper* w =
+ static_cast<DebuggerNodeWrapper*>(v8::External::Cast(*args.Data())->Value());
+ DebuggerNode* n = w->node();
+ if (n->IsValid() && n->IsFunction()) {
+ return n->Function(args);
+ } else {
+ return v8::Undefined();
+ }
+}
+
+
+
+/////////////////////////////////////////////
+
+ChromeNode::ChromeNode(DebuggerShell* debugger) {
+ debugger_ = debugger;
+}
+
+ChromeNode::~ChromeNode() {
+}
+
+v8::Handle<v8::Value> ChromeNode::PropGetter(v8::Handle<v8::String> prop,
+ const v8::AccessorInfo& info) {
+ if (prop->Equals(v8::String::New("pid"))) {
+ return v8::Number::New(GetCurrentProcessId());
+ } else if (prop->Equals(v8::String::New("browser"))) {
+ BrowserListNode *node = BrowserListNode::BrowserList();
+ return node->NewInstance();
+ } else if (prop->Equals(v8::String::New("setDebuggerReady"))) {
+ FunctionNode<DebuggerShell>* f =
+ new FunctionNode<DebuggerShell>(DebuggerShell::SetDebuggerReady, debugger_);
+ return f->NewInstance();
+ } else if (prop->Equals(v8::String::New("setDebuggerBreak"))) {
+ FunctionNode<DebuggerShell>* f =
+ new FunctionNode<DebuggerShell>(DebuggerShell::SetDebuggerBreak, debugger_);
+ return f->NewInstance();
+ } else if (prop->Equals(v8::String::New("foo"))) {
+ return v8::Undefined();
+ } else {
+ return prop;
+ }
+}
+
+void ChromeNode::StopObserving(NotificationService *service) {
+}
+
+/////////////////////////////////////////////
+
+BrowserNode::BrowserNode(Browser *b) {
+ data_ = b;
+
+ NotificationService* service = NotificationService::current();
+ DCHECK(service);
+ service->AddObserver(this, NOTIFY_BROWSER_CLOSED, Source<Browser>(b));
+ observing_ = true;
+}
+
+void BrowserNode::StopObserving(NotificationService *service) {
+ Browser *b = static_cast<Browser*>(data_);
+ service->RemoveObserver(this, NOTIFY_BROWSER_CLOSED, Source<Browser>(b));
+}
+
+BrowserNode* BrowserNode::BrowserAtIndex(int index) {
+ if (index >= 0) {
+ BrowserList::const_iterator iter = BrowserList::begin();
+
+ for (; (iter != BrowserList::end()) && (index > 0); ++iter, --index);
+
+ if (iter != BrowserList::end()) {
+ return new BrowserNode(*iter);
+ }
+ }
+ return NULL;
+}
+
+BrowserNode::~BrowserNode() {
+}
+
+Browser* BrowserNode::GetBrowser() {
+ if (IsValid()) {
+ return static_cast<Browser *>(data_);
+ } else {
+ return NULL;
+ }
+}
+
+v8::Handle<v8::Value> BrowserNode::PropGetter(v8::Handle<v8::String> prop,
+ const v8::AccessorInfo& info) {
+ Browser *b = GetBrowser();
+ if (b != NULL) {
+ if (prop->Equals(v8::String::New("title"))) {
+ const TabContents *t = b->GetSelectedTabContents();
+ std::wstring title = t->GetTitle();
+ std::string title2 = WideToUTF8(title);
+ return v8::String::New(title2.c_str());
+ } else if (prop->Equals(v8::String::New("tab"))) {
+ TabListNode* node = TabListNode::TabList(b);
+ return node->NewInstance();
+ }
+ }
+ return v8::Undefined();
+}
+
+/////////////////////////////////////////////
+
+BrowserListNode* BrowserListNode::BrowserList() {
+ // TODO(erikkay): cache
+ return new BrowserListNode();
+}
+
+BrowserListNode::BrowserListNode() {
+}
+
+BrowserListNode::~BrowserListNode() {
+}
+
+v8::Handle<v8::Value> BrowserListNode::IndexGetter(
+ uint32_t index,
+ const v8::AccessorInfo& info) {
+ BrowserNode* b = BrowserNode::BrowserAtIndex(index);
+ if (!b) {
+ return v8::Undefined();
+ }
+ return b->NewInstance();
+}
+
+void BrowserListNode::StopObserving(NotificationService *service) {
+}
+
+/////////////////////////////////////////////
+
+TabListNode::TabListNode(Browser* b) {
+ data_ = b;
+
+ NotificationService* service = NotificationService::current();
+ DCHECK(service);
+ service->AddObserver(this, NOTIFY_BROWSER_CLOSED, Source<Browser>(b));
+ observing_ = true;
+}
+
+TabListNode::~TabListNode() {
+}
+
+TabListNode* TabListNode::TabList(Browser* b) {
+ return new TabListNode(b);
+}
+
+Browser* TabListNode::GetBrowser() {
+ if (IsValid()) {
+ return static_cast<Browser *>(data_);
+ } else {
+ return NULL;
+ }
+}
+
+void TabListNode::StopObserving(NotificationService *service) {
+ Browser *b = static_cast<Browser*>(data_);
+ service->RemoveObserver(this, NOTIFY_BROWSER_CLOSED, Source<Browser>(b));
+}
+
+v8::Handle<v8::Value> TabListNode::IndexGetter(uint32_t index,
+ const v8::AccessorInfo& info) {
+ Browser* b = GetBrowser();
+ if (b != NULL) {
+ TabContents* tab_contents = b->GetTabContentsAt(index);
+ if (tab_contents) {
+ TabNode* node = new TabNode(tab_contents);
+ return node->NewInstance();
+ }
+ }
+ return v8::Undefined();
+}
+
+/////////////////////////////////////////////
+
+TabNode::TabNode(TabContents *c) {
+ data_ = c->controller();
+
+ NotificationService* service = NotificationService::current();
+ DCHECK(service);
+ service->AddObserver(this, NOTIFY_TAB_CLOSING,
+ Source<NavigationController>(c->controller()));
+ observing_ = true;
+}
+
+TabNode::~TabNode() {
+}
+
+void TabNode::StopObserving(NotificationService *service) {
+ NavigationController *c = static_cast<NavigationController*>(data_);
+ service->RemoveObserver(this, NOTIFY_TAB_CLOSING,
+ Source<NavigationController>(c));
+}
+
+TabContents* TabNode::GetTab() {
+ if (IsValid()) {
+ return static_cast<NavigationController*>(data_)->active_contents();
+ } else {
+ return NULL;
+ }
+}
+
+v8::Handle<v8::Value> TabNode::SendToDebugger(const v8::Arguments& args,
+ WebContents* web) {
+ RenderViewHost* host = web->render_view_host();
+ if (args.Length() == 1) {
+ std::wstring cmd;
+ v8::Handle<v8::Value> obj;
+ obj = args[0];
+ DebuggerShell::ObjectToString(obj, &cmd);
+ host->SendToDebugger(cmd);
+ }
+ return v8::Undefined();
+}
+
+v8::Handle<v8::Value> TabNode::Attach(const v8::Arguments& args,
+ WebContents* web) {
+ RenderViewHost* host = web->render_view_host();
+ host->DebugAttach();
+ RenderProcessHost* proc = host->process();
+ return v8::Int32::New(process_util::GetProcId(proc->process()));
+}
+
+v8::Handle<v8::Value> TabNode::Detach(const v8::Arguments& args,
+ WebContents* web) {
+ RenderViewHost* host = web->render_view_host();
+ host->DebugDetach();
+ RenderProcessHost* proc = host->process();
+ return v8::Int32::New(process_util::GetProcId(proc->process()));
+}
+
+v8::Handle<v8::Value> TabNode::Break(const v8::Arguments& args,
+ WebContents* web) {
+ RenderViewHost* host = web->render_view_host();
+ host->DebugBreak();
+ return v8::Undefined();
+}
+
+v8::Handle<v8::Value> TabNode::PropGetter(v8::Handle<v8::String> prop,
+ const v8::AccessorInfo& info) {
+ TabContents* t = GetTab();
+ if (t != NULL) {
+ WebContents* web = t->AsWebContents();
+ if (prop->Equals(v8::String::New("title"))) {
+ std::wstring title = t->GetTitle();
+ std::string title2 = WideToUTF8(title);
+ return v8::String::New(title2.c_str());
+ } else if (web) {
+ if (prop->Equals(v8::String::New("attach"))) {
+ FunctionNode<WebContents>* f =
+ new FunctionNode<WebContents>(TabNode::Attach, web);
+ return f->NewInstance();
+ } else if (prop->Equals(v8::String::New("detach"))) {
+ FunctionNode<WebContents>* f =
+ new FunctionNode<WebContents>(TabNode::Detach, web);
+ return f->NewInstance();
+ } else if (prop->Equals(v8::String::New("sendToDebugger"))) {
+ FunctionNode<WebContents>* f =
+ new FunctionNode<WebContents>(TabNode::SendToDebugger, web);
+ return f->NewInstance();
+ } else if (prop->Equals(v8::String::New("debugBreak"))) {
+ FunctionNode<WebContents>* f =
+ new FunctionNode<WebContents>(TabNode::Break, web);
+ return f->NewInstance();
+ }
+ }
+ }
+ return v8::Undefined();
+}
+
+
+//////////////////////////////////
+
+template<class T>
+v8::Handle<v8::Value> FunctionNode<T>::Function(const v8::Arguments &args) {
+ return function_(args, data_);
+}
diff --git a/chrome/browser/debugger/debugger_node.h b/chrome/browser/debugger/debugger_node.h
new file mode 100644
index 0000000..351d9c7
--- /dev/null
+++ b/chrome/browser/debugger/debugger_node.h
@@ -0,0 +1,261 @@
+// Copyright 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * 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.
+// * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
+// OWNER OR 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.
+
+// Proxy objects for exposing Chrome internals to V8. Adds some convenience
+// methods to simplify properties, indexes and functions, as well as helping
+// with object lifetime bi-directionally.
+
+// TODO: this code is temporary and will be converted to use IDL
+// Also note that it's missing a lot of functionality and isn't correct.
+// For example, objects aren't being cached properly (browser.foo = 1 wouldn't
+// be remembered), and setters aren't implemented to begin with.
+
+#ifndef CHROME_BROWSER_DEBUGGER_DEBUGGER_NODE_H__
+#define CHROME_BROWSER_DEBUGGER_DEBUGGER_NODE_H__
+
+#include "base/basictypes.h"
+#include "base/ref_counted.h"
+#include "chrome/common/notification_service.h"
+#include "v8/public/v8.h"
+
+class Browser;
+class TabContents;
+class DebuggerShell;
+class WebContents;
+
+class DebuggerNode : public NotificationObserver {
+ public:
+ DebuggerNode();
+ virtual ~DebuggerNode();
+
+ // does your object handle array references? (e.g. myobj[0])
+ virtual bool IsCollection() = 0;
+ // does your object work as a function (e.g. myobj())
+ virtual bool IsFunction() = 0;
+ // does your object contain other named properties? (e.g. myobj.foo)
+ virtual bool IsObject() = 0;
+
+ // Is the underlying C++ object valid or not? It's possible for the JS object
+ // to be alive after the underlying C++ object has gone away. In that case,
+ // the DebuggerNode stays around but is marked as invalid.
+ bool IsValid() { return valid_; }
+ virtual void Invalidate() { valid_ = false; }
+
+ // Callback for DebuggerNode subclasses which use the NotificationService to
+ // track object validity.
+ virtual void Observe(NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details);
+ void StopObserving();
+ virtual void StopObserving(NotificationService *service);
+
+ // Index getter callback from V8 for objects where IsCollection is true
+ virtual v8::Handle<v8::Value> IndexGetter(uint32_t index,
+ const v8::AccessorInfo& info);
+ // Index getter callback from V8 for objects where IsObject is true
+ virtual v8::Handle<v8::Value> PropGetter(v8::Handle<v8::String> prop,
+ const v8::AccessorInfo& info);
+ // Functor callback from V8 for objects where IsFunction is true
+ virtual v8::Handle<v8::Value> Function(const v8::Arguments& args);
+
+ // Create a new instance of this JS object.
+ virtual v8::Handle<v8::Value> NewInstance();
+
+ // Generic DebuggerNode named property getter
+ static v8::Handle<v8::Value> NodeGetter(v8::Local<v8::String> prop,
+ const v8::AccessorInfo& info);
+ // Generic DebuggerNode index getter
+ static v8::Handle<v8::Value> NodeIndex(uint32_t index,
+ const v8::AccessorInfo& info);
+ // Generic DebuggerNode functor
+ static v8::Handle<v8::Value> NodeFunc(const v8::Arguments& args);
+
+ protected:
+ void *data_;
+ bool valid_;
+ bool observing_;
+
+ private:
+};
+
+// A wrapper around the proxy to handle two issues:
+// - call virtual methods to stop observing at destruction time
+// - call virtual methods during callbacks from V8 after a static_cast
+// from void*
+// The point here is that we'd like to be able to stick DebuggerNode* objects
+// into V8. To do that, we need to cast them to void*, which means we need
+// this additional layer of wrapper to protect them from the harmful effects
+// of static_cast. Rather than passing in a DebuggerNode*, we instead pass in
+// a DebuggerNodeWrapper*. Since this is what's being referenced by V8, we
+// also handle lifetime issues (RefCounted) in the wrapper.
+class DebuggerNodeWrapper : public base::RefCounted<DebuggerNodeWrapper> {
+ public:
+ DebuggerNodeWrapper(DebuggerNode* node) : node_(node) {}
+ virtual ~DebuggerNodeWrapper() {
+ node_->StopObserving();
+ delete node_;
+ }
+ DebuggerNode* node() { return node_; }
+ private:
+ DebuggerNode* node_;
+};
+
+// top level chrome object implements:
+// * pid() - process id of chrome browser process
+// * browser[] - returns collection of browser objects
+class ChromeNode : public DebuggerNode {
+ public:
+ ChromeNode(DebuggerShell* debugger);
+ virtual ~ChromeNode();
+
+ bool IsCollection() { return false; }
+ bool IsFunction() { return false; }
+ bool IsObject() { return true; }
+
+ virtual v8::Handle<v8::Value> PropGetter(v8::Handle<v8::String> prop,
+ const v8::AccessorInfo& info);
+
+ virtual void StopObserving(NotificationService *service);
+
+ private:
+
+ DebuggerShell* debugger_;
+};
+
+// browser collection, simply returns the n'th browser from BrowserList
+class BrowserListNode : public DebuggerNode {
+ public:
+ bool IsCollection() { return true; }
+ bool IsFunction() { return false; }
+ bool IsObject() { return false; }
+
+ virtual v8::Handle<v8::Value> IndexGetter(uint32_t index,
+ const v8::AccessorInfo& info);
+ virtual void StopObserving(NotificationService *service);
+
+ static BrowserListNode* BrowserList();
+
+ private:
+ BrowserListNode();
+ virtual ~BrowserListNode();
+};
+
+// Wrapper around Browser object. implements:
+// * title - title of the current tab
+// * tab[] - collection of tabs
+class BrowserNode : public DebuggerNode {
+ public:
+ bool IsCollection() { return false; }
+ bool IsFunction() { return false; }
+ bool IsObject() { return true; }
+
+ static BrowserNode* BrowserAtIndex(int index);
+
+ virtual void StopObserving(NotificationService *service);
+
+ virtual v8::Handle<v8::Value> PropGetter(v8::Handle<v8::String> prop,
+ const v8::AccessorInfo& info);
+
+ private:
+ BrowserNode(Browser* b);
+ Browser* GetBrowser();
+ virtual ~BrowserNode();
+};
+
+// tab collection, simply returns the n'th TabContents from Browser
+class TabListNode : public DebuggerNode {
+ public:
+ bool IsCollection() { return true; }
+ bool IsFunction() { return false; }
+ bool IsObject() { return false; }
+
+ virtual void StopObserving(NotificationService *service);
+
+ virtual v8::Handle<v8::Value> IndexGetter(uint32_t index,
+ const v8::AccessorInfo& info);
+ static TabListNode* TabList(Browser* b);
+
+ private:
+ TabListNode(Browser* b);
+ virtual ~TabListNode();
+ Browser* GetBrowser();
+};
+
+// Wrapper around TabContents. Implements:
+// * title - tab title
+// * attach - starts debugging in this tab (currently this just means log msgs)
+// * detach - stops debugging in this tab
+// * eval(xpath, expr), eval(expr) - evaluates JS expr in xpath iframe context
+class TabNode : public DebuggerNode {
+ public:
+ bool IsCollection() { return false; }
+ bool IsFunction() { return false; }
+ bool IsObject() { return true; }
+
+ TabNode(TabContents* c);
+ virtual void StopObserving(NotificationService* service);
+ virtual v8::Handle<v8::Value> PropGetter(v8::Handle<v8::String> prop,
+ const v8::AccessorInfo& info);
+ private:
+
+ static v8::Handle<v8::Value> SendToDebugger(const v8::Arguments& args,
+ WebContents* data);
+ static v8::Handle<v8::Value> Attach(const v8::Arguments& args,
+ WebContents* data);
+ static v8::Handle<v8::Value> Detach(const v8::Arguments& args,
+ WebContents* data);
+ static v8::Handle<v8::Value> Break(const v8::Arguments& args,
+ WebContents* data);
+
+ virtual ~TabNode();
+ TabContents* GetTab();
+};
+
+template<class T>
+class FunctionNode : public DebuggerNode {
+ public:
+ bool IsCollection() { return false; }
+ bool IsFunction() { return true; }
+ bool IsObject() { return false; }
+
+ typedef v8::Handle<v8::Value> (*Callback)(const v8::Arguments& args, T* data);
+
+ FunctionNode(Callback f, T* data) :
+ function_(f), data_(data) {};
+
+private:
+ // Functor callback from V8 for objects where IsFunction is true
+ virtual v8::Handle<v8::Value> Function(const v8::Arguments& args);
+
+ Callback function_;
+ T* data_;
+};
+
+
+#endif // CHROME_BROWSER_DEBUGGER_DEBUGGER_NODE_H__
diff --git a/chrome/browser/debugger/debugger_shell.cc b/chrome/browser/debugger/debugger_shell.cc
new file mode 100644
index 0000000..0679292
--- /dev/null
+++ b/chrome/browser/debugger/debugger_shell.cc
@@ -0,0 +1,419 @@
+// Copyright 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * 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.
+// * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
+// OWNER OR 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 "chrome/browser/debugger/debugger_shell.h"
+
+#include "base/file_util.h"
+#include "base/path_service.h"
+#include "base/string_util.h"
+#include "base/thread.h"
+#include "chrome/browser/browser.h"
+#include "chrome/browser/browser_list.h"
+#include "chrome/browser/browser_process.h"
+#include "chrome/browser/browser_resources.h"
+#include "chrome/browser/render_process_host.h"
+#include "chrome/browser/tab_contents.h"
+#include "chrome/browser/debugger/debugger_io.h"
+#include "chrome/browser/debugger/debugger_node.h"
+#include "chrome/common/chrome_paths.h"
+#include "chrome/common/resource_bundle.h"
+#include "v8/public/v8.h"
+
+DebuggerShell::DebuggerShell(DebuggerInputOutput* io) : io_(io),
+ debugger_ready_(true) {
+}
+
+DebuggerShell::~DebuggerShell() {
+ io_->Stop();
+ io_ = NULL;
+
+ v8::HandleScope scope;
+ SubshellFunction("exit", 0, NULL);
+ v8::V8::RemoveMessageListeners(&DelegateMessageListener);
+ v8_this_.Dispose();
+ v8_context_.Dispose();
+ shell_.Dispose();
+}
+
+void DebuggerShell::Start() {
+ io_->Start(this);
+
+ v8::HandleScope scope;
+
+ v8_this_ = v8::Persistent<v8::External>::New(v8::External::New(this));
+
+ v8::V8::AddMessageListener(&DelegateMessageListener, v8_this_);
+
+ v8::Local<v8::ObjectTemplate> global_template = v8::ObjectTemplate::New();
+
+ // shell function
+ v8::Local<v8::FunctionTemplate> shell_template =
+ v8::FunctionTemplate::New(&DelegateSubshell, v8_this_);
+ global_template->Set(v8::String::New("shell"), shell_template);
+
+ // print function
+ v8::Local<v8::FunctionTemplate> print_template =
+ v8::FunctionTemplate::New(&DelegatePrint, v8_this_);
+ global_template->Set(v8::String::New("print"), print_template);
+
+ // source function
+ v8::Local<v8::FunctionTemplate> source_template =
+ v8::FunctionTemplate::New(&DelegateSource, v8_this_);
+ global_template->Set(v8::String::New("source"), source_template);
+
+ v8_context_ = v8::Context::New(NULL, global_template);
+ v8::Context::Scope ctx(v8_context_);
+
+ // This doesn't really leak. It's wrapped by the NewInstance() return value.
+ ChromeNode* chrome = new ChromeNode(this);
+ v8_context_->Global()->Set(v8::String::New("chrome"),
+ chrome->NewInstance());
+
+ ResourceBundle& rb = ResourceBundle::GetSharedInstance();
+ const std::string& debugger_shell_js =
+ rb.GetDataResource(IDR_DEBUGGER_SHELL_JS);
+ CompileAndRun(debugger_shell_js, "chrome.dll/debugger_shell.js");
+}
+
+void DebuggerShell::HandleWeakReference(v8::Persistent<v8::Object> obj, void* data) {
+ DebuggerNodeWrapper* node = static_cast<DebuggerNodeWrapper*>(data);
+ node->Release();
+}
+
+v8::Handle<v8::Value> DebuggerShell::SetDebuggerReady(const v8::Arguments& args,
+ DebuggerShell* debugger) {
+ if (args[0]->IsBoolean()) {
+ bool flag = args[0]->BooleanValue();
+ debugger->debugger_ready_ = flag;
+ debugger->GetIo()->SetDebuggerReady(flag);
+ }
+ return v8::Undefined();
+}
+
+v8::Handle<v8::Value> DebuggerShell::SetDebuggerBreak(const v8::Arguments& args,
+ DebuggerShell* debugger) {
+ if (args[0]->IsBoolean()) {
+ bool flag = args[0]->BooleanValue();
+ debugger->GetIo()->SetDebuggerBreak(flag);
+ }
+ return v8::Undefined();
+}
+
+DebuggerInputOutput* DebuggerShell::GetIo() {
+ return io_.get();
+}
+
+v8::Handle<v8::Value> DebuggerShell::DelegateSubshell(const v8::Arguments& args) {
+ DebuggerShell* debugger =
+ static_cast<DebuggerShell*>(v8::External::Cast(*args.Data())->Value());
+ return debugger->Subshell(args);
+}
+
+v8::Handle<v8::Value> DebuggerShell::Subshell(const v8::Arguments& args) {
+ if (args.Length() != 1) {
+ return v8::Undefined();
+ }
+ if (!shell_.IsEmpty()) {
+ shell_.Dispose();
+ shell_.Clear();
+ v8_context_->Global()->Delete(v8::String::New("shell_"));
+ }
+ if (args[0]->IsFunction()) {
+ v8::Handle<v8::Function> func = v8::Handle<v8::Function>::Cast(args[0]);
+ v8::Local<v8::Object> obj = func->NewInstance();
+ if (!obj->IsUndefined()) {
+ shell_= v8::Persistent<v8::Object>::New(obj);
+ v8_context_->Global()->Set(v8::String::New("shell_"), shell_);
+ }
+ } else if (args[0]->IsObject()) {
+ shell_= v8::Persistent<v8::Object>::New(v8::Local<v8::Object>::Cast(args[0]));
+ v8_context_->Global()->Set(v8::String::New("shell_"), shell_);
+ }
+ return v8::Undefined();
+}
+
+v8::Handle<v8::Value> DebuggerShell::SubshellFunction(const char* func,
+ int argc,
+ v8::Handle<v8::Value>* argv) {
+ if (!shell_.IsEmpty()) {
+ v8::Context::Scope scope(v8_context_);
+ v8::Local<v8::Value> function = shell_->Get(v8::String::New(func));
+ if (function->IsFunction()) {
+ v8::Local<v8::Value> ret =
+ v8::Function::Cast(*function)->Call(shell_, argc, argv);
+ return ret;
+ }
+ }
+ return v8::Undefined();
+}
+
+v8::Handle<v8::Value> DebuggerShell::DelegatePrint(const v8::Arguments& args) {
+ DebuggerShell* debugger =
+ static_cast<DebuggerShell*>(v8::External::Cast(*args.Data())->Value());
+ return debugger->Print(args);
+}
+
+v8::Handle<v8::Value> DebuggerShell::Print(const v8::Arguments& args) {
+ int len = args.Length();
+ for (int i = 0; i < len; i++) {
+ PrintObject(args[i]);
+ }
+ return v8::Undefined();
+}
+
+v8::Handle<v8::Value> DebuggerShell::DelegateSource(const v8::Arguments& args) {
+ DebuggerShell* debugger =
+ static_cast<DebuggerShell*>(v8::External::Cast(*args.Data())->Value());
+ std::wstring path;
+ if (args.Length() == 0) {
+ debugger->LoadUserConfig();
+ } else {
+ ObjectToString(args[0], &path);
+ bool ret = debugger->LoadFile(path);
+ if (!ret) {
+ return v8::String::New("failed to load");
+ }
+ }
+ return v8::Undefined();
+}
+
+void DebuggerShell::DelegateMessageListener(v8::Handle<v8::Message> message,
+ v8::Handle<v8::Value> data) {
+ DCHECK(!data.IsEmpty());
+ DebuggerShell* debugger =
+ static_cast<DebuggerShell*>(v8::External::Cast(*data)->Value());
+ debugger->MessageListener(message);
+}
+
+void DebuggerShell::MessageListener(v8::Handle<v8::Message> message) {
+ v8::HandleScope scope;
+ v8::Local<v8::String> msg_str = message->Get();
+ PrintObject(msg_str);
+
+ v8::Handle<v8::Value> data = message->GetScriptResourceName();
+ if (!data.IsEmpty() && !data->IsUndefined()) {
+ std::wstring out;
+ ObjectToString(data, &out);
+ int line_number = message->GetLineNumber();
+ if (line_number >= 0)
+ out += StringPrintf(L":%d", line_number);
+ PrintLine(out);
+ data = message->GetSourceLine();
+ if (!data->IsUndefined()) {
+ ObjectToString(data, &out);
+ PrintLine(out);
+ }
+ }
+}
+
+void DebuggerShell::Debug(TabContents* tab) {
+ v8::HandleScope outer;
+ v8::Context::Scope scope(v8_context_);
+
+ v8::Local<v8::Object> global = v8_context_->Global();
+ v8::Local<v8::Value> function = global->Get(v8::String::New("debug"));
+ if (function->IsFunction()) {
+ TabNode* node = new TabNode(tab);
+ v8::Handle<v8::Value> argv[] = {node->NewInstance()};
+ PrintObject(v8::Function::Cast(*function)->Call(global, 1, argv));
+ }
+}
+
+void DebuggerShell::DebugMessage(const std::wstring& msg) {
+ v8::HandleScope scope;
+
+ if (msg.length()) {
+ if ((msg[0] == L'{' || msg[0] == L'[' || msg[0] == L'(') && (!shell_.IsEmpty())) {
+ // v8's wide String constructor requires uint16 rather than wchar
+ const uint16* data = reinterpret_cast<const uint16* >(msg.c_str());
+ v8::Handle<v8::Value> argv[] = {v8::String::New(data)};
+ PrintObject(SubshellFunction("response", 1, argv));
+ PrintPrompt();
+ } else {
+ if (msg[msg.length() - 1] == L'\n')
+ PrintString(msg);
+ else
+ PrintLine(msg);
+ }
+ }
+}
+
+void DebuggerShell::OnDebugDisconnect() {
+ v8::HandleScope scope;
+ SubshellFunction("on_disconnect", 0, NULL);
+}
+
+void DebuggerShell::ObjectToString(v8::Handle<v8::Value> result, std::wstring* str) {
+ v8::HandleScope scope;
+ if (!result.IsEmpty() && !result->IsUndefined()) {
+ v8::Local<v8::String> str_obj = result->ToString();
+ if (!str_obj.IsEmpty()) {
+ int length = str_obj->Length();
+ wchar_t* buf = new wchar_t[length + 1];
+ int size = str_obj->Write(reinterpret_cast<uint16_t*>(buf));
+ str->clear();
+ str->append(buf, size);
+ delete[] buf;
+ }
+ }
+}
+
+void DebuggerShell::ObjectToString(v8::Handle<v8::Value> result, std::string* str) {
+ v8::HandleScope scope;
+ if (!result.IsEmpty() && !result->IsUndefined()) {
+ v8::Local<v8::String> str_obj = result->ToString();
+ if (!str_obj.IsEmpty()) {
+ int length = str_obj->Length();
+ char* buf = new char[length + 1];
+ str_obj->WriteAscii(buf);
+ str->clear();
+ str->append(buf);
+ delete[] buf;
+ }
+ }
+}
+
+void DebuggerShell::PrintObject(v8::Handle<v8::Value> result, bool crlf) {
+ if (!result.IsEmpty() && !result->IsUndefined()) {
+ std::wstring out;
+ ObjectToString(result, &out);
+ if (crlf) {
+ PrintLine(out);
+ } else if (out.length()) {
+ PrintString(out);
+ }
+ }
+}
+
+void DebuggerShell::PrintString(const std::wstring& out) {
+ if (io_)
+ io_->Output(out);
+}
+
+void DebuggerShell::PrintLine(const std::wstring& out) {
+ if (io_)
+ io_->OutputLine(out);
+}
+
+void DebuggerShell::PrintString(const std::string& out) {
+ if (io_)
+ io_->Output(out);
+}
+
+void DebuggerShell::PrintLine(const std::string& out) {
+ if (io_)
+ io_->OutputLine(out);
+}
+
+void DebuggerShell::PrintPrompt() {
+ std::wstring out = L"Chrome> ";
+ if (!shell_.IsEmpty()) {
+ if (!debugger_ready_)
+ return;
+ v8::HandleScope outer;
+ v8::Handle<v8::Value> result = CompileAndRun("shell_.prompt()");
+ if (!result.IsEmpty() && !result->IsUndefined()) {
+ ObjectToString(result, &out);
+ }
+ }
+ if (io_)
+ io_->OutputPrompt(out);
+}
+
+void DebuggerShell::ProcessCommand(const std::string& data) {
+ v8::HandleScope outer;
+ v8::Context::Scope scope(v8_context_);
+ if (!shell_.IsEmpty() && data.substr(0, 7) != "source(") {
+ if (data == "exit") {
+ PrintObject(SubshellFunction("exit", 0, NULL));
+ v8_context_->Global()->Delete(v8::String::New("shell_"));
+ shell_.Dispose();
+ shell_.Clear();
+ } else {
+ v8::Handle<v8::Value> argv[] = {v8::String::New(data.c_str())};
+ PrintObject(SubshellFunction("command", 1, argv));
+ }
+ } else if (data.length()) {
+ v8::Handle<v8::Value> result = CompileAndRun(data);
+ PrintObject(result);
+ }
+ PrintPrompt();
+}
+
+bool DebuggerShell::LoadFile(const std::wstring& file) {
+ if (file_util::PathExists(file)) {
+ std::string contents;
+ if (file_util::ReadFileToString(file, &contents)) {
+ std::string afile = WideToUTF8(file);
+ CompileAndRun(contents, afile);
+ return true;
+ }
+ }
+ return false;
+}
+
+void DebuggerShell::LoadUserConfig() {
+ std::wstring path;
+ PathService::Get(chrome::DIR_USER_DATA, &path);
+ file_util::AppendToPath(&path, L"debugger_custom.js");
+ LoadFile(path);
+}
+
+void DebuggerShell::DidConnect() {
+ v8::HandleScope outer;
+ v8::Context::Scope scope(v8_context_);
+
+ LoadUserConfig();
+
+ PrintPrompt();
+}
+
+v8::Handle<v8::Value> DebuggerShell::CompileAndRun(const std::string& str,
+ const std::string& filename) {
+ v8::Context::Scope scope(v8_context_);
+ v8::Handle<v8::String> scriptname;
+ if (filename.length() > 0) {
+ scriptname = v8::String::New(filename.c_str());
+ } else {
+ scriptname = v8::String::New("");
+ }
+ v8::ScriptOrigin origin =
+ v8::ScriptOrigin(scriptname);
+ v8::Local<v8::Script> code =
+ v8::Script::Compile(v8::String::New(str.c_str()), &origin);
+ if (!code.IsEmpty()) {
+ v8::Local<v8::Value> result = code->Run();
+ if (!result.IsEmpty()) {
+ return result;
+ }
+ }
+ return v8::Undefined();
+}
+
+
diff --git a/chrome/browser/debugger/debugger_shell.h b/chrome/browser/debugger/debugger_shell.h
new file mode 100644
index 0000000..d7b18b4
--- /dev/null
+++ b/chrome/browser/debugger/debugger_shell.h
@@ -0,0 +1,150 @@
+// Copyright 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * 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.
+// * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
+// OWNER OR 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.
+
+// A browser-side server debugger built with V8 providing a scriptable
+// interface to a JavaScript debugger as well as browser automation.
+// Supports multiple user interfaces including a command-line debugger
+// accessible from a Chrome window or telnet.
+
+// NOTE: DON'T include this file outside of the debugger project. In order to
+// build in the KJS solution, you should instead use debugger_wrapper.h.
+// If DebuggerWraper doesn't expose the interface you need, extend it to do so.
+// See comments in debugger_wrapper.h for more details.
+
+#ifndef CHROME_BROWSER_DEBUGGER_DEBUGGER_SHELL_H__
+#define CHROME_BROWSER_DEBUGGER_DEBUGGER_SHELL_H__
+
+#include "base/basictypes.h"
+#include "base/ref_counted.h"
+
+#ifdef CHROME_DEBUGGER_DISABLED
+class DebuggerShell : public base::RefCountedThreadSafe<DebuggerShell> {
+ public:
+ DebuggerShell() {
+ LOG(ERROR) << "Debug Debugger not enabled for KJS";
+ }
+ virtual ~DebuggerShell() {}
+ void Start() {}
+ void DebugMessage(const std::wstring& msg) {}
+ void OnDebugDisconnect() {}
+};
+#else
+#include "debugger_io.h"
+#include "debugger_node.h"
+#include "v8/public/v8.h"
+
+class DebuggerInputOutput;
+class MessageLoop;
+class TabContents;
+
+class DebuggerShell : public base::RefCountedThreadSafe<DebuggerShell> {
+ public:
+ DebuggerShell(DebuggerInputOutput *io);
+ virtual ~DebuggerShell();
+
+ // call before other methods
+ void Start();
+
+ // Start debugging the specified tab
+ void Debug(TabContents* tab);
+
+ // A message from the V8 debugger in the renderer being debugged via
+ // RenderViewHost
+ void DebugMessage(const std::wstring& msg);
+
+ // The renderer we're attached to is gone.
+ void OnDebugDisconnect();
+
+ // SocketInputOutput callback methods
+ void DidConnect();
+ void ProcessCommand(const std::string& data);
+
+ static v8::Handle<v8::Value> SetDebuggerReady(const v8::Arguments& args,
+ DebuggerShell* debugger);
+ static v8::Handle<v8::Value> SetDebuggerBreak(const v8::Arguments& args,
+ DebuggerShell* debugger);
+
+ // For C++ objects which are tied to JS objects (e.g. DebuggerNode),
+ // we need to know when the underlying JS objects have been collected
+ // so that we can clean up the C++ object as well.
+ static void HandleWeakReference(v8::Persistent<v8::Object> obj, void* data);
+
+ // populates str with the ascii string value of result
+ static void ObjectToString(v8::Handle<v8::Value> result, std::string* str);
+ static void ObjectToString(v8::Handle<v8::Value> result, std::wstring* str);
+
+ DebuggerInputOutput* GetIo();
+
+ private:
+ void PrintObject(v8::Handle<v8::Value> result, bool crlf = true);
+ void PrintLine(const std::wstring& out);
+ void PrintString(const std::wstring& out);
+ void PrintLine(const std::string& out);
+ void PrintString(const std::string& out);
+ void PrintPrompt();
+ v8::Handle<v8::Value> CompileAndRun(const std::string& str,
+ const std::string& filename = "");
+
+ bool LoadFile(const std::wstring& file);
+ void LoadUserConfig();
+
+ // Log/error messages from V8
+ static void DelegateMessageListener(v8::Handle<v8::Message> message,
+ v8::Handle<v8::Value> data);
+
+ void MessageListener(v8::Handle<v8::Message> message);
+
+ // global debugger() function designed to allow command-line processing by
+ // javascript code rather than by this object.
+ static v8::Handle<v8::Value> DelegateSubshell(const v8::Arguments& args);
+ v8::Handle<v8::Value> Subshell(const v8::Arguments& args);
+ v8::Handle<v8::Value> SubshellFunction(const char* func,
+ int argc,
+ v8::Handle<v8::Value>* argv);
+
+ // print message to the debugger
+ static v8::Handle<v8::Value> DelegatePrint(const v8::Arguments& args);
+ v8::Handle<v8::Value> Print(const v8::Arguments& args);
+
+ // load and execute javascript file
+ static v8::Handle<v8::Value> DelegateSource(const v8::Arguments& args);
+
+ v8::Persistent<v8::Context> v8_context_;
+ v8::Persistent<v8::External> v8_this_;
+ v8::Persistent<v8::Object> shell_;
+ scoped_refptr<DebuggerInputOutput> io_;
+
+ // If the debugger is ready to process another command or is busy.
+ bool debugger_ready_;
+
+ DISALLOW_EVIL_CONSTRUCTORS(DebuggerShell);
+};
+
+#endif // else CHROME_DEBUGGER_DISABLED
+#endif // CHROME_BROWSER_DEBUGGER_DEBUGGER_SHELL_H__
diff --git a/chrome/browser/debugger/debugger_view.cc b/chrome/browser/debugger/debugger_view.cc
new file mode 100644
index 0000000..14b1733
--- /dev/null
+++ b/chrome/browser/debugger/debugger_view.cc
@@ -0,0 +1,135 @@
+// Copyright 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * 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.
+// * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
+// OWNER OR 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 "chrome/browser/debugger/debugger_window.h"
+
+#include "base/logging.h"
+#include "base/string_util.h"
+#include "base/json_writer.h"
+#include "base/values.h"
+#include "chrome/browser/browser_list.h"
+#include "chrome/browser/browser_process.h"
+#include "chrome/browser/render_view_host.h"
+#include "chrome/browser/debugger/debugger_view.h"
+#include "chrome/browser/standard_layout.h"
+#include "chrome/browser/tab_contents.h"
+#include "chrome/browser/tab_contents_container_view.h"
+#include "chrome/browser/view_ids.h"
+#include "chrome/browser/web_contents.h"
+#include "chrome/common/gfx/chrome_canvas.h"
+#include "chrome/common/resource_bundle.h"
+#include "chrome/views/grid_layout.h"
+#include "chrome/views/native_scroll_bar.h"
+#include "chrome/views/scroll_view.h"
+#include "chrome/views/text_field.h"
+#include "chrome/views/view.h"
+
+
+DebuggerView::DebuggerView(ChromeViews::TextField::Controller* controller) {
+ command_text_ = new ChromeViews::TextField();
+ command_text_->SetFont(font_);
+ command_text_->SetController(controller);
+ AddChildView(command_text_);
+ web_container_ = new TabContentsContainerView();
+ AddChildView(web_container_);
+}
+
+DebuggerView::~DebuggerView() {
+}
+
+void DebuggerView::GetPreferredSize(CSize* out) {
+ out->cx = 700;
+ out->cy = 400;
+}
+
+void DebuggerView::Layout() {
+ int cmd_height = 20;
+ web_container_->SetBounds(0, 0, GetWidth(), GetHeight() - cmd_height);
+ command_text_->SetBounds(0, GetHeight() - cmd_height, GetWidth(), cmd_height);
+}
+
+void DebuggerView::Paint(ChromeCanvas* canvas) {
+#ifndef NDEBUG
+ SkPaint paint;
+ canvas->FillRectInt(SK_ColorCYAN, bounds_.left, bounds_.top,
+ bounds_.Width(), bounds_.Height());
+#endif
+}
+
+void DebuggerView::Output(const std::string& out) {
+ Output(UTF8ToWide(out));
+}
+
+void DebuggerView::Output(const std::wstring& out) {
+ if (web_contents_->is_loading()) {
+ Sleep(100);
+ }
+ Value* str_value = Value::CreateStringValue(out);
+ std::string json;
+ JSONWriter::Write(str_value, false, &json);
+ const std::string js =
+ StringPrintf("javascript:void(appendText(%s))", json.c_str());
+ web_contents_->render_view_host()->ExecuteJavascriptInWebFrame(L"",
+ UTF8ToWide(js));
+}
+
+void DebuggerView::OnInit() {
+ // We can't create the WebContents until we've actually been put into a real
+ // view hierarchy somewhere.
+ Profile* profile = BrowserList::GetLastActive()->profile();
+ TabContents* tc = TabContents::CreateWithType(TAB_CONTENTS_WEB,
+ ::GetDesktopWindow(), profile, NULL);
+ web_contents_ = tc->AsWebContents();
+ web_contents_->SetupController(profile);
+ web_contents_->set_delegate(this);
+ web_container_->SetTabContents(web_contents_);
+
+ // TODO(erikkay): move this into chrome-tools scheme when that gets added.
+ // This will allow us to do some spiffier things as well as making this
+ // HTML easier to maintain.
+ GURL contents("data:text/html,<html><head><script>function appendText(txt){var output = document.getElementById('output'); output.appendChild(document.createTextNode(txt)); output.appendChild(document.createElement('br')); document.body.scrollTop = document.body.scrollHeight;};</script><style type='text/css'>body{margin:0px;padding:0px;}#output { font-family: monospace; background-} #outer { width: 100%; height: 100%; white-space: pre-wrap;}</style></head><body><table id='outer'><tr><td valign='bottom' id='output'>JavaScript Debugger<br/></td></tr></table></body></html>");
+ web_contents_->controller()->LoadURL(contents, PageTransition::START_PAGE);
+}
+
+void DebuggerView::OnShow() {
+ command_text_->RequestFocus();
+}
+
+void DebuggerView::OnClose() {
+ web_container_->SetTabContents(NULL);
+
+ web_contents_->CloseContents();
+}
+
+void DebuggerView::OpenURLFromTab(TabContents* source,
+ const GURL& url,
+ WindowOpenDisposition disposition,
+ PageTransition::Type transition) {
+ BrowserList::GetLastActive()->OpenURL(url, disposition, transition);
+}
diff --git a/chrome/browser/debugger/debugger_view.h b/chrome/browser/debugger/debugger_view.h
new file mode 100644
index 0000000..a4ae560
--- /dev/null
+++ b/chrome/browser/debugger/debugger_view.h
@@ -0,0 +1,110 @@
+// Copyright 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * 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.
+// * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
+// OWNER OR 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.
+
+// Simple UI for the command-line V8 debugger consisting of a text field for
+// entry and an output view consisting of (potentially wrapped) lines of text.
+
+// TODO(erikkay): investigate replacing this with a DHTML interface
+
+#ifndef CHROME_BROWSER_DEBUGGER_DEBUGGER_VIEW_H__
+#define CHROME_BROWSER_DEBUGGER_DEBUGGER_VIEW_H__
+
+#include "base/gfx/size.h"
+#include "chrome/browser/tab_contents_delegate.h"
+#include "chrome/views/view.h"
+#include "chrome/views/text_field.h"
+
+class DebuggerView;
+class DebuggerWindow;
+class TabContentsContainerView;
+class WebContents;
+
+class DebuggerView : public ChromeViews::View,
+ public TabContentsDelegate {
+ public:
+ DebuggerView(ChromeViews::TextField::Controller* controller);
+ virtual ~DebuggerView();
+
+ // Output a line of text to the debugger view
+ void Output(const std::string& out);
+ void Output(const std::wstring& out);
+
+ void OnInit();
+
+ // Called when the window is shown.
+ void OnShow();
+
+ // Called when the window is being closed.
+ void OnClose();
+
+ // Overridden from ChromeViews::View:
+ virtual std::string GetClassName() const {
+ return "DebuggerView";
+ }
+ virtual void GetPreferredSize(CSize* out);
+ virtual void Layout();
+ virtual void Paint(ChromeCanvas* canvas);
+
+ // Overridden from TabContentsDelegate:
+ virtual void OpenURLFromTab(TabContents* source,
+ const GURL& url,
+ WindowOpenDisposition disposition,
+ PageTransition::Type transition);
+ virtual void NavigationStateChanged(const TabContents* source,
+ unsigned changed_flags) {}
+ virtual void ReplaceContents(TabContents* source,
+ TabContents* new_contents) {}
+ virtual void AddNewContents(TabContents* source,
+ TabContents* new_contents,
+ WindowOpenDisposition disposition,
+ const gfx::Rect& initial_pos,
+ bool user_gesture) {}
+ virtual void ActivateContents(TabContents* contents) {}
+ virtual void LoadingStateChanged(TabContents* source) {}
+ virtual void CloseContents(TabContents* source) {}
+ virtual void MoveContents(TabContents* source, const gfx::Rect& pos) {}
+ virtual bool IsPopup(TabContents* source) { return false; }
+ virtual void ToolbarSizeChanged(TabContents* source, bool is_animating) {}
+ virtual void URLStarredChanged(TabContents* source, bool) {}
+ virtual void UpdateTargetURL(TabContents* source, const GURL& url) {}
+ virtual bool CanBlur() const { return false; }
+
+ private:
+
+ ChromeViews::TextField* command_text_;
+ DebuggerWindow* window_;
+ ChromeFont font_;
+ WebContents* web_contents_;
+ TabContentsContainerView* web_container_;
+
+ DISALLOW_EVIL_CONSTRUCTORS(DebuggerView);
+};
+
+
+#endif // CHROME_BROWSER_DEBUGGER_DEBUGGER_VIEW_H__ \ No newline at end of file
diff --git a/chrome/browser/debugger/debugger_window.cc b/chrome/browser/debugger/debugger_window.cc
new file mode 100644
index 0000000..ee21dd0
--- /dev/null
+++ b/chrome/browser/debugger/debugger_window.cc
@@ -0,0 +1,199 @@
+// Copyright 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * 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.
+// * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
+// OWNER OR 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 "base/string_util.h"
+#include "chrome/browser/browser_process.h"
+#include "chrome/browser/constrained_window.h"
+#include "chrome/browser/debugger/debugger_shell.h"
+#include "chrome/browser/debugger/debugger_view.h"
+#include "chrome/browser/debugger/debugger_window.h"
+#include "chrome/browser/debugger/debugger_wrapper.h"
+#include "chrome/browser/tab_contents.h"
+#include "chrome/common/l10n_util.h"
+#include "generated_resources.h"
+
+DebuggerWindow::DebuggerWindow() : window_(NULL),
+ view_(NULL),
+ debugger_ready_(true),
+ debugger_break_(false) {
+}
+
+DebuggerWindow::~DebuggerWindow() {
+}
+
+bool DebuggerWindow::DoesDebuggerExist() {
+ DebuggerWrapper* wrapper = g_browser_process->debugger_wrapper();
+ if (!wrapper)
+ return false;
+ return wrapper->GetDebugger() != NULL;
+}
+
+void DebuggerWindow::Show(TabContents* tab) {
+#ifndef CHROME_DEBUGGER_DISABLED
+ if (window_) {
+ window_->Show();
+ view_->OnShow();
+ return;
+ }
+ view_ = new DebuggerView(this);
+ window_ = ChromeViews::Window::CreateChromeWindow(
+ NULL, gfx::Rect(), view_, this);
+ view_->OnInit();
+ window_->Show();
+ view_->OnShow();
+ debugger_ready_ = true;
+ debugger_break_ = false;
+ DebuggerShell* debugger = new DebuggerShell(this);
+ DebuggerWrapper* wrapper = g_browser_process->debugger_wrapper();
+ if (!wrapper) {
+ g_browser_process->InitDebuggerWrapper(0);
+ wrapper = g_browser_process->debugger_wrapper();
+ }
+ wrapper->SetDebugger(debugger);
+ debugger->Start();
+ // TODO(erikkay): this method name should really change, or maybe even
+ // go away / merge into start. It's a legacy from the telnet code.
+ debugger->DidConnect();
+ debugger->Debug(tab);
+#endif
+}
+
+
+///////////////////////////////////////////////////////////////////
+// DebuggerInputOutput overrides
+
+void DebuggerWindow::Output(const std::wstring &out) {
+#ifndef CHROME_DEBUGGER_DISABLED
+ if (view_)
+ view_->Output(out);
+#endif
+}
+
+void DebuggerWindow::OutputLine(const std::wstring &out) {
+#ifndef CHROME_DEBUGGER_DISABLED
+ if (view_)
+ view_->Output(out);
+#endif
+}
+
+void DebuggerWindow::OutputPrompt(const std::wstring& prompt) {
+}
+
+void DebuggerWindow::Output(const std::string &out) {
+#ifndef CHROME_DEBUGGER_DISABLED
+ if (view_)
+ view_->Output(out);
+#endif
+}
+
+void DebuggerWindow::OutputLine(const std::string &out) {
+#ifndef CHROME_DEBUGGER_DISABLED
+ if (view_)
+ view_->Output(out);
+#endif
+}
+
+void DebuggerWindow::OutputPrompt(const std::string& prompt) {
+}
+
+void DebuggerWindow::Start(DebuggerShell* debugger) {
+#ifndef CHROME_DEBUGGER_DISABLED
+ DebuggerInputOutput::Start(debugger);
+#endif
+}
+
+void DebuggerWindow::SetDebuggerReady(bool ready) {
+#ifndef CHROME_DEBUGGER_DISABLED
+ if (debugger_ready_ != ready) {
+ debugger_ready_ = ready;
+ window_->UpdateWindowTitle();
+ }
+#endif
+}
+
+void DebuggerWindow::SetDebuggerBreak(bool brk) {
+#ifndef CHROME_DEBUGGER_DISABLED
+ if (debugger_break_ != brk) {
+ debugger_break_ = brk;
+ window_->UpdateWindowTitle();
+ if (brk)
+ window_->Activate();
+ }
+#endif
+}
+
+///////////////////////////////////////////////////////////////////
+// ChromeViews::WindowDelegate methods
+
+std::wstring DebuggerWindow::GetWindowTitle() const {
+ if (!debugger_ready_) {
+ return l10n_util::GetString(IDS_DEBUGGER_TITLE_BUSY);
+ } else if (debugger_break_) {
+ return l10n_util::GetString(IDS_DEBUGGER_TITLE_BREAK);
+ } else {
+ return l10n_util::GetString(IDS_DEBUGGER_TITLE_RUNNING);
+ }
+}
+
+void DebuggerWindow::WindowClosing() {
+#ifndef CHROME_DEBUGGER_DISABLED
+ view_->OnClose();
+#endif
+ debugger_ = NULL;
+ window_ = NULL;
+ view_ = NULL;
+ DebuggerWrapper* wrapper = g_browser_process->debugger_wrapper();
+ wrapper->SetDebugger(NULL);
+}
+
+bool DebuggerWindow::CanResize() const {
+ return true;
+}
+
+///////////////////////////////////////////////////////////////////
+// Overridden from ChromeViews::TextField::Controller:
+
+void DebuggerWindow::ContentsChanged(ChromeViews::TextField* sender,
+ const std::wstring& new_contents) {
+ //
+}
+
+void DebuggerWindow::HandleKeystroke(ChromeViews::TextField* sender, UINT message,
+ TCHAR key, UINT repeat_count, UINT flags) {
+#ifndef CHROME_DEBUGGER_DISABLED
+ if (key == VK_RETURN) {
+ std::wstring txt = sender->GetText();
+ if (txt.length()) {
+ view_->Output(L"$ " + txt);
+ debugger_->ProcessCommand(WideToUTF8(txt));
+ sender->SetText(L"");
+ }
+ }
+#endif
+}
diff --git a/chrome/browser/debugger/debugger_window.h b/chrome/browser/debugger/debugger_window.h
new file mode 100644
index 0000000..552cedc
--- /dev/null
+++ b/chrome/browser/debugger/debugger_window.h
@@ -0,0 +1,86 @@
+// Copyright 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * 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.
+// * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
+// OWNER OR 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.
+
+#ifndef CHROME_BROWSER_DEBUGGER_DEBUGGER_WINDOW_H__
+#define CHROME_BROWSER_DEBUGGER_DEBUGGER_WINDOW_H__
+
+#include "chrome/browser/debugger/debugger_io.h"
+#include "chrome/views/text_field.h"
+#include "chrome/views/window.h"
+#include "chrome/views/window_delegate.h"
+
+class DebuggerView;
+class TabContents;
+
+class DebuggerWindow : public DebuggerInputOutput,
+ public ChromeViews::WindowDelegate,
+ public ChromeViews::TextField::Controller {
+ public:
+ DebuggerWindow();
+ virtual ~DebuggerWindow();
+
+ // returns true if a debugger has already been instantiated
+ static bool DoesDebuggerExist();
+
+ // Show the window
+ void Show(TabContents* tab);
+
+ // overrides from DebuggerInputOutput
+ virtual void Output(const std::wstring& out);
+ virtual void OutputLine(const std::wstring& out);
+ virtual void OutputPrompt(const std::wstring& prompt);
+ virtual void Output(const std::string& out);
+ virtual void OutputLine(const std::string& out);
+ virtual void OutputPrompt(const std::string& prompt);
+ virtual void Start(DebuggerShell* debugger);
+ virtual void SetDebuggerReady(bool ready);
+ virtual void SetDebuggerBreak(bool brk);
+
+ // ChromeViews::WindowDelegate methods:
+ virtual std::wstring GetWindowTitle() const;
+ virtual void WindowClosing();
+ virtual bool CanResize() const;
+
+ // Overridden from ChromeViews::TextField::Controller:
+ virtual void ContentsChanged(ChromeViews::TextField* sender,
+ const std::wstring& new_contents);
+ virtual void HandleKeystroke(ChromeViews::TextField* sender, UINT message,
+ TCHAR key, UINT repeat_count, UINT flags);
+
+ private:
+ ChromeViews::Window* window_;
+ DebuggerView* view_;
+
+ bool debugger_ready_;
+ bool debugger_break_;
+
+ DISALLOW_EVIL_CONSTRUCTORS(DebuggerWindow);
+};
+
+#endif // CHROME_BROWSER_DEBUGGER_DEBUGGER_WINDOW_H__
diff --git a/chrome/browser/debugger/debugger_wrapper.cc b/chrome/browser/debugger/debugger_wrapper.cc
new file mode 100644
index 0000000..0643a83
--- /dev/null
+++ b/chrome/browser/debugger/debugger_wrapper.cc
@@ -0,0 +1,63 @@
+// Copyright 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * 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.
+// * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
+// OWNER OR 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 "debugger_wrapper.h"
+#include "debugger_shell.h"
+#include "debugger_io_socket.h"
+
+DebuggerWrapper::DebuggerWrapper(int port) {
+#ifndef CHROME_DEBUGGER_DISABLED
+ if (port > 0) {
+ DebuggerInputOutputSocket *io = new DebuggerInputOutputSocket(port);
+ debugger_ = new DebuggerShell(io);
+ debugger_->Start();
+ }
+#endif
+}
+
+DebuggerWrapper::~DebuggerWrapper() {
+}
+
+void DebuggerWrapper::SetDebugger(DebuggerShell* debugger) {
+ debugger_ = debugger;
+}
+
+DebuggerShell* DebuggerWrapper::GetDebugger() {
+ return debugger_.get();
+}
+
+void DebuggerWrapper::DebugMessage(const std::wstring& msg) {
+ if (debugger_.get())
+ debugger_->DebugMessage(msg);
+}
+
+void DebuggerWrapper::OnDebugDisconnect() {
+ if (debugger_.get())
+ debugger_->OnDebugDisconnect();
+} \ No newline at end of file
diff --git a/chrome/browser/debugger/debugger_wrapper.h b/chrome/browser/debugger/debugger_wrapper.h
new file mode 100644
index 0000000..92d9c6c
--- /dev/null
+++ b/chrome/browser/debugger/debugger_wrapper.h
@@ -0,0 +1,68 @@
+// Copyright 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * 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.
+// * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
+// OWNER OR 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 this file if you need to access the Debugger outside of the debugger
+// project. Don't include debugger.h directly. If there's functionality from
+// Debugger needed, add new wrapper methods to this file.
+//
+// This is a workaround to enable the Debugger without breaking the KJS build.
+// It wraps all methods in Debugger which are called from outside of the debugger
+// project. Each solution has its own project with debugger files. KJS has only
+// debugger_wrapper* and debugger.h, and defines CHROME_DEBUGGER_DISABLED, which makes
+// it compile only a stub version of Debugger that doesn't reference V8. Meanwhile
+// the V8 solution includes all of the debugger files without CHROME_DEBUGGER_DISABLED
+// so the full functionality is enabled.
+
+#ifndef CHROME_BROWSER_DEBUGGER_DEBUGGER_INTERFACE_H__
+#define CHROME_BROWSER_DEBUGGER_DEBUGGER_INTERFACE_H__
+
+#include "base/basictypes.h"
+#include "base/ref_counted.h"
+
+class DebuggerShell;
+
+class DebuggerWrapper : public base::RefCountedThreadSafe<DebuggerWrapper> {
+ public:
+ DebuggerWrapper(int port);
+
+ virtual ~DebuggerWrapper();
+
+ void SetDebugger(DebuggerShell* debugger);
+ DebuggerShell* GetDebugger();
+
+ void DebugMessage(const std::wstring& msg);
+
+ void OnDebugDisconnect();
+
+ private:
+ scoped_refptr<DebuggerShell> debugger_;
+};
+
+
+#endif // CHROME_BROWSER_DEBUGGER_DEBUGGER_INTERFACE_H__ \ No newline at end of file