From ce586e08358ece4141c66865a6b52bccea796d08 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 30 Jan 2014 21:06:56 +0800 Subject: [PATCH 01/15] Don't append duplicate arguments to renderer process. --- app/atom_main_delegate.cc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/atom_main_delegate.cc b/app/atom_main_delegate.cc index 40a42d721741..1f304926db99 100644 --- a/app/atom_main_delegate.cc +++ b/app/atom_main_delegate.cc @@ -51,6 +51,12 @@ void AtomMainDelegate::PreSandboxStartup() { InitializeResourceBundle(); CommandLine* command_line = CommandLine::ForCurrentProcess(); + std::string process_type = command_line->GetSwitchValueASCII( + switches::kProcessType); + + // Don't append arguments for renderer process. + if (process_type == switches::kRendererProcess) + return; // Disable renderer sandbox for most of node's functions. command_line->AppendSwitch(switches::kNoSandbox); From 9a58706e1f5e8f75f4745b050c825706e932ee32 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 30 Jan 2014 21:17:16 +0800 Subject: [PATCH 02/15] Don't pollute process.argv of browser process. --- app/atom_main_delegate.cc | 2 +- browser/default_app/main.js | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/app/atom_main_delegate.cc b/app/atom_main_delegate.cc index 1f304926db99..816df2916b13 100644 --- a/app/atom_main_delegate.cc +++ b/app/atom_main_delegate.cc @@ -66,7 +66,7 @@ void AtomMainDelegate::PreSandboxStartup() { command_line->AppendSwitch(switches::kDisableAcceleratedCompositing); // Add a flag to mark the end of switches added by atom-shell. - command_line->AppendSwitch("no-more-switches"); + command_line->AppendSwitch("no-more-atom-shell-switches"); } void AtomMainDelegate::InitializeResourceBundle() { diff --git a/browser/default_app/main.js b/browser/default_app/main.js index 2aff83e30b0d..acf1a38976df 100644 --- a/browser/default_app/main.js +++ b/browser/default_app/main.js @@ -1,5 +1,4 @@ var app = require('app'); -var dialog = require('dialog'); var path = require('path'); var optimist = require('optimist'); @@ -9,6 +8,10 @@ app.on('window-all-closed', function() { app.quit(); }); +// Pick out switches appended by atom-shell. +var endMark = process.argv.indexOf('--no-more-atom-shell-switches'); +process.execArgv = process.argv.splice(1, endMark) + var argv = optimist(process.argv.slice(1)).argv; // Start the specified app if there is one specified in command line, otherwise From a0b15661edcf2756b382f79101f51a94f7c7639c Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 30 Jan 2014 21:57:01 +0800 Subject: [PATCH 03/15] Append --iframe-security to renderer process. --- browser/atom_browser_client.cc | 23 +++++++++++++++++++++++ browser/atom_browser_client.h | 2 ++ browser/native_window.cc | 11 +++++++---- browser/native_window.h | 4 ++++ common/options_switches.cc | 2 ++ common/options_switches.h | 1 + 6 files changed, 39 insertions(+), 4 deletions(-) diff --git a/browser/atom_browser_client.cc b/browser/atom_browser_client.cc index 19617002a816..b58057102495 100644 --- a/browser/atom_browser_client.cc +++ b/browser/atom_browser_client.cc @@ -4,9 +4,15 @@ #include "browser/atom_browser_client.h" +#include "base/command_line.h" #include "browser/atom_browser_context.h" #include "browser/atom_browser_main_parts.h" +#include "browser/native_window.h" #include "browser/net/atom_url_request_context_getter.h" +#include "browser/window_list.h" +#include "common/options_switches.h" +#include "content/public/browser/render_process_host.h" +#include "content/public/browser/web_contents.h" #include "webkit/common/webpreferences.h" namespace atom { @@ -54,6 +60,23 @@ bool AtomBrowserClient::ShouldSwapProcessesForNavigation( return true; } +void AtomBrowserClient::AppendExtraCommandLineSwitches( + CommandLine* command_line, + int child_process_id) { + // Append --iframe-security to renderer process. + WindowList* list = WindowList::GetInstance(); + for (WindowList::const_iterator iter = list->begin(); iter != list->end(); + ++iter) { + NativeWindow* window = *iter; + int id = window->GetWebContents()->GetRenderProcessHost()->GetID(); + if (id == child_process_id) { + command_line->AppendSwitchASCII(switches::kIframeSecurity, + window->iframe_security()); + return; + } + } +} + brightray::BrowserMainParts* AtomBrowserClient::OverrideCreateBrowserMainParts( const content::MainFunctionParams&) { return new AtomBrowserMainParts; diff --git a/browser/atom_browser_client.h b/browser/atom_browser_client.h index 3443f0a707d9..183b647837ec 100644 --- a/browser/atom_browser_client.h +++ b/browser/atom_browser_client.h @@ -25,6 +25,8 @@ class AtomBrowserClient : public brightray::BrowserClient { content::SiteInstance* site_instance, const GURL& current_url, const GURL& new_url) OVERRIDE; + virtual void AppendExtraCommandLineSwitches(CommandLine* command_line, + int child_process_id) OVERRIDE; private: virtual brightray::BrowserMainParts* OverrideCreateBrowserMainParts( diff --git a/browser/native_window.cc b/browser/native_window.cc index 7b923adf2c3b..b8ca401b8aaa 100644 --- a/browser/native_window.cc +++ b/browser/native_window.cc @@ -48,16 +48,19 @@ NativeWindow::NativeWindow(content::WebContents* web_contents, : content::WebContentsObserver(web_contents), has_frame_(true), is_closed_(false), + iframe_security_("full"), weak_factory_(this), inspectable_web_contents_( brightray::InspectableWebContents::Create(web_contents)) { options->GetBoolean(switches::kFrame, &has_frame_); + // Read icon before window is created. std::string icon; - if (options->GetString(switches::kIcon, &icon)) { - if (!SetIcon(icon)) - LOG(ERROR) << "Failed to set icon to " << icon; - } + if (options->GetString(switches::kIcon, &icon) && !SetIcon(icon)) + LOG(ERROR) << "Failed to set icon to " << icon; + + // Read iframe security before any navigation. + options->GetString(switches::kIframeSecurity, &iframe_security_); web_contents->SetDelegate(this); diff --git a/browser/native_window.h b/browser/native_window.h index 54cb539d755d..462d96c19955 100644 --- a/browser/native_window.h +++ b/browser/native_window.h @@ -140,6 +140,7 @@ class NativeWindow : public brightray::DefaultWebContentsDelegate, } bool has_frame() const { return has_frame_; } + std::string iframe_security() const { return iframe_security_; } protected: explicit NativeWindow(content::WebContents* web_contents, @@ -219,6 +220,9 @@ class NativeWindow : public brightray::DefaultWebContentsDelegate, // The windows has been closed. bool is_closed_; + // The security token of iframe. + std::string iframe_security_; + // Closure that would be called when window is unresponsive when closing, // it should be cancelled when we can prove that the window is responsive. base::CancelableClosure window_unresposive_closure_; diff --git a/common/options_switches.cc b/common/options_switches.cc index 6f068a19d258..74ff309b25bf 100644 --- a/common/options_switches.cc +++ b/common/options_switches.cc @@ -31,6 +31,8 @@ const char kKiosk[] = "kiosk"; // Make windows stays on the top of all other windows. const char kAlwaysOnTop[] = "always-on-top"; +const char kIframeSecurity[] = "iframe-security"; + } // namespace switches } // namespace atom diff --git a/common/options_switches.h b/common/options_switches.h index ee61044df2ef..fa658d2c9a3a 100644 --- a/common/options_switches.h +++ b/common/options_switches.h @@ -26,6 +26,7 @@ extern const char kResizable[]; extern const char kFullscreen[]; extern const char kKiosk[]; extern const char kAlwaysOnTop[]; +extern const char kIframeSecurity[]; } // namespace switches From d4929de33c3a057a0144e504d8e2696a489f59c0 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 30 Jan 2014 22:47:21 +0800 Subject: [PATCH 04/15] Add iframe-security support. --- renderer/atom_render_view_observer.cc | 6 +++++ renderer/atom_renderer_client.cc | 37 +++++++++++++++++++++++++-- renderer/atom_renderer_client.h | 10 ++++++++ 3 files changed, 51 insertions(+), 2 deletions(-) diff --git a/renderer/atom_render_view_observer.cc b/renderer/atom_render_view_observer.cc index 960be5c0207f..ec6a531e5660 100644 --- a/renderer/atom_render_view_observer.cc +++ b/renderer/atom_render_view_observer.cc @@ -5,12 +5,14 @@ #include "renderer/atom_render_view_observer.h" #include "common/api/api_messages.h" +#include "content/public/renderer/render_view.h" #include "ipc/ipc_message_macros.h" #include "renderer/api/atom_renderer_bindings.h" #include "renderer/atom_renderer_client.h" #include "third_party/WebKit/public/web/WebDraggableRegion.h" #include "third_party/WebKit/public/web/WebDocument.h" #include "third_party/WebKit/public/web/WebFrame.h" +#include "third_party/WebKit/public/web/WebView.h" #include "common/v8/node_common.h" @@ -53,6 +55,10 @@ bool AtomRenderViewObserver::OnMessageReceived(const IPC::Message& message) { void AtomRenderViewObserver::OnBrowserMessage(const string16& channel, const base::ListValue& args) { + WebKit::WebFrame* frame = render_view()->GetWebView()->mainFrame(); + if (!renderer_client_->IsNodeBindingEnabled(frame)) + return; + renderer_client_->atom_bindings()->OnBrowserMessage( render_view(), channel, args); } diff --git a/renderer/atom_renderer_client.cc b/renderer/atom_renderer_client.cc index c89b6c256e68..b215e0bd2a3f 100644 --- a/renderer/atom_renderer_client.cc +++ b/renderer/atom_renderer_client.cc @@ -6,23 +6,39 @@ #include +#include "base/command_line.h" #include "common/node_bindings.h" +#include "common/options_switches.h" #include "renderer/api/atom_renderer_bindings.h" #include "renderer/atom_render_view_observer.h" +#include "third_party/WebKit/public/web/WebFrame.h" #include "common/v8/node_common.h" namespace atom { AtomRendererClient::AtomRendererClient() - : node_bindings_(NodeBindings::Create(false)), - atom_bindings_(new AtomRendererBindings) { + : iframe_security_(FULL) { + std::string security = CommandLine::ForCurrentProcess()-> + GetSwitchValueASCII(switches::kIframeSecurity); + if (security == "manual") + iframe_security_ = MANUAL; + else if (security == "none") + iframe_security_ = NONE; + + if (IsNodeBindingEnabled()) { + node_bindings_.reset(NodeBindings::Create(false)); + atom_bindings_.reset(new AtomRendererBindings); + } } AtomRendererClient::~AtomRendererClient() { } void AtomRendererClient::RenderThreadStarted() { + if (!IsNodeBindingEnabled()) + return; + node_bindings_->Initialize(); node_bindings_->PrepareMessageLoop(); @@ -43,6 +59,9 @@ void AtomRendererClient::DidCreateScriptContext(WebKit::WebFrame* frame, v8::Handle context, int extension_group, int world_id) { + if (!IsNodeBindingEnabled(frame)) + return; + v8::Context::Scope scope(context); // Check the existance of process object to prevent duplicate initialization. @@ -70,6 +89,9 @@ void AtomRendererClient::WillReleaseScriptContext( WebKit::WebFrame* frame, v8::Handle context, int world_id) { + if (!IsNodeBindingEnabled(frame)) + return; + node::Environment* env = node::Environment::GetCurrent(context); if (env == NULL) { LOG(ERROR) << "Encounter a non-node context when releasing script context"; @@ -108,4 +130,15 @@ bool AtomRendererClient::ShouldFork(WebKit::WebFrame* frame, return true; } +bool AtomRendererClient::IsNodeBindingEnabled(WebKit::WebFrame* frame) { + if (iframe_security_ == FULL) + return false; + else if (iframe_security_ == MANUAL && + frame != NULL && + frame->uniqueName().utf8().find("-enable-node") == std::string::npos) + return false; + else + return true; +} + } // namespace atom diff --git a/renderer/atom_renderer_client.h b/renderer/atom_renderer_client.h index 3dde5eb1d950..54d173b953b7 100644 --- a/renderer/atom_renderer_client.h +++ b/renderer/atom_renderer_client.h @@ -23,9 +23,17 @@ class AtomRendererClient : public content::ContentRendererClient { AtomRendererClient(); virtual ~AtomRendererClient(); + bool IsNodeBindingEnabled(WebKit::WebFrame* frame = NULL); + AtomRendererBindings* atom_bindings() const { return atom_bindings_.get(); } private: + enum IframeSecurity { + FULL, + MANUAL, + NONE, + }; + virtual void RenderThreadStarted() OVERRIDE; virtual void RenderViewCreated(content::RenderView*) OVERRIDE; virtual void DidCreateScriptContext(WebKit::WebFrame* frame, @@ -47,6 +55,8 @@ class AtomRendererClient : public content::ContentRendererClient { scoped_ptr node_bindings_; scoped_ptr atom_bindings_; + IframeSecurity iframe_security_; + DISALLOW_COPY_AND_ASSIGN(AtomRendererClient); }; From ec00da416f85d113e902fe4ccca3f5dda0a4856b Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 30 Jan 2014 23:20:12 +0800 Subject: [PATCH 05/15] Rename iframe-security to node-integration. --- browser/atom_browser_client.cc | 6 +++--- browser/native_window.cc | 4 ++-- browser/native_window.h | 4 ++-- common/options_switches.cc | 2 +- common/options_switches.h | 2 +- renderer/atom_render_view_observer.cc | 3 +++ renderer/atom_renderer_client.cc | 31 +++++++++++++++++++-------- renderer/atom_renderer_client.h | 15 ++++++++----- 8 files changed, 44 insertions(+), 23 deletions(-) diff --git a/browser/atom_browser_client.cc b/browser/atom_browser_client.cc index b58057102495..247f52db3efc 100644 --- a/browser/atom_browser_client.cc +++ b/browser/atom_browser_client.cc @@ -63,15 +63,15 @@ bool AtomBrowserClient::ShouldSwapProcessesForNavigation( void AtomBrowserClient::AppendExtraCommandLineSwitches( CommandLine* command_line, int child_process_id) { - // Append --iframe-security to renderer process. + // Append --node-integration to renderer process. WindowList* list = WindowList::GetInstance(); for (WindowList::const_iterator iter = list->begin(); iter != list->end(); ++iter) { NativeWindow* window = *iter; int id = window->GetWebContents()->GetRenderProcessHost()->GetID(); if (id == child_process_id) { - command_line->AppendSwitchASCII(switches::kIframeSecurity, - window->iframe_security()); + command_line->AppendSwitchASCII(switches::kNodeIntegration, + window->node_integration()); return; } } diff --git a/browser/native_window.cc b/browser/native_window.cc index b8ca401b8aaa..c81625c367d6 100644 --- a/browser/native_window.cc +++ b/browser/native_window.cc @@ -48,7 +48,7 @@ NativeWindow::NativeWindow(content::WebContents* web_contents, : content::WebContentsObserver(web_contents), has_frame_(true), is_closed_(false), - iframe_security_("full"), + node_integration_("all"), weak_factory_(this), inspectable_web_contents_( brightray::InspectableWebContents::Create(web_contents)) { @@ -60,7 +60,7 @@ NativeWindow::NativeWindow(content::WebContents* web_contents, LOG(ERROR) << "Failed to set icon to " << icon; // Read iframe security before any navigation. - options->GetString(switches::kIframeSecurity, &iframe_security_); + options->GetString(switches::kNodeIntegration, &node_integration_); web_contents->SetDelegate(this); diff --git a/browser/native_window.h b/browser/native_window.h index 462d96c19955..ad6e8a152b76 100644 --- a/browser/native_window.h +++ b/browser/native_window.h @@ -140,7 +140,7 @@ class NativeWindow : public brightray::DefaultWebContentsDelegate, } bool has_frame() const { return has_frame_; } - std::string iframe_security() const { return iframe_security_; } + std::string node_integration() const { return node_integration_; } protected: explicit NativeWindow(content::WebContents* web_contents, @@ -221,7 +221,7 @@ class NativeWindow : public brightray::DefaultWebContentsDelegate, bool is_closed_; // The security token of iframe. - std::string iframe_security_; + std::string node_integration_; // Closure that would be called when window is unresponsive when closing, // it should be cancelled when we can prove that the window is responsive. diff --git a/common/options_switches.cc b/common/options_switches.cc index 74ff309b25bf..f3d849ef176c 100644 --- a/common/options_switches.cc +++ b/common/options_switches.cc @@ -31,7 +31,7 @@ const char kKiosk[] = "kiosk"; // Make windows stays on the top of all other windows. const char kAlwaysOnTop[] = "always-on-top"; -const char kIframeSecurity[] = "iframe-security"; +const char kNodeIntegration[] = "node-integration"; } // namespace switches diff --git a/common/options_switches.h b/common/options_switches.h index fa658d2c9a3a..ad6b68b2eaa5 100644 --- a/common/options_switches.h +++ b/common/options_switches.h @@ -26,7 +26,7 @@ extern const char kResizable[]; extern const char kFullscreen[]; extern const char kKiosk[]; extern const char kAlwaysOnTop[]; -extern const char kIframeSecurity[]; +extern const char kNodeIntegration[]; } // namespace switches diff --git a/renderer/atom_render_view_observer.cc b/renderer/atom_render_view_observer.cc index ec6a531e5660..69d811bf5acf 100644 --- a/renderer/atom_render_view_observer.cc +++ b/renderer/atom_render_view_observer.cc @@ -55,6 +55,9 @@ bool AtomRenderViewObserver::OnMessageReceived(const IPC::Message& message) { void AtomRenderViewObserver::OnBrowserMessage(const string16& channel, const base::ListValue& args) { + if (!render_view()->GetWebView()) + return; + WebKit::WebFrame* frame = render_view()->GetWebView()->mainFrame(); if (!renderer_client_->IsNodeBindingEnabled(frame)) return; diff --git a/renderer/atom_renderer_client.cc b/renderer/atom_renderer_client.cc index b215e0bd2a3f..f12fe4c1c269 100644 --- a/renderer/atom_renderer_client.cc +++ b/renderer/atom_renderer_client.cc @@ -18,13 +18,17 @@ namespace atom { AtomRendererClient::AtomRendererClient() - : iframe_security_(FULL) { - std::string security = CommandLine::ForCurrentProcess()-> - GetSwitchValueASCII(switches::kIframeSecurity); - if (security == "manual") - iframe_security_ = MANUAL; - else if (security == "none") - iframe_security_ = NONE; + : node_integration_(ALL), + main_frame_(NULL) { + // Translate the token. + std::string token = CommandLine::ForCurrentProcess()-> + GetSwitchValueASCII(switches::kNodeIntegration); + if (token == "except-iframe") + node_integration_ = EXCEPT_IFRAME; + else if (token == "manual-enable-iframe") + node_integration_ = MANUAL_ENABLE_IFRAME; + else if (token == "disable") + node_integration_ = DISABLE; if (IsNodeBindingEnabled()) { node_bindings_.reset(NodeBindings::Create(false)); @@ -59,6 +63,10 @@ void AtomRendererClient::DidCreateScriptContext(WebKit::WebFrame* frame, v8::Handle context, int extension_group, int world_id) { + // The first web frame is the main frame. + if (main_frame_ == NULL) + main_frame_ = frame; + if (!IsNodeBindingEnabled(frame)) return; @@ -131,12 +139,17 @@ bool AtomRendererClient::ShouldFork(WebKit::WebFrame* frame, } bool AtomRendererClient::IsNodeBindingEnabled(WebKit::WebFrame* frame) { - if (iframe_security_ == FULL) + if (node_integration_ == DISABLE) return false; - else if (iframe_security_ == MANUAL && + // Node integration is enabled in main frame unless explictly disabled. + else if (frame == main_frame_) + return true; + else if (node_integration_ == MANUAL_ENABLE_IFRAME && frame != NULL && frame->uniqueName().utf8().find("-enable-node") == std::string::npos) return false; + else if (node_integration_ == EXCEPT_IFRAME && frame != NULL) + return false; else return true; } diff --git a/renderer/atom_renderer_client.h b/renderer/atom_renderer_client.h index 54d173b953b7..bc7aab740a5e 100644 --- a/renderer/atom_renderer_client.h +++ b/renderer/atom_renderer_client.h @@ -28,10 +28,11 @@ class AtomRendererClient : public content::ContentRendererClient { AtomRendererBindings* atom_bindings() const { return atom_bindings_.get(); } private: - enum IframeSecurity { - FULL, - MANUAL, - NONE, + enum NodeIntegration { + ALL, + EXCEPT_IFRAME, + MANUAL_ENABLE_IFRAME, + DISABLE, }; virtual void RenderThreadStarted() OVERRIDE; @@ -55,7 +56,11 @@ class AtomRendererClient : public content::ContentRendererClient { scoped_ptr node_bindings_; scoped_ptr atom_bindings_; - IframeSecurity iframe_security_; + // The level of node integration we should support. + NodeIntegration node_integration_; + + // The main frame. + WebKit::WebFrame* main_frame_; DISALLOW_COPY_AND_ASSIGN(AtomRendererClient); }; From 61b69a4e8a93a0160406032405338a04faec8101 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 31 Jan 2014 10:30:16 +0800 Subject: [PATCH 06/15] Fix loss of --node-integration token after refresh. --- browser/atom_browser_client.cc | 55 +++++++++++++++++++++++++++------- browser/atom_browser_client.h | 3 ++ 2 files changed, 47 insertions(+), 11 deletions(-) diff --git a/browser/atom_browser_client.cc b/browser/atom_browser_client.cc index 247f52db3efc..2f43c2b01808 100644 --- a/browser/atom_browser_client.cc +++ b/browser/atom_browser_client.cc @@ -12,12 +12,30 @@ #include "browser/window_list.h" #include "common/options_switches.h" #include "content/public/browser/render_process_host.h" +#include "content/public/browser/site_instance.h" #include "content/public/browser/web_contents.h" #include "webkit/common/webpreferences.h" namespace atom { -AtomBrowserClient::AtomBrowserClient() { +namespace { + +struct FindByProcessId { + FindByProcessId(int child_process_id) : child_process_id_(child_process_id) { + } + + bool operator() (NativeWindow* const window) { + int id = window->GetWebContents()->GetRenderProcessHost()->GetID(); + return id == child_process_id_; + } + + int child_process_id_; +}; + +} // namespace + +AtomBrowserClient::AtomBrowserClient() + : dying_render_process_(NULL) { } AtomBrowserClient::~AtomBrowserClient() { @@ -56,6 +74,9 @@ bool AtomBrowserClient::ShouldSwapProcessesForNavigation( content::SiteInstance* site_instance, const GURL& current_url, const GURL& new_url) { + if (site_instance->HasProcess()) + dying_render_process_ = site_instance->GetProcess(); + // Restart renderer process for all navigations. return true; } @@ -63,18 +84,30 @@ bool AtomBrowserClient::ShouldSwapProcessesForNavigation( void AtomBrowserClient::AppendExtraCommandLineSwitches( CommandLine* command_line, int child_process_id) { - // Append --node-integration to renderer process. WindowList* list = WindowList::GetInstance(); - for (WindowList::const_iterator iter = list->begin(); iter != list->end(); - ++iter) { - NativeWindow* window = *iter; - int id = window->GetWebContents()->GetRenderProcessHost()->GetID(); - if (id == child_process_id) { - command_line->AppendSwitchASCII(switches::kNodeIntegration, - window->node_integration()); - return; - } + NativeWindow* window = NULL; + + // Find the owner of this child process. + WindowList::const_iterator iter = std::find_if( + list->begin(), list->end(), FindByProcessId(child_process_id)); + if (iter != list->end()) + window = *iter; + + // If the render process is a newly started one, which means the window still + // uses the old going-to-be-swapped render process, then we try to find the + // window from the swapped render process. + if (window == NULL && dying_render_process_ != NULL) { + child_process_id = dying_render_process_->GetID(); + WindowList::const_iterator iter = std::find_if( + list->begin(), list->end(), FindByProcessId(child_process_id)); + if (iter != list->end()) + window = *iter; } + + // Append --node-integration to renderer process. + if (window != NULL) + command_line->AppendSwitchASCII(switches::kNodeIntegration, + window->node_integration()); } brightray::BrowserMainParts* AtomBrowserClient::OverrideCreateBrowserMainParts( diff --git a/browser/atom_browser_client.h b/browser/atom_browser_client.h index 183b647837ec..4fe1131dc428 100644 --- a/browser/atom_browser_client.h +++ b/browser/atom_browser_client.h @@ -32,6 +32,9 @@ class AtomBrowserClient : public brightray::BrowserClient { virtual brightray::BrowserMainParts* OverrideCreateBrowserMainParts( const content::MainFunctionParams&) OVERRIDE; + // The render process which would be swapped out soon. + content::RenderProcessHost* dying_render_process_; + DISALLOW_COPY_AND_ASSIGN(AtomBrowserClient); }; From 192014cc3f1b0e108080d429349fc4bc92e863dc Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 31 Jan 2014 10:41:20 +0800 Subject: [PATCH 07/15] Do not use plain string iterals. --- renderer/atom_renderer_client.cc | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/renderer/atom_renderer_client.cc b/renderer/atom_renderer_client.cc index f12fe4c1c269..b5e606a0e588 100644 --- a/renderer/atom_renderer_client.cc +++ b/renderer/atom_renderer_client.cc @@ -17,17 +17,26 @@ namespace atom { +namespace { + +const char* kExceptIframe = "except-iframe"; +const char* kManualEnableIframe = "manual-enable-iframe"; +const char* kDisable = "disable"; +const char* kEnableNodeIntegration = "enable-node-integration"; + +} // namespace + AtomRendererClient::AtomRendererClient() : node_integration_(ALL), main_frame_(NULL) { // Translate the token. std::string token = CommandLine::ForCurrentProcess()-> GetSwitchValueASCII(switches::kNodeIntegration); - if (token == "except-iframe") + if (token == kExceptIframe) node_integration_ = EXCEPT_IFRAME; - else if (token == "manual-enable-iframe") + else if (token == kManualEnableIframe) node_integration_ = MANUAL_ENABLE_IFRAME; - else if (token == "disable") + else if (token == kDisable) node_integration_ = DISABLE; if (IsNodeBindingEnabled()) { @@ -146,7 +155,8 @@ bool AtomRendererClient::IsNodeBindingEnabled(WebKit::WebFrame* frame) { return true; else if (node_integration_ == MANUAL_ENABLE_IFRAME && frame != NULL && - frame->uniqueName().utf8().find("-enable-node") == std::string::npos) + frame->uniqueName().utf8().find(kEnableNodeIntegration) + == std::string::npos) return false; else if (node_integration_ == EXCEPT_IFRAME && frame != NULL) return false; From e0f660301c01ca97080ef837674a519929ff2f32 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 31 Jan 2014 12:09:43 +0800 Subject: [PATCH 08/15] Specify the commit of libchromiumcontent to download. --- script/bootstrap.py | 4 +++- script/create-dist.py | 4 +++- vendor/brightray | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/script/bootstrap.py b/script/bootstrap.py index 10dfde5b3dd4..d9c01ebe35d6 100755 --- a/script/bootstrap.py +++ b/script/bootstrap.py @@ -12,6 +12,7 @@ SOURCE_ROOT = os.path.abspath(os.path.dirname(os.path.dirname(__file__))) VENDOR_DIR = os.path.join(SOURCE_ROOT, 'vendor') BASE_URL = 'https://gh-contractor-zcbenz.s3.amazonaws.com/libchromiumcontent' PYTHON_26_URL = 'https://chromium.googlesource.com/chromium/deps/python_26' +LIBCHROMIUMCONTENT_COMMIT = 'b27290717c08f8c6a58067d3c3725d68b4e6a2e5' def main(): @@ -52,7 +53,8 @@ def update_submodules(): def bootstrap_brightray(url): bootstrap = os.path.join(VENDOR_DIR, 'brightray', 'script', 'bootstrap') - subprocess.check_call([sys.executable, bootstrap, url]) + subprocess.check_call([sys.executable, bootstrap, '--commit', + LIBCHROMIUMCONTENT_COMMIT, url]) def update_apm(): diff --git a/script/create-dist.py b/script/create-dist.py index 5d96a8f0a1f8..02ef94819167 100755 --- a/script/create-dist.py +++ b/script/create-dist.py @@ -14,6 +14,7 @@ from lib.util import scoped_cwd, rm_rf, get_atom_shell_version, make_zip, \ ATOM_SHELL_VRESION = get_atom_shell_version() NODE_VERSION = 'v0.11.10' BASE_URL = 'https://gh-contractor-zcbenz.s3.amazonaws.com/libchromiumcontent' +LIBCHROMIUMCONTENT_COMMIT = 'b27290717c08f8c6a58067d3c3725d68b4e6a2e5' SOURCE_ROOT = os.path.abspath(os.path.dirname(os.path.dirname(__file__))) DIST_DIR = os.path.join(SOURCE_ROOT, 'dist') @@ -163,7 +164,8 @@ def download_libchromiumcontent_symbols(url): download = os.path.join(brightray_dir, 'libchromiumcontent', 'script', 'download') - subprocess.check_call([sys.executable, download, '-f', '-s', url, target_dir]) + subprocess.check_call([sys.executable, download, '-f', '-s', '-c', + LIBCHROMIUMCONTENT_COMMIT, url, target_dir]) def create_symbols(): diff --git a/vendor/brightray b/vendor/brightray index 6fa8c1c1fce5..785e744bd4a4 160000 --- a/vendor/brightray +++ b/vendor/brightray @@ -1 +1 @@ -Subproject commit 6fa8c1c1fce59577bc0a2c03378ad16c20aef4e7 +Subproject commit 785e744bd4a433bad91a3f71d294f85401606eb5 From 6478244fbf38947828257744c2dab91a4260f034 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 31 Jan 2014 12:18:30 +0800 Subject: [PATCH 09/15] Put common constants into one file. --- script/bootstrap.py | 3 +-- script/create-dist.py | 4 +--- script/lib/config.py | 5 +++++ script/upload.py | 2 +- 4 files changed, 8 insertions(+), 6 deletions(-) create mode 100644 script/lib/config.py diff --git a/script/bootstrap.py b/script/bootstrap.py index d9c01ebe35d6..b4101cd10f02 100755 --- a/script/bootstrap.py +++ b/script/bootstrap.py @@ -5,14 +5,13 @@ import os import subprocess import sys +from lib.config import LIBCHROMIUMCONTENT_COMMIT, BASE_URL from lib.util import scoped_cwd SOURCE_ROOT = os.path.abspath(os.path.dirname(os.path.dirname(__file__))) VENDOR_DIR = os.path.join(SOURCE_ROOT, 'vendor') -BASE_URL = 'https://gh-contractor-zcbenz.s3.amazonaws.com/libchromiumcontent' PYTHON_26_URL = 'https://chromium.googlesource.com/chromium/deps/python_26' -LIBCHROMIUMCONTENT_COMMIT = 'b27290717c08f8c6a58067d3c3725d68b4e6a2e5' def main(): diff --git a/script/create-dist.py b/script/create-dist.py index 02ef94819167..d0fd8bcc139a 100755 --- a/script/create-dist.py +++ b/script/create-dist.py @@ -7,14 +7,12 @@ import subprocess import sys import tarfile +from lib.config import LIBCHROMIUMCONTENT_COMMIT, BASE_URL, NODE_VERSION from lib.util import scoped_cwd, rm_rf, get_atom_shell_version, make_zip, \ safe_mkdir ATOM_SHELL_VRESION = get_atom_shell_version() -NODE_VERSION = 'v0.11.10' -BASE_URL = 'https://gh-contractor-zcbenz.s3.amazonaws.com/libchromiumcontent' -LIBCHROMIUMCONTENT_COMMIT = 'b27290717c08f8c6a58067d3c3725d68b4e6a2e5' SOURCE_ROOT = os.path.abspath(os.path.dirname(os.path.dirname(__file__))) DIST_DIR = os.path.join(SOURCE_ROOT, 'dist') diff --git a/script/lib/config.py b/script/lib/config.py new file mode 100644 index 000000000000..5c746e294144 --- /dev/null +++ b/script/lib/config.py @@ -0,0 +1,5 @@ +#!/usr/bin/env python + +NODE_VERSION = 'v0.11.10' +BASE_URL = 'https://gh-contractor-zcbenz.s3.amazonaws.com/libchromiumcontent' +LIBCHROMIUMCONTENT_COMMIT = 'b27290717c08f8c6a58067d3c3725d68b4e6a2e5' diff --git a/script/upload.py b/script/upload.py index c51cc22eaea5..e93581e58996 100755 --- a/script/upload.py +++ b/script/upload.py @@ -8,6 +8,7 @@ import subprocess import sys import tempfile +from lib.config import NODE_VERSION from lib.util import get_atom_shell_version, scoped_cwd, safe_mkdir from lib.github import GitHub @@ -21,7 +22,6 @@ TARGET_PLATFORM = { ATOM_SHELL_REPO = 'atom/atom-shell' ATOM_SHELL_VRESION = get_atom_shell_version() -NODE_VERSION = 'v0.11.10' SOURCE_ROOT = os.path.abspath(os.path.dirname(os.path.dirname(__file__))) OUT_DIR = os.path.join(SOURCE_ROOT, 'out', 'Release') From bd51a4c8cf3937c1be64b6838547cedf1c9438b1 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 31 Jan 2014 15:09:13 +0800 Subject: [PATCH 10/15] Fix crash when opening multiple pages at the same time. --- browser/atom_browser_client.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/browser/atom_browser_client.cc b/browser/atom_browser_client.cc index 2f43c2b01808..512d1f58661b 100644 --- a/browser/atom_browser_client.cc +++ b/browser/atom_browser_client.cc @@ -108,6 +108,8 @@ void AtomBrowserClient::AppendExtraCommandLineSwitches( if (window != NULL) command_line->AppendSwitchASCII(switches::kNodeIntegration, window->node_integration()); + + dying_render_process_ = NULL; } brightray::BrowserMainParts* AtomBrowserClient::OverrideCreateBrowserMainParts( From 18fdbb6432e4112e8474b61d44baa53136b6620e Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 31 Jan 2014 15:22:32 +0800 Subject: [PATCH 11/15] Add docs on the node-integration setting. --- docs/api/browser/browser-window.md | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/docs/api/browser/browser-window.md b/docs/api/browser/browser-window.md index 3500b9c68040..66b875771ebd 100644 --- a/docs/api/browser/browser-window.md +++ b/docs/api/browser/browser-window.md @@ -18,9 +18,6 @@ win.show(); You can also create a window without chrome by using [Frameless Window](frameless-window.md) API. - -**Note:** Be careful not to use `window` as the variable name. - ## Class: BrowserWindow `BrowserWindow` is an @@ -44,11 +41,31 @@ You can also create a window without chrome by using * `show` Boolean - Whether window should be shown when created * `frame` Boolean - Specify `false` to create a [Frameless Window](frameless-window.md) + * `node-integration` String - Can be `all`, `except-iframe`, + `manual-enable-iframe` or `disable`. Creates a new `BrowserWindow` with native properties set by the `options`. Usually you only need to set the `width` and `height`, other properties will have decent default values. +By default the `node-integration` option is `all`, which means node integration +is available to the main page and all its iframes. You can also set it to +`except-iframe`, which would disable node integration in all iframes, or +`manual-enable-iframe`, which is like `except-iframe`, but would enable iframes +whose name is suffixed by `-enable-node-integration`. And setting to `disable` +would disable the node integration in both the main page and its iframes. + +An example of enable node integration in iframe with `node-integration` set to +`manual-enable-iframe`: + +```html + + + + + +``` + ### Event: 'page-title-updated' * `event` Event From 0df59e27143e08423da3029dc9895ac48bb0b3e2 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 31 Jan 2014 15:53:01 +0800 Subject: [PATCH 12/15] :lipstick: Fix cppling warning. --- browser/atom_browser_client.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/browser/atom_browser_client.cc b/browser/atom_browser_client.cc index 512d1f58661b..1f7351c92864 100644 --- a/browser/atom_browser_client.cc +++ b/browser/atom_browser_client.cc @@ -21,7 +21,8 @@ namespace atom { namespace { struct FindByProcessId { - FindByProcessId(int child_process_id) : child_process_id_(child_process_id) { + explicit FindByProcessId(int child_process_id) + : child_process_id_(child_process_id) { } bool operator() (NativeWindow* const window) { From 2634328720bf018d4643ee6d4a3aea7ecca62ca2 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 31 Jan 2014 16:40:20 +0800 Subject: [PATCH 13/15] Fix how we filter out atom-shell switches in process.argv. --- app/atom_main_delegate.cc | 5 ++++- browser/default_app/main.js | 6 +----- browser/lib/init.coffee | 5 +++++ 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/app/atom_main_delegate.cc b/app/atom_main_delegate.cc index 816df2916b13..d8f0c693d494 100644 --- a/app/atom_main_delegate.cc +++ b/app/atom_main_delegate.cc @@ -58,6 +58,9 @@ void AtomMainDelegate::PreSandboxStartup() { if (process_type == switches::kRendererProcess) return; + // Add a flag to mark the start of switches added by atom-shell. + command_line->AppendSwitch("atom-shell-switches-start"); + // Disable renderer sandbox for most of node's functions. command_line->AppendSwitch(switches::kNoSandbox); @@ -66,7 +69,7 @@ void AtomMainDelegate::PreSandboxStartup() { command_line->AppendSwitch(switches::kDisableAcceleratedCompositing); // Add a flag to mark the end of switches added by atom-shell. - command_line->AppendSwitch("no-more-atom-shell-switches"); + command_line->AppendSwitch("atom-shell-switches-end"); } void AtomMainDelegate::InitializeResourceBundle() { diff --git a/browser/default_app/main.js b/browser/default_app/main.js index acf1a38976df..b3e3bcb03640 100644 --- a/browser/default_app/main.js +++ b/browser/default_app/main.js @@ -8,11 +8,7 @@ app.on('window-all-closed', function() { app.quit(); }); -// Pick out switches appended by atom-shell. -var endMark = process.argv.indexOf('--no-more-atom-shell-switches'); -process.execArgv = process.argv.splice(1, endMark) - -var argv = optimist(process.argv.slice(1)).argv; +var argv = optimist(process.argv.slice(1)).boolean('ci').argv; // Start the specified app if there is one specified in command line, otherwise // start the default app. diff --git a/browser/lib/init.coffee b/browser/lib/init.coffee index 950d4671ac56..1b22b3d259b3 100644 --- a/browser/lib/init.coffee +++ b/browser/lib/init.coffee @@ -9,6 +9,11 @@ process.resourcesPath = path.resolve process.argv[1], '..', '..', '..' # we need to restore it here. process.argv.splice 1, 1 +# Pick out switches appended by atom-shell. +startMark = process.argv.indexOf '--atom-shell-switches-start' +endMark = process.argv.indexOf '--atom-shell-switches-end' +process.execArgv = process.argv.splice startMark, endMark - startMark + 1 + # Add browser/api/lib to require's search paths, # which contains javascript part of Atom's built-in libraries. globalPaths = require('module').globalPaths From fe30880ec03e795376221fd868d2741f19f5a275 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 31 Jan 2014 17:39:31 +0800 Subject: [PATCH 14/15] Add Info.plist for Atom Framework, fixes #171. --- atom.gyp | 1 + common/mac/Info.plist | 14 ++++++++++++++ 2 files changed, 15 insertions(+) create mode 100644 common/mac/Info.plist diff --git a/atom.gyp b/atom.gyp index 88d9755d3827..28b53e826a21 100644 --- a/atom.gyp +++ b/atom.gyp @@ -503,6 +503,7 @@ '<(libchromiumcontent_resources_dir)/content_shell.pak', ], 'xcode_settings': { + 'INFOPLIST_FILE': 'common/mac/Info.plist', 'LIBRARY_SEARCH_PATHS': [ '<(libchromiumcontent_library_dir)', ], diff --git a/common/mac/Info.plist b/common/mac/Info.plist new file mode 100644 index 000000000000..e259c9e21da9 --- /dev/null +++ b/common/mac/Info.plist @@ -0,0 +1,14 @@ + + + + + CFBundleExecutable + Atom Framework + CFBundleIdentifier + com.github.AtomFramework + CFBundleName + Atom Framework + CFBundlePackageType + FMWK + + From a85075103f7e50fe9b6e79433afa818c89fe6bd9 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 31 Jan 2014 19:34:31 +0800 Subject: [PATCH 15/15] Move resources file under resources/ --- atom.gyp | 16 ++++++++-------- browser/{ => resources}/mac/Info.plist | 0 browser/{ => resources}/mac/atom.icns | Bin {app => browser/resources}/win/atom.ico | Bin {app => browser/resources}/win/atom.rc | 0 {app => browser/resources}/win/resource.h | 0 common/{ => resources}/mac/Info.plist | 0 {browser => common/resources}/mac/MainMenu.xib | 0 renderer/{ => resources}/mac/Info.plist | 0 script/bump-version.py | 4 ++-- 10 files changed, 10 insertions(+), 10 deletions(-) rename browser/{ => resources}/mac/Info.plist (100%) rename browser/{ => resources}/mac/atom.icns (100%) rename {app => browser/resources}/win/atom.ico (100%) rename {app => browser/resources}/win/atom.rc (100%) rename {app => browser/resources}/win/resource.h (100%) rename common/{ => resources}/mac/Info.plist (100%) rename {browser => common/resources}/mac/MainMenu.xib (100%) rename renderer/{ => resources}/mac/Info.plist (100%) diff --git a/atom.gyp b/atom.gyp index 28b53e826a21..9956f0096e1b 100644 --- a/atom.gyp +++ b/atom.gyp @@ -8,7 +8,7 @@ 'app/atom_main.h', ], 'bundle_sources': [ - 'browser/mac/atom.icns', + 'browser/resources/mac/atom.icns', ], 'coffee_sources': [ 'browser/api/lib/app.coffee', @@ -191,9 +191,9 @@ 'conditions': [ ['OS=="win"', { 'app_sources': [ - 'app/win/resource.h', - 'app/win/atom.ico', - 'app/win/atom.rc', + 'browser/resources/win/resource.h', + 'browser/resources/win/atom.ico', + 'browser/resources/win/atom.rc', '<(libchromiumcontent_src_dir)/content/app/startup_helper_win.cc', ], }], # OS=="win" @@ -249,7 +249,7 @@ '<(project_name)_helper', ], 'xcode_settings': { - 'INFOPLIST_FILE': 'browser/mac/Info.plist', + 'INFOPLIST_FILE': 'browser/resources/mac/Info.plist', 'LD_RUNPATH_SEARCH_PATHS': [ '@executable_path/../Frameworks', ], @@ -499,11 +499,11 @@ }, 'mac_bundle': 1, 'mac_bundle_resources': [ - 'browser/mac/MainMenu.xib', + 'common/resources/mac/MainMenu.xib', '<(libchromiumcontent_resources_dir)/content_shell.pak', ], 'xcode_settings': { - 'INFOPLIST_FILE': 'common/mac/Info.plist', + 'INFOPLIST_FILE': 'common/resources/mac/Info.plist', 'LIBRARY_SEARCH_PATHS': [ '<(libchromiumcontent_library_dir)', ], @@ -564,7 +564,7 @@ ], 'mac_bundle': 1, 'xcode_settings': { - 'INFOPLIST_FILE': 'renderer/mac/Info.plist', + 'INFOPLIST_FILE': 'renderer/resources/mac/Info.plist', 'LD_RUNPATH_SEARCH_PATHS': [ '@executable_path/../../..', ], diff --git a/browser/mac/Info.plist b/browser/resources/mac/Info.plist similarity index 100% rename from browser/mac/Info.plist rename to browser/resources/mac/Info.plist diff --git a/browser/mac/atom.icns b/browser/resources/mac/atom.icns similarity index 100% rename from browser/mac/atom.icns rename to browser/resources/mac/atom.icns diff --git a/app/win/atom.ico b/browser/resources/win/atom.ico similarity index 100% rename from app/win/atom.ico rename to browser/resources/win/atom.ico diff --git a/app/win/atom.rc b/browser/resources/win/atom.rc similarity index 100% rename from app/win/atom.rc rename to browser/resources/win/atom.rc diff --git a/app/win/resource.h b/browser/resources/win/resource.h similarity index 100% rename from app/win/resource.h rename to browser/resources/win/resource.h diff --git a/common/mac/Info.plist b/common/resources/mac/Info.plist similarity index 100% rename from common/mac/Info.plist rename to common/resources/mac/Info.plist diff --git a/browser/mac/MainMenu.xib b/common/resources/mac/MainMenu.xib similarity index 100% rename from browser/mac/MainMenu.xib rename to common/resources/mac/MainMenu.xib diff --git a/renderer/mac/Info.plist b/renderer/resources/mac/Info.plist similarity index 100% rename from renderer/mac/Info.plist rename to renderer/resources/mac/Info.plist diff --git a/script/bump-version.py b/script/bump-version.py index 7d5f52f5d2db..1baaf355755e 100755 --- a/script/bump-version.py +++ b/script/bump-version.py @@ -71,7 +71,7 @@ def update_win_rc(version, versions): pattern_fvs = re.compile(' *VALUE "FileVersion", "[0-9.]+"') pattern_pvs = re.compile(' *VALUE "ProductVersion", "[0-9.]+"') - win_rc = os.path.join('app', 'win', 'atom.rc') + win_rc = os.path.join('browser', 'resources', 'win', 'atom.rc') with open(win_rc, 'r') as f: lines = f.readlines() @@ -109,7 +109,7 @@ def update_version_h(versions): def update_info_plist(version): - info_plist = os.path.join('browser', 'mac', 'Info.plist') + info_plist = os.path.join('browser', 'resources', 'mac', 'Info.plist') with open(info_plist, 'r') as f: lines = f.readlines()