diff --git a/common/node_bindings.cc b/common/node_bindings.cc index 5847192f0b8c..e4ba9ecd3770 100644 --- a/common/node_bindings.cc +++ b/common/node_bindings.cc @@ -8,8 +8,11 @@ #include "base/files/file_path.h" #include "base/logging.h" #include "v8/include/v8.h" +#include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h" +#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" #include "vendor/node/src/node.h" #include "vendor/node/src/node_internals.h" +#include "vendor/node/src/node_javascript.h" namespace atom { @@ -56,4 +59,29 @@ void NodeBindings::Load() { node::Load(node::process); } +void NodeBindings::BindTo(WebKit::WebFrame* frame) { + v8::HandleScope handle_scope; + + v8::Handle context = frame->mainWorldScriptContext(); + if (context.IsEmpty()) + return; + + v8::Context::Scope scope(context); + + // Erase security token. + context->SetSecurityToken(node::g_context->GetSecurityToken()); + + // Evaluate cefode.js. + v8::Handle script = node::CompileCefodeMainSource(); + v8::Local result = script->Run(); + + // Run the script of cefode.js. + std::string script_path(GURL(frame->document().url()).path()); + v8::Handle args[2] = { + v8::Local::New(node::process), + v8::String::New(script_path.c_str(), script_path.size()) + }; + v8::Local::Cast(result)->Call(context->Global(), 2, args); +} + } // namespace atom diff --git a/common/node_bindings.h b/common/node_bindings.h index 2b684d8ee441..4f4edec1725d 100644 --- a/common/node_bindings.h +++ b/common/node_bindings.h @@ -7,6 +7,10 @@ #include "base/basictypes.h" +namespace WebKit { +class WebFrame; +} + namespace atom { class NodeBindings { @@ -21,6 +25,9 @@ class NodeBindings { // Load node.js main script. virtual void Load(); + // Load cefode.js script under web frame. + virtual void BindTo(WebKit::WebFrame* frame); + // Prepare for message loop integration. virtual void PrepareMessageLoop() = 0; diff --git a/renderer/atom_render_view_observer.cc b/renderer/atom_render_view_observer.cc index 3f9ace15c0cf..bf0c12c784b8 100644 --- a/renderer/atom_render_view_observer.cc +++ b/renderer/atom_render_view_observer.cc @@ -4,21 +4,24 @@ #include "renderer/atom_render_view_observer.h" -#include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h" -#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" +#include "common/node_bindings.h" +#include "renderer/atom_renderer_client.h" #include "v8/include/v8.h" namespace atom { AtomRenderViewObserver::AtomRenderViewObserver( - content::RenderView *render_view) - : content::RenderViewObserver(render_view) { + content::RenderView* render_view, + AtomRendererClient* renderer_client) + : content::RenderViewObserver(render_view), + renderer_client_(renderer_client) { } AtomRenderViewObserver::~AtomRenderViewObserver() { } void AtomRenderViewObserver::DidClearWindowObject(WebKit::WebFrame* frame) { + renderer_client_->node_bindings()->BindTo(frame); } } // namespace atom diff --git a/renderer/atom_render_view_observer.h b/renderer/atom_render_view_observer.h index 20d80454c9f1..b8008d9ed53b 100644 --- a/renderer/atom_render_view_observer.h +++ b/renderer/atom_render_view_observer.h @@ -9,15 +9,21 @@ namespace atom { +class AtomRendererClient; + class AtomRenderViewObserver : content::RenderViewObserver { public: - explicit AtomRenderViewObserver(content::RenderView*); + explicit AtomRenderViewObserver(content::RenderView* render_view, + AtomRendererClient* renderer_client); private: virtual ~AtomRenderViewObserver(); virtual void DidClearWindowObject(WebKit::WebFrame*) OVERRIDE; + // Weak reference to renderer client. + AtomRendererClient* renderer_client_; + DISALLOW_COPY_AND_ASSIGN(AtomRenderViewObserver); }; diff --git a/renderer/atom_renderer_client.cc b/renderer/atom_renderer_client.cc index 7f15a6a39322..142e6ff470bc 100644 --- a/renderer/atom_renderer_client.cc +++ b/renderer/atom_renderer_client.cc @@ -4,18 +4,36 @@ #include "renderer/atom_renderer_client.h" +#include "common/node_bindings.h" #include "renderer/atom_render_view_observer.h" +#include "vendor/node/src/node_internals.h" + +namespace webkit_atom { +extern void SetNodeContext(v8::Persistent context); +} namespace atom { -AtomRendererClient::AtomRendererClient() { +AtomRendererClient::AtomRendererClient() + : node_bindings_(NodeBindings::Create(false)) { } AtomRendererClient::~AtomRendererClient() { } +void AtomRendererClient::RenderThreadStarted() { + node_bindings_->Initialize(); + + // Interact with dirty workarounds of extra node context in WebKit. + webkit_atom::SetNodeContext(node::g_context); + + node_bindings_->Load(); + node_bindings_->PrepareMessageLoop(); + node_bindings_->RunMessageLoop(); +} + void AtomRendererClient::RenderViewCreated(content::RenderView* render_view) { - new AtomRenderViewObserver(render_view); + new AtomRenderViewObserver(render_view, this); } } // namespace atom diff --git a/renderer/atom_renderer_client.h b/renderer/atom_renderer_client.h index 1cddcdc42bd3..46c79e75d645 100644 --- a/renderer/atom_renderer_client.h +++ b/renderer/atom_renderer_client.h @@ -9,14 +9,21 @@ namespace atom { +class NodeBindings; + class AtomRendererClient : public content::ContentRendererClient { public: AtomRendererClient(); virtual ~AtomRendererClient(); + NodeBindings* node_bindings() const { return node_bindings_.get(); } + private: + virtual void RenderThreadStarted() OVERRIDE; virtual void RenderViewCreated(content::RenderView*) OVERRIDE; + scoped_ptr node_bindings_; + DISALLOW_COPY_AND_ASSIGN(AtomRendererClient); };