diff --git a/atom/browser/api/atom_api_debugger.cc b/atom/browser/api/atom_api_debugger.cc index b40bb4134271..eab60311f3dd 100644 --- a/atom/browser/api/atom_api_debugger.cc +++ b/atom/browser/api/atom_api_debugger.cc @@ -6,12 +6,15 @@ #include +#include "atom/browser/atom_browser_main_parts.h" #include "atom/common/native_mate_converters/callback.h" #include "atom/common/native_mate_converters/value_converter.h" +#include "atom/common/node_includes.h" #include "base/json/json_reader.h" #include "base/json/json_writer.h" #include "content/public/browser/devtools_agent_host.h" #include "content/public/browser/web_contents.h" +#include "native_mate/dictionary.h" #include "native_mate/object_template_builder.h" using content::DevToolsAgentHost; @@ -20,6 +23,14 @@ namespace atom { namespace api { +namespace { + +// The wrapDebugger funtion which is implemented in JavaScript. +using WrapDebuggerCallback = base::Callback)>; +WrapDebuggerCallback g_wrap_debugger; + +} // namespace + Debugger::Debugger(content::WebContents* web_contents) : web_contents_(web_contents), previous_request_id_(0) { @@ -139,7 +150,9 @@ void Debugger::SendCommand(mate::Arguments* args) { mate::Handle Debugger::Create( v8::Isolate* isolate, content::WebContents* web_contents) { - return mate::CreateHandle(isolate, new Debugger(web_contents)); + auto handle = mate::CreateHandle(isolate, new Debugger(web_contents)); + g_wrap_debugger.Run(handle.ToV8()); + return handle; } // static @@ -152,6 +165,31 @@ void Debugger::BuildPrototype(v8::Isolate* isolate, .SetMethod("sendCommand", &Debugger::SendCommand); } +void ClearWrapDebugger() { + g_wrap_debugger.Reset(); +} + +void SetWrapDebugger(const WrapDebuggerCallback& callback) { + g_wrap_debugger = callback; + + // Cleanup the wrapper on exit. + atom::AtomBrowserMainParts::Get()->RegisterDestructionCallback( + base::Bind(ClearWrapDebugger)); +} + } // namespace api } // namespace atom + +namespace { + +void Initialize(v8::Local exports, v8::Local unused, + v8::Local context, void* priv) { + v8::Isolate* isolate = context->GetIsolate(); + mate::Dictionary dict(isolate, exports); + dict.SetMethod("_setWrapDebugger", &atom::api::SetWrapDebugger); +} + +} // namespace + +NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_browser_debugger, Initialize); diff --git a/atom/browser/api/lib/web-contents.js b/atom/browser/api/lib/web-contents.js index b71ddf4cb9fd..4f2e98a07081 100644 --- a/atom/browser/api/lib/web-contents.js +++ b/atom/browser/api/lib/web-contents.js @@ -8,6 +8,7 @@ const NavigationController = require('electron').NavigationController; const Menu = require('electron').Menu; const binding = process.atomBinding('web_contents'); +const debuggerBinding = process.atomBinding('debugger'); let slice = [].slice; let nextId = 0; @@ -70,9 +71,6 @@ let wrapWebContents = function(webContents) { var controller, method, name, ref1; webContents.__proto__ = EventEmitter.prototype; - // webContents.debugger is an EventEmitter. - webContents.debugger.__proto__ = EventEmitter.prototype; - // Every remote callback from renderer process would add a listenter to the // render-view-deleted event, so ignore the listenters warning. webContents.setMaxListeners(0); @@ -219,7 +217,14 @@ let wrapWebContents = function(webContents) { }; }; +// Wrapper for native class. +let wrapDebugger = function(webContentsDebugger) { + // debugger is an EventEmitter. + webContentsDebugger.__proto__ = EventEmitter.prototype; +}; + binding._setWrapWebContents(wrapWebContents); +debuggerBinding._setWrapDebugger(wrapDebugger); module.exports.create = function(options) { if (options == null) { diff --git a/atom/common/node_bindings.cc b/atom/common/node_bindings.cc index b1cb84eead90..69e7906ffbbb 100644 --- a/atom/common/node_bindings.cc +++ b/atom/common/node_bindings.cc @@ -35,6 +35,7 @@ REFERENCE_MODULE(atom_browser_app); REFERENCE_MODULE(atom_browser_auto_updater); REFERENCE_MODULE(atom_browser_content_tracing); REFERENCE_MODULE(atom_browser_dialog); +REFERENCE_MODULE(atom_browser_debugger); REFERENCE_MODULE(atom_browser_desktop_capturer); REFERENCE_MODULE(atom_browser_download_item); REFERENCE_MODULE(atom_browser_menu);