From e4bfa373ded902bb0b5685893135a3165c409c96 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 11 Dec 2013 23:59:03 +0800 Subject: [PATCH] Fix node integration to browser after updated to Chrome31. --- atom.gyp | 1 + browser/atom/atom-renderer.coffee | 5 +++ browser/atom/atom.coffee | 72 +++++++++++++++++------------- browser/atom_browser_main_parts.cc | 2 - common/node_bindings.cc | 42 +++++++++++------ vendor/node | 2 +- 6 files changed, 75 insertions(+), 49 deletions(-) create mode 100644 browser/atom/atom-renderer.coffee diff --git a/atom.gyp b/atom.gyp index a9d8b92b42..60f8c77941 100644 --- a/atom.gyp +++ b/atom.gyp @@ -22,6 +22,7 @@ 'browser/api/lib/power-monitor.coffee', 'browser/api/lib/protocol.coffee', 'browser/atom/atom.coffee', + 'browser/atom/atom-renderer.coffee', 'browser/atom/objects-registry.coffee', 'browser/atom/rpc-server.coffee', 'common/api/lib/callbacks-registry.coffee', diff --git a/browser/atom/atom-renderer.coffee b/browser/atom/atom-renderer.coffee new file mode 100644 index 0000000000..8430d18334 --- /dev/null +++ b/browser/atom/atom-renderer.coffee @@ -0,0 +1,5 @@ +path = require 'path' + +process.__atom_type = 'renderer' +process.resourcesPath = path.resolve process.argv[1], '..', '..', '..' +process.argv.splice 1, 1 diff --git a/browser/atom/atom.coffee b/browser/atom/atom.coffee index 2488620467..6212dd0b29 100644 --- a/browser/atom/atom.coffee +++ b/browser/atom/atom.coffee @@ -1,6 +1,11 @@ fs = require 'fs' path = require 'path' +# Restore the proces.argv. +process.__atom_type = 'browser' +process.resourcesPath = path.resolve process.argv[1], '..', '..', '..' +process.argv.splice 1, 1 + if process.platform is 'win32' # Redirect node's console to use our own implementations, since node can not # handle output when running as GUI program. @@ -33,41 +38,44 @@ globalPaths.push path.join process.resourcesPath, 'browser', 'api', 'lib' # And also common/api/lib globalPaths.push path.join process.resourcesPath, 'common', 'api', 'lib' -# Don't quit on fatal error. -process.on 'uncaughtException', (error) -> - # Show error in GUI. - message = error.stack ? "#{error.name}: #{error.message}" - require('dialog').showMessageBox - type: 'warning' - title: 'An javascript error occured in the browser' - message: 'uncaughtException' - detail: message - buttons: ['OK'] +# Do loading in next tick since we still need some initialize work before +# native bindings can work. +setImmediate -> + # Don't quit on fatal error. + process.on 'uncaughtException', (error) -> + # Show error in GUI. + message = error.stack ? "#{error.name}: #{error.message}" + require('dialog').showMessageBox + type: 'warning' + title: 'An javascript error occured in the browser' + message: 'uncaughtException' + detail: message + buttons: ['OK'] -# Load the RPC server. -require './rpc-server.js' + # Load the RPC server. + require './rpc-server.js' -# Now we try to load app's package.json. -packageJson = null + # Now we try to load app's package.json. + packageJson = null -packagePath = path.join process.resourcesPath, 'app' -try - # First we try to load process.resourcesPath/app - packageJson = JSON.parse(fs.readFileSync(path.join(packagePath, 'package.json'))) -catch error - # If not found then we load browser/default_app - packagePath = path.join process.resourcesPath, 'browser', 'default_app' - packageJson = JSON.parse(fs.readFileSync(path.join(packagePath, 'package.json'))) + packagePath = path.join process.resourcesPath, 'app' + try + # First we try to load process.resourcesPath/app + packageJson = JSON.parse(fs.readFileSync(path.join(packagePath, 'package.json'))) + catch error + # If not found then we load browser/default_app + packagePath = path.join process.resourcesPath, 'browser', 'default_app' + packageJson = JSON.parse(fs.readFileSync(path.join(packagePath, 'package.json'))) -# Set application's version. -app = require 'app' -app.setVersion packageJson.version if packageJson.version? + # Set application's version. + app = require 'app' + app.setVersion packageJson.version if packageJson.version? -# Set application's name. -if packageJson.productName? - app.setName packageJson.productName -else if packageJson.name? - app.setName packageJson.name + # Set application's name. + if packageJson.productName? + app.setName packageJson.productName + else if packageJson.name? + app.setName packageJson.name -# Finally load app's main.js and transfer control to C++. -require path.join(packagePath, packageJson.main) + # Finally load app's main.js and transfer control to C++. + require path.join(packagePath, packageJson.main) diff --git a/browser/atom_browser_main_parts.cc b/browser/atom_browser_main_parts.cc index 93e99dca43..2328fda1bb 100644 --- a/browser/atom_browser_main_parts.cc +++ b/browser/atom_browser_main_parts.cc @@ -41,8 +41,6 @@ brightray::BrowserContext* AtomBrowserMainParts::CreateBrowserContext() { void AtomBrowserMainParts::PostEarlyInitialization() { brightray::BrowserMainParts::PostEarlyInitialization(); - v8::HandleScope handle_scope(node_isolate); - node_bindings_->Initialize(); // Wrap whole process in one global context. diff --git a/common/node_bindings.cc b/common/node_bindings.cc index 05dae33e8d..9bda801b95 100644 --- a/common/node_bindings.cc +++ b/common/node_bindings.cc @@ -4,9 +4,13 @@ #include "common/node_bindings.h" +#include // PATH_MAX + #include "base/command_line.h" #include "base/logging.h" #include "base/message_loop/message_loop.h" +#include "base/base_paths.h" +#include "base/path_service.h" #include "common/v8/native_type_conversions.h" #include "content/public/browser/browser_thread.h" #include "net/base/escape.h" @@ -22,6 +26,7 @@ using content::BrowserThread; +// Forward declaration of internal node functions. namespace node { void Init(int* argc, const char** argv, @@ -86,9 +91,29 @@ void NodeBindings::Initialize() { #endif } - // Init idle GC. - uv_timer_init(uv_default_loop(), &idle_timer_); - uv_timer_start(&idle_timer_, IdleCallback, 5000, 5000); + // Feed node the path to initialization script. + base::FilePath exec_path(str_argv[0]); + PathService::Get(base::FILE_EXE, &exec_path); + base::FilePath resources_path = +#if defined(OS_MACOSX) + is_browser_ ? exec_path.DirName().DirName().Append("Resources") : + exec_path.DirName().DirName().DirName().DirName().DirName() + .Append("Resources"); +#else + exec_path.DirName().Append("resources"); +#endif + base::FilePath script_path = + resources_path.AppendASCII("browser") + .AppendASCII("atom") + .AppendASCII(is_browser_ ? "atom.js" : "atom-renderer.js"); + std::string script_path_str = script_path.AsUTF8Unsafe(); + args.insert(args.begin() + 1, script_path_str.c_str()); + + // Init idle GC for browser. + if (is_browser_) { + uv_timer_init(uv_default_loop(), &idle_timer_); + uv_timer_start(&idle_timer_, IdleCallback, 5000, 5000); + } // Open node's error reporting system for browser process. node::g_standalone_mode = is_browser_; @@ -104,17 +129,6 @@ void NodeBindings::Initialize() { // Create environment (setup process object and load node.js). global_env = node::CreateEnvironment(node_isolate, argc, argv, argc, argv); - - // Set the process.__atom_type. - { - v8::Context::Scope context_scope(global_env->context()); - v8::HandleScope handle_scope(global_env->isolate()); - - // Tell node.js we are in browser or renderer. - v8::Handle type = - is_browser_ ? v8::String::New("browser") : v8::String::New("renderer"); - global_env->process_object()->Set(v8::String::New("__atom_type"), type); - } } void NodeBindings::BindTo(WebKit::WebFrame* frame) { diff --git a/vendor/node b/vendor/node index 264b0177bc..4e04c9f0a2 160000 --- a/vendor/node +++ b/vendor/node @@ -1 +1 @@ -Subproject commit 264b0177bc11c4b2e733294c7921fd4c72e5b4e5 +Subproject commit 4e04c9f0a2d97e0b20a0980266917e11f2805280