diff --git a/atom.gyp b/atom.gyp index 0944c1675243..0f3b3edd5e37 100644 --- a/atom.gyp +++ b/atom.gyp @@ -17,16 +17,14 @@ 'browser/api/atom_api_event.h', 'browser/api/atom_api_event_emitter.cc', 'browser/api/atom_api_event_emitter.h', - 'browser/api/atom_api_extensions.cc', - 'browser/api/atom_api_extensions.h', 'browser/api/atom_api_objects_registry.cc', 'browser/api/atom_api_objects_registry.h', 'browser/api/atom_api_recorded_object.cc', 'browser/api/atom_api_recorded_object.h', 'browser/api/atom_api_window.cc', 'browser/api/atom_api_window.h', - 'browser/api/atom_bindings.cc', - 'browser/api/atom_bindings.h', + 'browser/api/atom_browser_bindings.cc', + 'browser/api/atom_browser_bindings.h', 'browser/atom_browser_client.cc', 'browser/atom_browser_client.h', 'browser/atom_browser_context.cc', @@ -40,8 +38,12 @@ 'browser/native_window_mac.h', 'browser/native_window_mac.mm', 'browser/native_window_observer.h', - 'common/api_messages.cc', - 'common/api_messages.h', + 'common/api/api_messages.cc', + 'common/api/api_messages.h', + 'common/api/atom_bindings.cc', + 'common/api/atom_bindings.h', + 'common/api/atom_extensions.cc', + 'common/api/atom_extensions.h', 'common/node_bindings.cc', 'common/node_bindings.h', 'common/node_bindings_mac.h', diff --git a/browser/api/atom_api_window.cc b/browser/api/atom_api_window.cc index 7f86cbf7c3a2..bb94f619da42 100644 --- a/browser/api/atom_api_window.cc +++ b/browser/api/atom_api_window.cc @@ -596,4 +596,4 @@ void Window::Initialize(v8::Handle target) { } // namespace atom -NODE_MODULE(atom_api_window, atom::api::Window::Initialize) +NODE_MODULE(atom_browser_window, atom::api::Window::Initialize) diff --git a/browser/api/atom_bindings.cc b/browser/api/atom_bindings.cc deleted file mode 100644 index 123f1207c6b6..000000000000 --- a/browser/api/atom_bindings.cc +++ /dev/null @@ -1,81 +0,0 @@ -// Copyright (c) 2013 GitHub, Inc. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "browser/api/atom_bindings.h" - -#include "base/logging.h" -#include "vendor/node/src/node.h" -#include "vendor/node/src/node_internals.h" - -using node::node_isolate; - -namespace atom { - -// Defined in atom_api_extensions.cc. -namespace api { -node::node_module_struct* get_builtin_module(const char *name); -} - -v8::Persistent AtomBindings::binding_cache_; - -AtomBindings::AtomBindings() { -} - -AtomBindings::~AtomBindings() { -} - -void AtomBindings::BindTo(v8::Handle process) { - v8::HandleScope scope; - - node::SetMethod(process, "atom_binding", Binding); -} - -void AtomBindings::AfterLoad() { - v8::HandleScope scope; - - v8::Handle global = node::g_context->Global(); - v8::Handle atom = - global->Get(v8::String::New("__atom"))->ToObject(); - DCHECK(!atom.IsEmpty()); - - browser_main_parts_ = v8::Persistent::New( - node_isolate, - atom->Get(v8::String::New("browserMainParts"))->ToObject()); - DCHECK(!browser_main_parts_.IsEmpty()); -} - -// static -v8::Handle AtomBindings::Binding(const v8::Arguments& args) { - v8::HandleScope scope; - - v8::Local module = args[0]->ToString(); - v8::String::Utf8Value module_v(module); - node::node_module_struct* modp; - - if (binding_cache_.IsEmpty()) { - binding_cache_ = v8::Persistent::New( - node_isolate, v8::Object::New()); - } - - v8::Local exports; - - if (binding_cache_->Has(module)) { - exports = binding_cache_->Get(module)->ToObject(); - return scope.Close(exports); - } - - if ((modp = api::get_builtin_module(*module_v)) != NULL) { - exports = v8::Object::New(); - // Internal bindings don't have a "module" object, - // only exports. - modp->register_func(exports, v8::Undefined()); - binding_cache_->Set(module, exports); - return scope.Close(exports); - } - - return v8::ThrowException(v8::Exception::Error( - v8::String::New("No such module"))); -} - -} // namespace atom diff --git a/browser/api/atom_browser_bindings.cc b/browser/api/atom_browser_bindings.cc new file mode 100644 index 000000000000..bc4d3b337345 --- /dev/null +++ b/browser/api/atom_browser_bindings.cc @@ -0,0 +1,38 @@ +// Copyright (c) 2013 GitHub, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "browser/api/atom_browser_bindings.h" + +#include "base/logging.h" +#include "content/public/browser/browser_thread.h" +#include "vendor/node/src/node.h" +#include "vendor/node/src/node_internals.h" + +using node::node_isolate; + +namespace atom { + +AtomBrowserBindings::AtomBrowserBindings() { +} + +AtomBrowserBindings::~AtomBrowserBindings() { +} + +void AtomBrowserBindings::AfterLoad() { + DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); + + v8::HandleScope scope; + + v8::Handle global = node::g_context->Global(); + v8::Handle atom = + global->Get(v8::String::New("__atom"))->ToObject(); + DCHECK(!atom.IsEmpty()); + + browser_main_parts_ = v8::Persistent::New( + node_isolate, + atom->Get(v8::String::New("browserMainParts"))->ToObject()); + DCHECK(!browser_main_parts_.IsEmpty()); +} + +} // namespace atom diff --git a/browser/api/atom_browser_bindings.h b/browser/api/atom_browser_bindings.h new file mode 100644 index 000000000000..f67fcf0b5020 --- /dev/null +++ b/browser/api/atom_browser_bindings.h @@ -0,0 +1,33 @@ +// Copyright (c) 2013 GitHub, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef ATOM_BROWSER_API_ATOM_BROWSER_BINDINGS_ +#define ATOM_BROWSER_API_ATOM_BROWSER_BINDINGS_ + +#include "common/api/atom_bindings.h" + +namespace atom { + +class AtomBrowserBindings : public AtomBindings { + public: + AtomBrowserBindings(); + virtual ~AtomBrowserBindings(); + + // Called when the node.js main script has been loaded. + virtual void AfterLoad(); + + // The require('atom').browserMainParts object. + v8::Handle browser_main_parts() { + return browser_main_parts_; + } + + private: + v8::Persistent browser_main_parts_; + + DISALLOW_COPY_AND_ASSIGN(AtomBrowserBindings); +}; + +} // namespace atom + +#endif // ATOM_BROWSER_API_ATOM_BINDINGS_ diff --git a/browser/atom_browser_main_parts.cc b/browser/atom_browser_main_parts.cc index ae5405a5547c..c5ac02a5784b 100644 --- a/browser/atom_browser_main_parts.cc +++ b/browser/atom_browser_main_parts.cc @@ -4,7 +4,7 @@ #include "browser/atom_browser_main_parts.h" -#include "browser/api/atom_bindings.h" +#include "browser/api/atom_browser_bindings.h" #include "browser/atom_browser_context.h" #include "browser/native_window.h" #include "common/node_bindings.h" @@ -14,7 +14,7 @@ namespace atom { AtomBrowserMainParts::AtomBrowserMainParts() - : atom_bindings_(new AtomBindings), + : atom_bindings_(new AtomBrowserBindings), node_bindings_(NodeBindings::Create(true)) { } diff --git a/browser/atom_browser_main_parts.h b/browser/atom_browser_main_parts.h index 732152628885..c1dd0c8e43bc 100644 --- a/browser/atom_browser_main_parts.h +++ b/browser/atom_browser_main_parts.h @@ -9,7 +9,7 @@ namespace atom { -class AtomBindings; +class AtomBrowserBindings; class NodeBindings; class AtomBrowserMainParts : public brightray::BrowserMainParts { @@ -27,7 +27,7 @@ class AtomBrowserMainParts : public brightray::BrowserMainParts { virtual void PreMainMessageLoopRun() OVERRIDE; private: - scoped_ptr atom_bindings_; + scoped_ptr atom_bindings_; scoped_ptr node_bindings_; DISALLOW_COPY_AND_ASSIGN(AtomBrowserMainParts); diff --git a/common/api_messages.cc b/common/api/api_messages.cc similarity index 76% rename from common/api_messages.cc rename to common/api/api_messages.cc index ee9b250a4af6..e5ba3c9f1680 100644 --- a/common/api_messages.cc +++ b/common/api/api_messages.cc @@ -4,30 +4,30 @@ // Get basic type definitions. #define IPC_MESSAGE_IMPL -#include "common/api_messages.h" +#include "common/api/api_messages.h" // Generate constructors. #include "ipc/struct_constructor_macros.h" -#include "common/api_messages.h" +#include "common/api/api_messages.h" // Generate destructors. #include "ipc/struct_destructor_macros.h" -#include "common/api_messages.h" +#include "common/api/api_messages.h" // Generate param traits write methods. #include "ipc/param_traits_write_macros.h" namespace IPC { -#include "common/api_messages.h" +#include "common/api/api_messages.h" } // namespace IPC // Generate param traits read methods. #include "ipc/param_traits_read_macros.h" namespace IPC { -#include "common/api_messages.h" +#include "common/api/api_messages.h" } // namespace IPC // Generate param traits log methods. #include "ipc/param_traits_log_macros.h" namespace IPC { -#include "common/api_messages.h" +#include "common/api/api_messages.h" } // namespace IPC diff --git a/common/api_messages.h b/common/api/api_messages.h similarity index 100% rename from common/api_messages.h rename to common/api/api_messages.h diff --git a/common/api/atom_bindings.cc b/common/api/atom_bindings.cc new file mode 100644 index 000000000000..75f589e3f0c1 --- /dev/null +++ b/common/api/atom_bindings.cc @@ -0,0 +1,91 @@ +// Copyright (c) 2013 GitHub, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "common/api/atom_bindings.h" + +#include "base/logging.h" +#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" +#include "vendor/node/src/node.h" + +namespace atom { + +// Defined in atom_extensions.cc. +node::node_module_struct* GetBuiltinModule(const char *name, bool is_browser); + +AtomBindings::AtomBindings() { +} + +AtomBindings::~AtomBindings() { +} + +void AtomBindings::BindTo(v8::Handle process) { + v8::HandleScope scope; + + node::SetMethod(process, "atom_binding", Binding); +} + +// static +v8::Handle AtomBindings::Binding(const v8::Arguments& args) { + v8::HandleScope scope; + + v8::Local module = args[0]->ToString(); + v8::String::Utf8Value module_v(module); + node::node_module_struct* modp; + + v8::Local process = v8::Context::GetCurrent()->Global()-> + Get(v8::String::New("process"))->ToObject(); + DCHECK(!process.IsEmpty()); + + // is_browser = process.__atom_type == 'browser'. + bool is_browser = std::string("browser") == *v8::String::Utf8Value( + process->Get(v8::String::New("__atom_type"))); + + // Cached in process.__atom_binding_cache. + v8::Local binding_cache; + v8::Local bc_name = v8::String::New("__atom_binding_cache"); + if (process->Has(bc_name)) { + binding_cache = process->Get(bc_name)->ToObject(); + DCHECK(!binding_cache.IsEmpty()); + } else { + binding_cache = v8::Object::New(); + process->Set(bc_name, binding_cache); + } + + v8::Local exports; + + if (binding_cache->Has(module)) { + exports = binding_cache->Get(module)->ToObject(); + return scope.Close(exports); + } + + if ((modp = GetBuiltinModule(*module_v, is_browser)) != NULL) { + exports = v8::Object::New(); + // Internal bindings don't have a "module" object, + // only exports. + modp->register_func(exports, v8::Undefined()); + binding_cache->Set(module, exports); + return scope.Close(exports); + } + + return v8::ThrowException(v8::Exception::Error( + v8::String::New("No such module"))); +} + +void AtomBindings::BindToFrame(WebKit::WebFrame* frame) { + v8::HandleScope handle_scope; + + v8::Handle context = frame->mainWorldScriptContext(); + if (context.IsEmpty()) + return; + + v8::Context::Scope scope(context); + + v8::Handle process = + context->Global()->Get(v8::String::New("process"))->ToObject(); + DCHECK(!process.IsEmpty()); + + AtomBindings::BindTo(process); +} + +} // namespace atom diff --git a/browser/api/atom_bindings.h b/common/api/atom_bindings.h similarity index 58% rename from browser/api/atom_bindings.h rename to common/api/atom_bindings.h index 351c212627fc..e778fa5d5502 100644 --- a/browser/api/atom_bindings.h +++ b/common/api/atom_bindings.h @@ -2,12 +2,16 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef ATOM_BROWSER_API_ATOM_BINDINGS_ -#define ATOM_BROWSER_API_ATOM_BINDINGS_ +#ifndef ATOM_COMMON_API_ATOM_BINDINGS_ +#define ATOM_COMMON_API_ATOM_BINDINGS_ #include "base/basictypes.h" #include "v8/include/v8.h" +namespace WebKit { +class WebFrame; +} + namespace atom { class AtomBindings { @@ -19,24 +23,15 @@ class AtomBindings { // load native code from atom-shell instead. virtual void BindTo(v8::Handle process); - // Called when the node.js main script has been loaded. - virtual void AfterLoad(); - - // The require('atom').browserMainParts object. - v8::Handle browser_main_parts() { - return browser_main_parts_; - } + // Call BindTo for process object of the frame. + void BindToFrame(WebKit::WebFrame* frame); private: static v8::Handle Binding(const v8::Arguments& args); - static v8::Persistent binding_cache_; - - v8::Persistent browser_main_parts_; - DISALLOW_COPY_AND_ASSIGN(AtomBindings); }; } // namespace atom -#endif // ATOM_BROWSER_API_ATOM_BINDINGS_ +#endif // ATOM_COMMON_API_ATOM_BINDINGS_ diff --git a/browser/api/atom_api_extensions.cc b/common/api/atom_extensions.cc similarity index 78% rename from browser/api/atom_api_extensions.cc rename to common/api/atom_extensions.cc index 0f205e30e941..e3f191bf20ee 100644 --- a/browser/api/atom_api_extensions.cc +++ b/common/api/atom_extensions.cc @@ -10,8 +10,6 @@ namespace atom { -namespace api { - #undef NODE_EXT_LIST_START #undef NODE_EXT_LIST_ITEM #undef NODE_EXT_LIST_END @@ -20,7 +18,7 @@ namespace api { #define NODE_EXT_LIST_ITEM NODE_MODULE_DECL #define NODE_EXT_LIST_END -#include "browser/api/atom_api_extensions.h" +#include "common/api/atom_extensions.h" #undef NODE_EXT_LIST_START #undef NODE_EXT_LIST_ITEM @@ -31,12 +29,15 @@ namespace api { #define NODE_EXT_LIST_ITEM NODE_EXT_STRING #define NODE_EXT_LIST_END NULL}; -#include "browser/api/atom_api_extensions.h" // NOLINT +#include "common/api/atom_extensions.h" // NOLINT -node::node_module_struct* get_builtin_module(const char *name) { +node::node_module_struct* GetBuiltinModule(const char *name, bool is_browser) { char buf[128]; node::node_module_struct *cur = NULL; - snprintf(buf, sizeof(buf), "atom_api_%s", name); + if (is_browser) + snprintf(buf, sizeof(buf), "atom_browser_%s", name); + else + snprintf(buf, sizeof(buf), "atom_renderer_%s", name); /* TODO: you could look these up in a hash, but there are only * a few, and once loaded they are cached. */ for (int i = 0; node_module_list[i] != NULL; i++) { @@ -49,6 +50,4 @@ node::node_module_struct* get_builtin_module(const char *name) { return NULL; } -} // namespace api - } // namespace atom diff --git a/browser/api/atom_api_extensions.h b/common/api/atom_extensions.h similarity index 89% rename from browser/api/atom_api_extensions.h rename to common/api/atom_extensions.h index 9e83337bb06e..47bdd3789c33 100644 --- a/browser/api/atom_api_extensions.h +++ b/common/api/atom_extensions.h @@ -8,6 +8,6 @@ NODE_EXT_LIST_START -NODE_EXT_LIST_ITEM(atom_api_window) +NODE_EXT_LIST_ITEM(atom_browser_window) NODE_EXT_LIST_END diff --git a/renderer/atom_render_view_observer.cc b/renderer/atom_render_view_observer.cc index d0f4ebe18d40..615434c4b2d0 100644 --- a/renderer/atom_render_view_observer.cc +++ b/renderer/atom_render_view_observer.cc @@ -7,6 +7,7 @@ #include #include +#include "common/api/atom_bindings.h" #include "common/node_bindings.h" #include "renderer/atom_renderer_client.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" @@ -67,6 +68,7 @@ void AtomRenderViewObserver::DidClearWindowObject(WebFrame* frame) { web_frames().push_back(frame); renderer_client_->node_bindings()->BindTo(frame); + renderer_client_->atom_bindings()->BindToFrame(frame); } void AtomRenderViewObserver::FrameWillClose(WebFrame* frame) { diff --git a/renderer/atom_renderer_client.cc b/renderer/atom_renderer_client.cc index 142e6ff470bc..1029bdbdf013 100644 --- a/renderer/atom_renderer_client.cc +++ b/renderer/atom_renderer_client.cc @@ -4,6 +4,7 @@ #include "renderer/atom_renderer_client.h" +#include "common/api/atom_bindings.h" #include "common/node_bindings.h" #include "renderer/atom_render_view_observer.h" #include "vendor/node/src/node_internals.h" @@ -15,7 +16,8 @@ extern void SetNodeContext(v8::Persistent context); namespace atom { AtomRendererClient::AtomRendererClient() - : node_bindings_(NodeBindings::Create(false)) { + : atom_bindings_(new AtomBindings), + node_bindings_(NodeBindings::Create(false)) { } AtomRendererClient::~AtomRendererClient() { diff --git a/renderer/atom_renderer_client.h b/renderer/atom_renderer_client.h index 46c79e75d645..2cc071612a93 100644 --- a/renderer/atom_renderer_client.h +++ b/renderer/atom_renderer_client.h @@ -9,6 +9,7 @@ namespace atom { +class AtomBindings; class NodeBindings; class AtomRendererClient : public content::ContentRendererClient { @@ -16,12 +17,14 @@ class AtomRendererClient : public content::ContentRendererClient { AtomRendererClient(); virtual ~AtomRendererClient(); + AtomBindings* atom_bindings() const { return atom_bindings_.get(); } NodeBindings* node_bindings() const { return node_bindings_.get(); } private: virtual void RenderThreadStarted() OVERRIDE; virtual void RenderViewCreated(content::RenderView*) OVERRIDE; + scoped_ptr atom_bindings_; scoped_ptr node_bindings_; DISALLOW_COPY_AND_ASSIGN(AtomRendererClient);