Merge branch 'master' into linux

Conflicts:
	atom.gyp
	vendor/apm
	vendor/brightray
This commit is contained in:
Cheng Zhao 2014-02-14 13:17:00 +00:00
commit 4051d2ebdb
85 changed files with 611 additions and 473 deletions

View file

@ -51,6 +51,15 @@ void AtomMainDelegate::PreSandboxStartup() {
InitializeResourceBundle(); InitializeResourceBundle();
CommandLine* command_line = CommandLine::ForCurrentProcess(); 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;
// 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. // Disable renderer sandbox for most of node's functions.
command_line->AppendSwitch(switches::kNoSandbox); command_line->AppendSwitch(switches::kNoSandbox);
@ -60,7 +69,7 @@ void AtomMainDelegate::PreSandboxStartup() {
command_line->AppendSwitch(switches::kDisableAcceleratedCompositing); command_line->AppendSwitch(switches::kDisableAcceleratedCompositing);
// Add a flag to mark the end of switches added by atom-shell. // Add a flag to mark the end of switches added by atom-shell.
command_line->AppendSwitch("no-more-switches"); command_line->AppendSwitch("atom-shell-switches-end");
} }
void AtomMainDelegate::InitializeResourceBundle() { void AtomMainDelegate::InitializeResourceBundle() {

View file

@ -8,7 +8,7 @@
'app/atom_main.h', 'app/atom_main.h',
], ],
'bundle_sources': [ 'bundle_sources': [
'browser/mac/atom.icns', 'browser/resources/mac/atom.icns',
], ],
'coffee_sources': [ 'coffee_sources': [
'browser/api/lib/app.coffee', 'browser/api/lib/app.coffee',
@ -65,7 +65,6 @@
'browser/api/atom_browser_bindings.h', 'browser/api/atom_browser_bindings.h',
'browser/auto_updater.cc', 'browser/auto_updater.cc',
'browser/auto_updater.h', 'browser/auto_updater.h',
'browser/auto_updater_delegate.cc',
'browser/auto_updater_delegate.h', 'browser/auto_updater_delegate.h',
'browser/auto_updater_linux.cc', 'browser/auto_updater_linux.cc',
'browser/auto_updater_mac.mm', 'browser/auto_updater_mac.mm',
@ -111,18 +110,18 @@
'browser/ui/accelerator_util_gtk.cc', 'browser/ui/accelerator_util_gtk.cc',
'browser/ui/accelerator_util_mac.mm', 'browser/ui/accelerator_util_mac.mm',
'browser/ui/accelerator_util_win.cc', 'browser/ui/accelerator_util_win.cc',
'browser/ui/atom_event_processing_window.h', 'browser/ui/cocoa/atom_menu_controller.h',
'browser/ui/atom_event_processing_window.mm', 'browser/ui/cocoa/atom_menu_controller.mm',
'browser/ui/atom_menu_controller_mac.h', 'browser/ui/cocoa/event_processing_window.h',
'browser/ui/atom_menu_controller_mac.mm', 'browser/ui/cocoa/event_processing_window.mm',
'browser/ui/cocoa/nsalert_synchronous_sheet.h',
'browser/ui/cocoa/nsalert_synchronous_sheet.mm',
'browser/ui/file_dialog.h', 'browser/ui/file_dialog.h',
'browser/ui/file_dialog_mac.mm', 'browser/ui/file_dialog_mac.mm',
'browser/ui/file_dialog_win.cc', 'browser/ui/file_dialog_win.cc',
'browser/ui/message_box.h', 'browser/ui/message_box.h',
'browser/ui/message_box_mac.mm', 'browser/ui/message_box_mac.mm',
'browser/ui/message_box_win.cc', 'browser/ui/message_box_win.cc',
'browser/ui/nsalert_synchronous_sheet_mac.h',
'browser/ui/nsalert_synchronous_sheet_mac.mm',
'browser/ui/gtk/gtk_window_util.cc', 'browser/ui/gtk/gtk_window_util.cc',
'browser/ui/gtk/gtk_window_util.h', 'browser/ui/gtk/gtk_window_util.h',
'browser/ui/win/menu_2.cc', 'browser/ui/win/menu_2.cc',
@ -202,20 +201,13 @@
'conditions': [ 'conditions': [
['OS=="win"', { ['OS=="win"', {
'app_sources': [ 'app_sources': [
'app/win/resource.h', 'browser/resources/win/resource.h',
'app/win/atom.ico', 'browser/resources/win/atom.ico',
'app/win/atom.rc', 'browser/resources/win/atom.rc',
'<(libchromiumcontent_src_dir)/content/app/startup_helper_win.cc', '<(libchromiumcontent_src_dir)/content/app/startup_helper_win.cc',
], ],
}], # OS=="win" }], # OS=="win"
], ],
'fix_framework_link_command': [
'install_name_tool',
'-change',
'@loader_path/../Frameworks/Sparkle.framework/Versions/A/Sparkle',
'@rpath/Sparkle.framework/Versions/A/Sparkle',
'${BUILT_PRODUCTS_DIR}/${EXECUTABLE_PATH}'
],
'atom_source_root': '<!(python tools/atom_source_root.py)', 'atom_source_root': '<!(python tools/atom_source_root.py)',
}, },
'target_defaults': { 'target_defaults': {
@ -260,7 +252,7 @@
'<(project_name)_helper', '<(project_name)_helper',
], ],
'xcode_settings': { 'xcode_settings': {
'INFOPLIST_FILE': 'browser/mac/Info.plist', 'INFOPLIST_FILE': 'browser/resources/mac/Info.plist',
'LD_RUNPATH_SEARCH_PATHS': [ 'LD_RUNPATH_SEARCH_PATHS': [
'@executable_path/../Frameworks', '@executable_path/../Frameworks',
], ],
@ -274,7 +266,9 @@
'files': [ 'files': [
'<(PRODUCT_DIR)/<(product_name) Helper.app', '<(PRODUCT_DIR)/<(product_name) Helper.app',
'<(PRODUCT_DIR)/<(framework_name).framework', '<(PRODUCT_DIR)/<(framework_name).framework',
'frameworks/Sparkle.framework', 'frameworks/Squirrel.framework',
'frameworks/ReactiveCocoa.framework',
'frameworks/Mantle.framework',
], ],
}, },
{ {
@ -285,12 +279,6 @@
}, },
], ],
'postbuilds': [ 'postbuilds': [
{
'postbuild_name': 'Fix Framework Link',
'action': [
'<@(fix_framework_link_command)',
],
},
{ {
# This postbuid step is responsible for creating the following # This postbuid step is responsible for creating the following
# helpers: # helpers:
@ -504,15 +492,18 @@
'link_settings': { 'link_settings': {
'libraries': [ 'libraries': [
'$(SDKROOT)/System/Library/Frameworks/Carbon.framework', '$(SDKROOT)/System/Library/Frameworks/Carbon.framework',
'frameworks/Sparkle.framework', 'frameworks/Squirrel.framework',
'frameworks/ReactiveCocoa.framework',
'frameworks/Mantle.framework',
], ],
}, },
'mac_bundle': 1, 'mac_bundle': 1,
'mac_bundle_resources': [ 'mac_bundle_resources': [
'browser/mac/MainMenu.xib', 'common/resources/mac/MainMenu.xib',
'<(libchromiumcontent_resources_dir)/content_shell.pak', '<(libchromiumcontent_resources_dir)/content_shell.pak',
], ],
'xcode_settings': { 'xcode_settings': {
'INFOPLIST_FILE': 'common/resources/mac/Info.plist',
'LIBRARY_SEARCH_PATHS': [ 'LIBRARY_SEARCH_PATHS': [
'<(libchromiumcontent_library_dir)', '<(libchromiumcontent_library_dir)',
], ],
@ -541,12 +532,6 @@
}, },
], ],
'postbuilds': [ 'postbuilds': [
{
'postbuild_name': 'Fix Framework Link',
'action': [
'<@(fix_framework_link_command)',
],
},
{ {
'postbuild_name': 'Add symlinks for framework subdirectories', 'postbuild_name': 'Add symlinks for framework subdirectories',
'action': [ 'action': [
@ -573,19 +558,11 @@
], ],
'mac_bundle': 1, 'mac_bundle': 1,
'xcode_settings': { 'xcode_settings': {
'INFOPLIST_FILE': 'renderer/mac/Info.plist', 'INFOPLIST_FILE': 'renderer/resources/mac/Info.plist',
'LD_RUNPATH_SEARCH_PATHS': [ 'LD_RUNPATH_SEARCH_PATHS': [
'@executable_path/../../..', '@executable_path/../../..',
], ],
}, },
'postbuilds': [
{
'postbuild_name': 'Fix Framework Link',
'action': [
'<@(fix_framework_link_command)',
],
},
],
}, # target helper }, # target helper
], ],
}], # OS==Mac }], # OS==Mac

View file

@ -174,8 +174,6 @@ void App::DockGetBadgeText(const v8::FunctionCallbackInfo<v8::Value>& args) {
// static // static
void App::Initialize(v8::Handle<v8::Object> target) { void App::Initialize(v8::Handle<v8::Object> target) {
v8::HandleScope handle_scope(v8::Isolate::GetCurrent());
v8::Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(New); v8::Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(New);
t->InstanceTemplate()->SetInternalFieldCount(1); t->InstanceTemplate()->SetInternalFieldCount(1);
t->SetClassName(v8::String::NewSymbol("Application")); t->SetClassName(v8::String::NewSymbol("Application"));

View file

@ -4,6 +4,7 @@
#include "browser/api/atom_api_auto_updater.h" #include "browser/api/atom_api_auto_updater.h"
#include "base/time/time.h"
#include "base/values.h" #include "base/values.h"
#include "browser/auto_updater.h" #include "browser/auto_updater.h"
#include "common/v8/native_type_conversions.h" #include "common/v8/native_type_conversions.h"
@ -17,38 +18,47 @@ namespace api {
AutoUpdater::AutoUpdater(v8::Handle<v8::Object> wrapper) AutoUpdater::AutoUpdater(v8::Handle<v8::Object> wrapper)
: EventEmitter(wrapper) { : EventEmitter(wrapper) {
auto_updater::AutoUpdater::SetDelegate(this); auto_updater::AutoUpdater::SetDelegate(this);
auto_updater::AutoUpdater::Init();
} }
AutoUpdater::~AutoUpdater() { AutoUpdater::~AutoUpdater() {
auto_updater::AutoUpdater::SetDelegate(NULL); auto_updater::AutoUpdater::SetDelegate(NULL);
} }
void AutoUpdater::WillInstallUpdate(const std::string& version, void AutoUpdater::OnError(const std::string& error) {
const base::Closure& install) {
continue_update_ = install;
base::ListValue args; base::ListValue args;
args.AppendString(version); args.AppendString(error);
bool prevent_default = Emit("will-install-update-raw", &args); Emit("error", &args);
if (!prevent_default)
install.Run();
} }
void AutoUpdater::ReadyForUpdateOnQuit(const std::string& version, void AutoUpdater::OnCheckingForUpdate() {
Emit("checking-for-update");
}
void AutoUpdater::OnUpdateAvailable() {
Emit("update-available");
}
void AutoUpdater::OnUpdateNotAvailable() {
Emit("update-not-available");
}
void AutoUpdater::OnUpdateDownloaded(const std::string& release_notes,
const std::string& release_name,
const base::Time& release_date,
const std::string& update_url,
const base::Closure& quit_and_install) { const base::Closure& quit_and_install) {
quit_and_install_ = quit_and_install; quit_and_install_ = quit_and_install;
base::ListValue args; base::ListValue args;
args.AppendString(version); args.AppendString(release_notes);
Emit("ready-for-update-on-quit-raw", &args); args.AppendString(release_name);
args.AppendDouble(release_date.ToJsTime());
args.AppendString(update_url);
Emit("update-downloaded-raw", &args);
} }
// static // static
void AutoUpdater::New(const v8::FunctionCallbackInfo<v8::Value>& args) { void AutoUpdater::New(const v8::FunctionCallbackInfo<v8::Value>& args) {
v8::HandleScope handle_scope(args.GetIsolate());
if (!args.IsConstructCall()) if (!args.IsConstructCall())
return node::ThrowError("Require constructor call"); return node::ThrowError("Require constructor call");
@ -60,39 +70,12 @@ void AutoUpdater::SetFeedURL(const v8::FunctionCallbackInfo<v8::Value>& args) {
auto_updater::AutoUpdater::SetFeedURL(FromV8Value(args[0])); auto_updater::AutoUpdater::SetFeedURL(FromV8Value(args[0]));
} }
// static
void AutoUpdater::SetAutomaticallyChecksForUpdates(
const v8::FunctionCallbackInfo<v8::Value>& args) {
auto_updater::AutoUpdater::SetAutomaticallyChecksForUpdates(
FromV8Value(args[0]));
}
// static
void AutoUpdater::SetAutomaticallyDownloadsUpdates(
const v8::FunctionCallbackInfo<v8::Value>& args) {
auto_updater::AutoUpdater::SetAutomaticallyDownloadsUpdates(
FromV8Value(args[0]));
}
// static // static
void AutoUpdater::CheckForUpdates( void AutoUpdater::CheckForUpdates(
const v8::FunctionCallbackInfo<v8::Value>& args) { const v8::FunctionCallbackInfo<v8::Value>& args) {
auto_updater::AutoUpdater::CheckForUpdates(); auto_updater::AutoUpdater::CheckForUpdates();
} }
// static
void AutoUpdater::CheckForUpdatesInBackground(
const v8::FunctionCallbackInfo<v8::Value>& args) {
auto_updater::AutoUpdater::CheckForUpdatesInBackground();
}
// static
void AutoUpdater::ContinueUpdate(
const v8::FunctionCallbackInfo<v8::Value>& args) {
AutoUpdater* self = AutoUpdater::Unwrap<AutoUpdater>(args.This());
self->continue_update_.Run();
}
// static // static
void AutoUpdater::QuitAndInstall( void AutoUpdater::QuitAndInstall(
const v8::FunctionCallbackInfo<v8::Value>& args) { const v8::FunctionCallbackInfo<v8::Value>& args) {
@ -102,26 +85,13 @@ void AutoUpdater::QuitAndInstall(
// static // static
void AutoUpdater::Initialize(v8::Handle<v8::Object> target) { void AutoUpdater::Initialize(v8::Handle<v8::Object> target) {
v8::HandleScope handle_scope(v8::Isolate::GetCurrent());
v8::Local<v8::FunctionTemplate> t( v8::Local<v8::FunctionTemplate> t(
v8::FunctionTemplate::New(AutoUpdater::New)); v8::FunctionTemplate::New(AutoUpdater::New));
t->InstanceTemplate()->SetInternalFieldCount(1); t->InstanceTemplate()->SetInternalFieldCount(1);
t->SetClassName(v8::String::NewSymbol("AutoUpdater")); t->SetClassName(v8::String::NewSymbol("AutoUpdater"));
NODE_SET_PROTOTYPE_METHOD(t, "setFeedUrl", SetFeedURL); NODE_SET_PROTOTYPE_METHOD(t, "setFeedUrl", SetFeedURL);
NODE_SET_PROTOTYPE_METHOD(t,
"setAutomaticallyChecksForUpdates",
SetAutomaticallyChecksForUpdates);
NODE_SET_PROTOTYPE_METHOD(t,
"setAutomaticallyDownloadsUpdates",
SetAutomaticallyDownloadsUpdates);
NODE_SET_PROTOTYPE_METHOD(t, "checkForUpdates", CheckForUpdates); NODE_SET_PROTOTYPE_METHOD(t, "checkForUpdates", CheckForUpdates);
NODE_SET_PROTOTYPE_METHOD(t,
"checkForUpdatesInBackground",
CheckForUpdatesInBackground);
NODE_SET_PROTOTYPE_METHOD(t, "continueUpdate", ContinueUpdate);
NODE_SET_PROTOTYPE_METHOD(t, "quitAndInstall", QuitAndInstall); NODE_SET_PROTOTYPE_METHOD(t, "quitAndInstall", QuitAndInstall);
target->Set(v8::String::NewSymbol("AutoUpdater"), t->GetFunction()); target->Set(v8::String::NewSymbol("AutoUpdater"), t->GetFunction());

View file

@ -24,28 +24,27 @@ class AutoUpdater : public EventEmitter,
protected: protected:
explicit AutoUpdater(v8::Handle<v8::Object> wrapper); explicit AutoUpdater(v8::Handle<v8::Object> wrapper);
virtual void WillInstallUpdate(const std::string& version, // AutoUpdaterDelegate implementations.
const base::Closure& install) OVERRIDE; virtual void OnError(const std::string& error) OVERRIDE;
virtual void ReadyForUpdateOnQuit( virtual void OnCheckingForUpdate() OVERRIDE;
const std::string& version, virtual void OnUpdateAvailable() OVERRIDE;
virtual void OnUpdateNotAvailable() OVERRIDE;
virtual void OnUpdateDownloaded(
const std::string& release_notes,
const std::string& release_name,
const base::Time& release_date,
const std::string& update_url,
const base::Closure& quit_and_install) OVERRIDE; const base::Closure& quit_and_install) OVERRIDE;
private: private:
static void New(const v8::FunctionCallbackInfo<v8::Value>& args); static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
static void SetFeedURL(const v8::FunctionCallbackInfo<v8::Value>& args); static void SetFeedURL(const v8::FunctionCallbackInfo<v8::Value>& args);
static void SetAutomaticallyChecksForUpdates(
const v8::FunctionCallbackInfo<v8::Value>& args);
static void SetAutomaticallyDownloadsUpdates(
const v8::FunctionCallbackInfo<v8::Value>& args);
static void CheckForUpdates(const v8::FunctionCallbackInfo<v8::Value>& args); static void CheckForUpdates(const v8::FunctionCallbackInfo<v8::Value>& args);
static void CheckForUpdatesInBackground(
const v8::FunctionCallbackInfo<v8::Value>& args);
static void ContinueUpdate(const v8::FunctionCallbackInfo<v8::Value>& args); static void ContinueUpdate(const v8::FunctionCallbackInfo<v8::Value>& args);
static void QuitAndInstall(const v8::FunctionCallbackInfo<v8::Value>& args); static void QuitAndInstall(const v8::FunctionCallbackInfo<v8::Value>& args);
base::Closure continue_update_;
base::Closure quit_and_install_; base::Closure quit_and_install_;
DISALLOW_COPY_AND_ASSIGN(AutoUpdater); DISALLOW_COPY_AND_ASSIGN(AutoUpdater);

View file

@ -19,7 +19,9 @@ namespace {
template<typename T> template<typename T>
void CallV8Function(const RefCountedV8Function& callback, T arg) { void CallV8Function(const RefCountedV8Function& callback, T arg) {
v8::Locker locker(node_isolate);
v8::HandleScope handle_scope(node_isolate); v8::HandleScope handle_scope(node_isolate);
v8::Handle<v8::Value> value = ToV8Value(arg); v8::Handle<v8::Value> value = ToV8Value(arg);
callback->NewHandle(node_isolate)->Call( callback->NewHandle(node_isolate)->Call(
v8::Context::GetCurrent()->Global(), 1, &value); v8::Context::GetCurrent()->Global(), 1, &value);
@ -34,8 +36,6 @@ void CallV8Function2(const RefCountedV8Function& callback, bool result, T arg) {
} }
void Initialize(v8::Handle<v8::Object> target) { void Initialize(v8::Handle<v8::Object> target) {
v8::HandleScope handle_scope(node_isolate);
NODE_SET_METHOD(target, "showMessageBox", ShowMessageBox); NODE_SET_METHOD(target, "showMessageBox", ShowMessageBox);
NODE_SET_METHOD(target, "showOpenDialog", ShowOpenDialog); NODE_SET_METHOD(target, "showOpenDialog", ShowOpenDialog);
NODE_SET_METHOD(target, "showSaveDialog", ShowSaveDialog); NODE_SET_METHOD(target, "showSaveDialog", ShowSaveDialog);

View file

@ -24,6 +24,7 @@ v8::Handle<v8::Value> CallDelegate(v8::Handle<v8::Value> default_value,
v8::Handle<v8::Object> menu, v8::Handle<v8::Object> menu,
const char* method, const char* method,
int command_id) { int command_id) {
v8::Locker locker(node_isolate);
v8::HandleScope handle_scope(node_isolate); v8::HandleScope handle_scope(node_isolate);
v8::Handle<v8::Value> delegate = menu->Get(v8::String::New("delegate")); v8::Handle<v8::Value> delegate = menu->Get(v8::String::New("delegate"));
@ -52,6 +53,7 @@ Menu::~Menu() {
} }
bool Menu::IsCommandIdChecked(int command_id) const { bool Menu::IsCommandIdChecked(int command_id) const {
v8::Locker locker(node_isolate);
v8::HandleScope handle_scope(node_isolate); v8::HandleScope handle_scope(node_isolate);
return CallDelegate(v8::False(), return CallDelegate(v8::False(),
const_cast<Menu*>(this)->handle(), const_cast<Menu*>(this)->handle(),
@ -60,6 +62,7 @@ bool Menu::IsCommandIdChecked(int command_id) const {
} }
bool Menu::IsCommandIdEnabled(int command_id) const { bool Menu::IsCommandIdEnabled(int command_id) const {
v8::Locker locker(node_isolate);
v8::HandleScope handle_scope(node_isolate); v8::HandleScope handle_scope(node_isolate);
return CallDelegate(v8::True(), return CallDelegate(v8::True(),
const_cast<Menu*>(this)->handle(), const_cast<Menu*>(this)->handle(),
@ -68,6 +71,7 @@ bool Menu::IsCommandIdEnabled(int command_id) const {
} }
bool Menu::IsCommandIdVisible(int command_id) const { bool Menu::IsCommandIdVisible(int command_id) const {
v8::Locker locker(node_isolate);
v8::HandleScope handle_scope(node_isolate); v8::HandleScope handle_scope(node_isolate);
return CallDelegate(v8::True(), return CallDelegate(v8::True(),
const_cast<Menu*>(this)->handle(), const_cast<Menu*>(this)->handle(),
@ -77,6 +81,7 @@ bool Menu::IsCommandIdVisible(int command_id) const {
bool Menu::GetAcceleratorForCommandId(int command_id, bool Menu::GetAcceleratorForCommandId(int command_id,
ui::Accelerator* accelerator) { ui::Accelerator* accelerator) {
v8::Locker locker(node_isolate);
v8::HandleScope handle_scope(node_isolate); v8::HandleScope handle_scope(node_isolate);
v8::Handle<v8::Value> shortcut = CallDelegate(v8::Undefined(), v8::Handle<v8::Value> shortcut = CallDelegate(v8::Undefined(),
handle(), handle(),
@ -91,6 +96,7 @@ bool Menu::GetAcceleratorForCommandId(int command_id,
} }
bool Menu::IsItemForCommandIdDynamic(int command_id) const { bool Menu::IsItemForCommandIdDynamic(int command_id) const {
v8::Locker locker(node_isolate);
v8::HandleScope handle_scope(node_isolate); v8::HandleScope handle_scope(node_isolate);
return CallDelegate(v8::False(), return CallDelegate(v8::False(),
const_cast<Menu*>(this)->handle(), const_cast<Menu*>(this)->handle(),
@ -99,6 +105,7 @@ bool Menu::IsItemForCommandIdDynamic(int command_id) const {
} }
string16 Menu::GetLabelForCommandId(int command_id) const { string16 Menu::GetLabelForCommandId(int command_id) const {
v8::Locker locker(node_isolate);
v8::HandleScope handle_scope(node_isolate); v8::HandleScope handle_scope(node_isolate);
return FromV8Value(CallDelegate(v8::False(), return FromV8Value(CallDelegate(v8::False(),
const_cast<Menu*>(this)->handle(), const_cast<Menu*>(this)->handle(),
@ -107,6 +114,7 @@ string16 Menu::GetLabelForCommandId(int command_id) const {
} }
string16 Menu::GetSublabelForCommandId(int command_id) const { string16 Menu::GetSublabelForCommandId(int command_id) const {
v8::Locker locker(node_isolate);
v8::HandleScope handle_scope(node_isolate); v8::HandleScope handle_scope(node_isolate);
return FromV8Value(CallDelegate(v8::False(), return FromV8Value(CallDelegate(v8::False(),
const_cast<Menu*>(this)->handle(), const_cast<Menu*>(this)->handle(),
@ -115,14 +123,13 @@ string16 Menu::GetSublabelForCommandId(int command_id) const {
} }
void Menu::ExecuteCommand(int command_id, int event_flags) { void Menu::ExecuteCommand(int command_id, int event_flags) {
v8::Locker locker(node_isolate);
v8::HandleScope handle_scope(node_isolate); v8::HandleScope handle_scope(node_isolate);
CallDelegate(v8::False(), handle(), "executeCommand", command_id); CallDelegate(v8::False(), handle(), "executeCommand", command_id);
} }
// static // static
void Menu::New(const v8::FunctionCallbackInfo<v8::Value>& args) { void Menu::New(const v8::FunctionCallbackInfo<v8::Value>& args) {
v8::HandleScope handle_scope(args.GetIsolate());
if (!args.IsConstructCall()) if (!args.IsConstructCall())
return node::ThrowError("Require constructor call"); return node::ThrowError("Require constructor call");
@ -307,8 +314,6 @@ void Menu::Popup(const v8::FunctionCallbackInfo<v8::Value>& args) {
// static // static
void Menu::Initialize(v8::Handle<v8::Object> target) { void Menu::Initialize(v8::Handle<v8::Object> target) {
v8::HandleScope handle_scope(node_isolate);
v8::Local<v8::FunctionTemplate> t(v8::FunctionTemplate::New(Menu::New)); v8::Local<v8::FunctionTemplate> t(v8::FunctionTemplate::New(Menu::New));
t->InstanceTemplate()->SetInternalFieldCount(1); t->InstanceTemplate()->SetInternalFieldCount(1);
t->SetClassName(v8::String::NewSymbol("Menu")); t->SetClassName(v8::String::NewSymbol("Menu"));

View file

@ -7,7 +7,7 @@
#include "browser/api/atom_api_menu.h" #include "browser/api/atom_api_menu.h"
#import "browser/ui/atom_menu_controller_mac.h" #import "browser/ui/cocoa/atom_menu_controller.h"
namespace atom { namespace atom {

View file

@ -74,8 +74,6 @@ void MenuMac::SendActionToFirstResponder(const std::string& action) {
// static // static
void Menu::SetApplicationMenu(const v8::FunctionCallbackInfo<v8::Value>& args) { void Menu::SetApplicationMenu(const v8::FunctionCallbackInfo<v8::Value>& args) {
v8::HandleScope handle_scope(args.GetIsolate());
if (!args[0]->IsObject()) if (!args[0]->IsObject())
return node::ThrowTypeError("Bad argument"); return node::ThrowTypeError("Bad argument");
@ -94,8 +92,6 @@ void Menu::SetApplicationMenu(const v8::FunctionCallbackInfo<v8::Value>& args) {
// static // static
void Menu::SendActionToFirstResponder( void Menu::SendActionToFirstResponder(
const v8::FunctionCallbackInfo<v8::Value>& args) { const v8::FunctionCallbackInfo<v8::Value>& args) {
v8::HandleScope handle_scope(args.GetIsolate());
std::string action; std::string action;
if (!FromV8Arguments(args, &action)) if (!FromV8Arguments(args, &action))
return node::ThrowTypeError("Bad argument"); return node::ThrowTypeError("Bad argument");

View file

@ -31,8 +31,6 @@ void MenuWin::Popup(NativeWindow* native_window) {
// static // static
void Menu::AttachToWindow(const v8::FunctionCallbackInfo<v8::Value>& args) { void Menu::AttachToWindow(const v8::FunctionCallbackInfo<v8::Value>& args) {
v8::HandleScope handle_scope(args.GetIsolate());
Menu* self = ObjectWrap::Unwrap<Menu>(args.This()); Menu* self = ObjectWrap::Unwrap<Menu>(args.This());
if (self == NULL) if (self == NULL)
return node::ThrowError("Menu is already destroyed"); return node::ThrowError("Menu is already destroyed");

View file

@ -39,8 +39,6 @@ void PowerMonitor::OnResume() {
// static // static
void PowerMonitor::New(const v8::FunctionCallbackInfo<v8::Value>& args) { void PowerMonitor::New(const v8::FunctionCallbackInfo<v8::Value>& args) {
v8::HandleScope handle_scope(args.GetIsolate());
if (!args.IsConstructCall()) if (!args.IsConstructCall())
return node::ThrowError("Require constructor call"); return node::ThrowError("Require constructor call");
@ -49,8 +47,6 @@ void PowerMonitor::New(const v8::FunctionCallbackInfo<v8::Value>& args) {
// static // static
void PowerMonitor::Initialize(v8::Handle<v8::Object> target) { void PowerMonitor::Initialize(v8::Handle<v8::Object> target) {
v8::HandleScope handle_scope(node_isolate);
#if defined(OS_MACOSX) #if defined(OS_MACOSX)
base::PowerMonitorDeviceSource::AllocateSystemIOPorts(); base::PowerMonitorDeviceSource::AllocateSystemIOPorts();
#endif #endif

View file

@ -35,6 +35,7 @@ static const char* kEarlyUseProtocolError = "This method can only be used"
// Emit an event for the protocol module. // Emit an event for the protocol module.
void EmitEventInUI(const std::string& event, const std::string& parameter) { void EmitEventInUI(const std::string& event, const std::string& parameter) {
v8::Locker locker(node_isolate);
v8::HandleScope handle_scope(node_isolate); v8::HandleScope handle_scope(node_isolate);
v8::Handle<v8::Value> argv[] = { v8::Handle<v8::Value> argv[] = {
@ -72,6 +73,7 @@ class CustomProtocolRequestJob : public AdapterRequestJob {
virtual void GetJobTypeInUI() OVERRIDE { virtual void GetJobTypeInUI() OVERRIDE {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
v8::Locker locker(node_isolate);
v8::HandleScope handle_scope(node_isolate); v8::HandleScope handle_scope(node_isolate);
// Call the JS handler. // Call the JS handler.

View file

@ -92,6 +92,7 @@ void Window::OnRendererCrashed() {
void Window::OnCapturePageDone(const RefCountedV8Function& callback, void Window::OnCapturePageDone(const RefCountedV8Function& callback,
const std::vector<unsigned char>& data) { const std::vector<unsigned char>& data) {
v8::Locker locker(node_isolate);
v8::HandleScope handle_scope(node_isolate); v8::HandleScope handle_scope(node_isolate);
v8::Local<v8::Value> buffer = node::Buffer::New( v8::Local<v8::Value> buffer = node::Buffer::New(
@ -103,8 +104,6 @@ void Window::OnCapturePageDone(const RefCountedV8Function& callback,
// static // static
void Window::New(const v8::FunctionCallbackInfo<v8::Value>& args) { void Window::New(const v8::FunctionCallbackInfo<v8::Value>& args) {
v8::HandleScope handle_scope(args.GetIsolate());
if (!args.IsConstructCall()) if (!args.IsConstructCall())
return node::ThrowError("Require constructor call"); return node::ThrowError("Require constructor call");
@ -625,8 +624,6 @@ void Window::ReloadIgnoringCache(
// static // static
void Window::Initialize(v8::Handle<v8::Object> target) { void Window::Initialize(v8::Handle<v8::Object> target) {
v8::HandleScope handle_scope(node_isolate);
v8::Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(Window::New); v8::Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(Window::New);
t->InstanceTemplate()->SetInternalFieldCount(1); t->InstanceTemplate()->SetInternalFieldCount(1);
t->SetClassName(v8::String::NewSymbol("BrowserWindow")); t->SetClassName(v8::String::NewSymbol("BrowserWindow"));

View file

@ -25,6 +25,7 @@ void AtomBrowserBindings::OnRendererMessage(int process_id,
int routing_id, int routing_id,
const string16& channel, const string16& channel,
const base::ListValue& args) { const base::ListValue& args) {
v8::Locker locker(node_isolate);
v8::HandleScope handle_scope(node_isolate); v8::HandleScope handle_scope(node_isolate);
scoped_ptr<V8ValueConverter> converter(new V8ValueConverter); scoped_ptr<V8ValueConverter> converter(new V8ValueConverter);
@ -58,6 +59,7 @@ void AtomBrowserBindings::OnRendererMessageSync(
const base::ListValue& args, const base::ListValue& args,
NativeWindow* sender, NativeWindow* sender,
IPC::Message* message) { IPC::Message* message) {
v8::Locker locker(node_isolate);
v8::HandleScope handle_scope(node_isolate); v8::HandleScope handle_scope(node_isolate);
scoped_ptr<V8ValueConverter> converter(new V8ValueConverter); scoped_ptr<V8ValueConverter> converter(new V8ValueConverter);

View file

@ -4,9 +4,8 @@ EventEmitter = require('events').EventEmitter
AutoUpdater::__proto__ = EventEmitter.prototype AutoUpdater::__proto__ = EventEmitter.prototype
autoUpdater = new AutoUpdater autoUpdater = new AutoUpdater
autoUpdater.on 'will-install-update-raw', (event, version) -> autoUpdater.on 'update-downloaded-raw', (args...) ->
@emit 'will-install-update', event, version, => @continueUpdate() args[3] = new Date(args[3]) # releaseDate
autoUpdater.on 'ready-for-update-on-quit-raw', (event, version) -> @emit 'update-downloaded', args..., => @quitAndInstall()
@emit 'ready-for-update-on-quit', event, version, => @quitAndInstall()
module.exports = autoUpdater module.exports = autoUpdater

View file

@ -4,14 +4,39 @@
#include "browser/atom_browser_client.h" #include "browser/atom_browser_client.h"
#include "base/command_line.h"
#include "browser/atom_browser_context.h" #include "browser/atom_browser_context.h"
#include "browser/atom_browser_main_parts.h" #include "browser/atom_browser_main_parts.h"
#include "browser/native_window.h"
#include "browser/net/atom_url_request_context_getter.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/site_instance.h"
#include "content/public/browser/web_contents.h"
#include "webkit/common/webpreferences.h" #include "webkit/common/webpreferences.h"
namespace atom { namespace atom {
AtomBrowserClient::AtomBrowserClient() { namespace {
struct FindByProcessId {
explicit 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() { AtomBrowserClient::~AtomBrowserClient() {
@ -50,10 +75,44 @@ bool AtomBrowserClient::ShouldSwapProcessesForNavigation(
content::SiteInstance* site_instance, content::SiteInstance* site_instance,
const GURL& current_url, const GURL& current_url,
const GURL& new_url) { const GURL& new_url) {
if (site_instance->HasProcess())
dying_render_process_ = site_instance->GetProcess();
// Restart renderer process for all navigations. // Restart renderer process for all navigations.
return true; return true;
} }
void AtomBrowserClient::AppendExtraCommandLineSwitches(
CommandLine* command_line,
int child_process_id) {
WindowList* list = WindowList::GetInstance();
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());
dying_render_process_ = NULL;
}
brightray::BrowserMainParts* AtomBrowserClient::OverrideCreateBrowserMainParts( brightray::BrowserMainParts* AtomBrowserClient::OverrideCreateBrowserMainParts(
const content::MainFunctionParams&) { const content::MainFunctionParams&) {
return new AtomBrowserMainParts; return new AtomBrowserMainParts;

View file

@ -25,11 +25,16 @@ class AtomBrowserClient : public brightray::BrowserClient {
content::SiteInstance* site_instance, content::SiteInstance* site_instance,
const GURL& current_url, const GURL& current_url,
const GURL& new_url) OVERRIDE; const GURL& new_url) OVERRIDE;
virtual void AppendExtraCommandLineSwitches(CommandLine* command_line,
int child_process_id) OVERRIDE;
private: private:
virtual brightray::BrowserMainParts* OverrideCreateBrowserMainParts( virtual brightray::BrowserMainParts* OverrideCreateBrowserMainParts(
const content::MainFunctionParams&) OVERRIDE; const content::MainFunctionParams&) OVERRIDE;
// The render process which would be swapped out soon.
content::RenderProcessHost* dying_render_process_;
DISALLOW_COPY_AND_ASSIGN(AtomBrowserClient); DISALLOW_COPY_AND_ASSIGN(AtomBrowserClient);
}; };

View file

@ -61,7 +61,8 @@ AtomURLRequestContextGetter* AtomBrowserContext::CreateRequestContext(
GetPath(), GetPath(),
BrowserThread::UnsafeGetMessageLoopForThread(BrowserThread::IO), BrowserThread::UnsafeGetMessageLoopForThread(BrowserThread::IO),
BrowserThread::UnsafeGetMessageLoopForThread(BrowserThread::FILE), BrowserThread::UnsafeGetMessageLoopForThread(BrowserThread::FILE),
CreateNetworkDelegate().Pass(), base::Bind(&AtomBrowserContext::CreateNetworkDelegate,
base::Unretained(this)),
protocol_handlers); protocol_handlers);
resource_context_->set_url_request_context_getter(url_request_getter_.get()); resource_context_->set_url_request_context_getter(url_request_getter_.get());

View file

@ -51,6 +51,7 @@ void AtomBrowserMainParts::PostEarlyInitialization() {
v8::V8::Initialize(); v8::V8::Initialize();
// Create context. // Create context.
v8::Locker locker(node_isolate);
v8::HandleScope handle_scope(node_isolate); v8::HandleScope handle_scope(node_isolate);
v8::Local<v8::Context> context = v8::Context::New(node_isolate); v8::Local<v8::Context> context = v8::Context::New(node_isolate);

View file

@ -19,13 +19,8 @@ class AutoUpdater {
static AutoUpdaterDelegate* GetDelegate(); static AutoUpdaterDelegate* GetDelegate();
static void SetDelegate(AutoUpdaterDelegate* delegate); static void SetDelegate(AutoUpdaterDelegate* delegate);
static void Init();
static void SetFeedURL(const std::string& url); static void SetFeedURL(const std::string& url);
static void SetAutomaticallyChecksForUpdates(bool yes);
static void SetAutomaticallyDownloadsUpdates(bool yes);
static void CheckForUpdates(); static void CheckForUpdates();
static void CheckForUpdatesInBackground();
private: private:
static AutoUpdaterDelegate* delegate_; static AutoUpdaterDelegate* delegate_;

View file

@ -1,21 +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/auto_updater_delegate.h"
#include "base/callback.h"
namespace auto_updater {
void AutoUpdaterDelegate::WillInstallUpdate(const std::string& version,
const base::Closure& install) {
install.Run();
}
void AutoUpdaterDelegate::ReadyForUpdateOnQuit(
const std::string& version,
const base::Closure& quit_and_install) {
}
} // namespace auto_updater

View file

@ -9,17 +9,32 @@
#include "base/callback_forward.h" #include "base/callback_forward.h"
namespace base {
class Time;
}
namespace auto_updater { namespace auto_updater {
class AutoUpdaterDelegate { class AutoUpdaterDelegate {
public: public:
// The application is going to relaunch to install update. // An error happened.
virtual void WillInstallUpdate(const std::string& version, virtual void OnError(const std::string& error) {}
const base::Closure& install);
// User has chosen to update on quit. // Checking to see if there is an update
virtual void ReadyForUpdateOnQuit(const std::string& version, virtual void OnCheckingForUpdate() {}
const base::Closure& quit_and_install);
// There is an update available and it is being downloaded
virtual void OnUpdateAvailable() {}
// There is no available update.
virtual void OnUpdateNotAvailable() {}
// There is a new update which has been downloaded.
virtual void OnUpdateDownloaded(const std::string& release_notes,
const std::string& release_name,
const base::Time& release_date,
const std::string& update_url,
const base::Closure& quit_and_install) {}
protected: protected:
virtual ~AutoUpdaterDelegate() {} virtual ~AutoUpdaterDelegate() {}

View file

@ -4,106 +4,89 @@
#include "browser/auto_updater.h" #include "browser/auto_updater.h"
// Sparkle's headers are throwing compilation warnings, supress them. #import <ReactiveCocoa/RACCommand.h>
#pragma GCC diagnostic ignored "-Wmissing-method-return-type" #import <ReactiveCocoa/RACSignal.h>
#import <Sparkle/Sparkle.h> #import <ReactiveCocoa/NSObject+RACPropertySubscribing.h>
#import <Squirrel/Squirrel.h>
#include "base/bind.h" #include "base/bind.h"
#include "base/memory/scoped_ptr.h" #include "base/time/time.h"
#include "base/strings/sys_string_conversions.h" #include "base/strings/sys_string_conversions.h"
#include "browser/auto_updater_delegate.h" #include "browser/auto_updater_delegate.h"
using auto_updater::AutoUpdaterDelegate; #include <iostream>
namespace auto_updater {
namespace { namespace {
struct NSInvocationDeleter { // The gloal SQRLUpdater object.
inline void operator()(NSInvocation* invocation) const { SQRLUpdater* g_updater = nil;
[invocation release];
}
};
typedef scoped_ptr<NSInvocation, NSInvocationDeleter> ScopedNSInvocation; void RelaunchToInstallUpdate() {
[[g_updater relaunchToInstallUpdate] subscribeError:^(NSError* error) {
// We are passing the NSInvocation as scoped_ptr, because we want to make sure AutoUpdaterDelegate* delegate = AutoUpdater::GetDelegate();
// whether or not the callback is called, the NSInvocation should alwasy be if (delegate)
// released, the only way to ensure it is to use scoped_ptr. delegate->OnError(base::SysNSStringToUTF8(error.localizedDescription));
void CallNSInvocation(ScopedNSInvocation invocation) { }];
[invocation.get() invoke];
} }
} // namespace } // namespace
@interface SUUpdaterDelegate : NSObject { // static
} void AutoUpdater::SetFeedURL(const std::string& feed) {
@end if (g_updater == nil) {
// Initialize the SQRLUpdater.
NSURL* url = [NSURL URLWithString:base::SysUTF8ToNSString(feed)];
NSURLRequest* urlRequest = [NSURLRequest requestWithURL:url];
g_updater = [[SQRLUpdater alloc] initWithUpdateRequest:urlRequest];
@implementation SUUpdaterDelegate AutoUpdaterDelegate* delegate = GetDelegate();
- (BOOL)updater:(SUUpdater*)updater
shouldPostponeRelaunchForUpdate:(SUAppcastItem*)update
untilInvoking:(NSInvocation*)invocation {
AutoUpdaterDelegate* delegate = auto_updater::AutoUpdater::GetDelegate();
if (!delegate)
return NO;
std::string version(base::SysNSStringToUTF8([update versionString]));
ScopedNSInvocation invocation_ptr([invocation retain]);
delegate->WillInstallUpdate(
version,
base::Bind(&CallNSInvocation, base::Passed(invocation_ptr.Pass())));
return YES;
}
- (void)updater:(SUUpdater*)updater
willInstallUpdateOnQuit:(SUAppcastItem*)update
immediateInstallationInvocation:(NSInvocation*)invocation {
AutoUpdaterDelegate* delegate = auto_updater::AutoUpdater::GetDelegate();
if (!delegate) if (!delegate)
return; return;
std::string version(base::SysNSStringToUTF8([update versionString])); [[g_updater rac_valuesForKeyPath:@"state" observer:g_updater]
ScopedNSInvocation invocation_ptr([invocation retain]); subscribeNext:^(NSNumber *stateNumber) {
delegate->ReadyForUpdateOnQuit( int state = [stateNumber integerValue];
version, if (state == SQRLUpdaterStateCheckingForUpdate) {
base::Bind(&CallNSInvocation, base::Passed(invocation_ptr.Pass()))); delegate->OnCheckingForUpdate();
} else if (state == SQRLUpdaterStateDownloadingUpdate) {
delegate->OnUpdateAvailable();
} }
}];
@end
namespace auto_updater {
// static
void AutoUpdater::Init() {
SUUpdaterDelegate* delegate = [[SUUpdaterDelegate alloc] init];
[[SUUpdater sharedUpdater] setDelegate:delegate];
} }
// static
void AutoUpdater::SetFeedURL(const std::string& url) {
NSString* url_str(base::SysUTF8ToNSString(url));
[[SUUpdater sharedUpdater] setFeedURL:[NSURL URLWithString:url_str]];
}
// static
void AutoUpdater::SetAutomaticallyChecksForUpdates(bool yes) {
[[SUUpdater sharedUpdater] setAutomaticallyChecksForUpdates:yes];
}
// static
void AutoUpdater::SetAutomaticallyDownloadsUpdates(bool yes) {
[[SUUpdater sharedUpdater] setAutomaticallyDownloadsUpdates:yes];
} }
// static // static
void AutoUpdater::CheckForUpdates() { void AutoUpdater::CheckForUpdates() {
[[SUUpdater sharedUpdater] checkForUpdates:nil]; AutoUpdaterDelegate* delegate = GetDelegate();
} if (!delegate)
return;
// static [[[[g_updater.checkForUpdatesCommand
void AutoUpdater::CheckForUpdatesInBackground() { execute:nil]
[[SUUpdater sharedUpdater] checkForUpdatesInBackground]; // Send a `nil` after everything...
concat:[RACSignal return:nil]]
// But only take the first value. If an update is sent, we'll get that.
// Otherwise, we'll get our inserted `nil` value.
take:1]
subscribeNext:^(SQRLDownloadedUpdate *downloadedUpdate) {
if (downloadedUpdate) {
SQRLUpdate* update = downloadedUpdate.update;
// There is a new update that has been downloaded.
delegate->OnUpdateDownloaded(
base::SysNSStringToUTF8(update.releaseNotes),
base::SysNSStringToUTF8(update.releaseName),
base::Time::FromDoubleT(update.releaseDate.timeIntervalSince1970),
base::SysNSStringToUTF8(update.updateURL.absoluteString),
base::Bind(RelaunchToInstallUpdate));
} else {
// When the completed event is sent with no update, then we know there
// is no update available.
delegate->OnUpdateNotAvailable();
}
} error:^(NSError *error) {
delegate->OnError(base::SysNSStringToUTF8(error.localizedDescription));
}];
} }
} // namespace auto_updater } // namespace auto_updater

View file

@ -6,28 +6,12 @@
namespace auto_updater { namespace auto_updater {
// static
void AutoUpdater::Init() {
}
// static // static
void AutoUpdater::SetFeedURL(const std::string& url) { void AutoUpdater::SetFeedURL(const std::string& url) {
} }
// static
void AutoUpdater::SetAutomaticallyChecksForUpdates(bool yes) {
}
// static
void AutoUpdater::SetAutomaticallyDownloadsUpdates(bool yes) {
}
// static // static
void AutoUpdater::CheckForUpdates() { void AutoUpdater::CheckForUpdates() {
} }
// static
void AutoUpdater::CheckForUpdatesInBackground() {
}
} // namespace auto_updater } // namespace auto_updater

View file

@ -1,5 +1,4 @@
var app = require('app'); var app = require('app');
var dialog = require('dialog');
var path = require('path'); var path = require('path');
var optimist = require('optimist'); var optimist = require('optimist');
@ -9,7 +8,7 @@ app.on('window-all-closed', function() {
app.quit(); app.quit();
}); });
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 specified app if there is one specified in command line, otherwise
// start the default app. // start the default app.

View file

@ -1,5 +1,6 @@
fs = require 'fs' fs = require 'fs'
path = require 'path' path = require 'path'
util = require 'util'
# Expose information of current process. # Expose information of current process.
process.__atom_type = 'browser' process.__atom_type = 'browser'
@ -9,6 +10,11 @@ process.resourcesPath = path.resolve process.argv[1], '..', '..', '..'
# we need to restore it here. # we need to restore it here.
process.argv.splice 1, 1 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, # Add browser/api/lib to require's search paths,
# which contains javascript part of Atom's built-in libraries. # which contains javascript part of Atom's built-in libraries.
globalPaths = require('module').globalPaths globalPaths = require('module').globalPaths
@ -23,8 +29,10 @@ setImmediate ->
if process.platform is 'win32' if process.platform is 'win32'
# Redirect node's console to use our own implementations, since node can not # Redirect node's console to use our own implementations, since node can not
# handle console output when running as GUI program. # handle console output when running as GUI program.
console.log = console.error = console.warn = process.log print = (args...) ->
process.stdout.write = process.stderr.write = process.log process.log util.format(args...)
console.log = console.error = console.warn = print
process.stdout.write = process.stderr.write = print
# Always returns EOF for stdin stream. # Always returns EOF for stdin stream.
Readable = require('stream').Readable Readable = require('stream').Readable

View file

@ -48,16 +48,20 @@ NativeWindow::NativeWindow(content::WebContents* web_contents,
: content::WebContentsObserver(web_contents), : content::WebContentsObserver(web_contents),
has_frame_(true), has_frame_(true),
is_closed_(false), is_closed_(false),
node_integration_("all"),
has_dialog_attached_(false),
weak_factory_(this), weak_factory_(this),
inspectable_web_contents_( inspectable_web_contents_(
brightray::InspectableWebContents::Create(web_contents)) { brightray::InspectableWebContents::Create(web_contents)) {
options->GetBoolean(switches::kFrame, &has_frame_); options->GetBoolean(switches::kFrame, &has_frame_);
// Read icon before window is created.
std::string icon; std::string icon;
if (options->GetString(switches::kIcon, &icon)) { if (options->GetString(switches::kIcon, &icon) && !SetIcon(icon))
if (!SetIcon(icon))
LOG(ERROR) << "Failed to set icon to " << icon; LOG(ERROR) << "Failed to set icon to " << icon;
}
// Read iframe security before any navigation.
options->GetString(switches::kNodeIntegration, &node_integration_);
web_contents->SetDelegate(this); web_contents->SetDelegate(this);
@ -155,6 +159,10 @@ void NativeWindow::InitFromOptions(base::DictionaryValue* options) {
Show(); Show();
} }
bool NativeWindow::HasModalDialog() {
return has_dialog_attached_;
}
void NativeWindow::OpenDevTools() { void NativeWindow::OpenDevTools() {
inspectable_web_contents()->ShowDevTools(); inspectable_web_contents()->ShowDevTools();
} }

View file

@ -54,6 +54,25 @@ class NativeWindow : public brightray::DefaultWebContentsDelegate,
typedef base::Callback<void(const std::vector<unsigned char>& buffer)> typedef base::Callback<void(const std::vector<unsigned char>& buffer)>
CapturePageCallback; CapturePageCallback;
class DialogScope {
public:
DialogScope(NativeWindow* window)
: window_(window) {
if (window_ != NULL)
window_->set_has_dialog_attached(true);
}
~DialogScope() {
if (window_ != NULL)
window_->set_has_dialog_attached(false);
}
private:
NativeWindow* window_;
DISALLOW_COPY_AND_ASSIGN(DialogScope);
};
virtual ~NativeWindow(); virtual ~NativeWindow();
// Create window with existing WebContents. // Create window with existing WebContents.
@ -100,7 +119,7 @@ class NativeWindow : public brightray::DefaultWebContentsDelegate,
virtual void FlashFrame(bool flash) = 0; virtual void FlashFrame(bool flash) = 0;
virtual void SetKiosk(bool kiosk) = 0; virtual void SetKiosk(bool kiosk) = 0;
virtual bool IsKiosk() = 0; virtual bool IsKiosk() = 0;
virtual bool HasModalDialog() = 0; virtual bool HasModalDialog();
virtual gfx::NativeWindow GetNativeWindow() = 0; virtual gfx::NativeWindow GetNativeWindow() = 0;
virtual bool IsClosed() const { return is_closed_; } virtual bool IsClosed() const { return is_closed_; }
@ -140,6 +159,11 @@ class NativeWindow : public brightray::DefaultWebContentsDelegate,
} }
bool has_frame() const { return has_frame_; } bool has_frame() const { return has_frame_; }
std::string node_integration() const { return node_integration_; }
void set_has_dialog_attached(bool has_dialog_attached) {
has_dialog_attached_ = has_dialog_attached;
}
protected: protected:
explicit NativeWindow(content::WebContents* web_contents, explicit NativeWindow(content::WebContents* web_contents,
@ -219,6 +243,12 @@ class NativeWindow : public brightray::DefaultWebContentsDelegate,
// The windows has been closed. // The windows has been closed.
bool is_closed_; bool is_closed_;
// The security token of iframe.
std::string node_integration_;
// There is a dialog that has been attached to window.
bool has_dialog_attached_;
// Closure that would be called when window is unresponsive when closing, // Closure that would be called when window is unresponsive when closing,
// it should be cancelled when we can prove that the window is responsive. // it should be cancelled when we can prove that the window is responsive.
base::CancelableClosure window_unresposive_closure_; base::CancelableClosure window_unresposive_closure_;

View file

@ -14,7 +14,7 @@
#include "base/mac/scoped_nsobject.h" #include "base/mac/scoped_nsobject.h"
#include "base/strings/sys_string_conversions.h" #include "base/strings/sys_string_conversions.h"
#include "base/values.h" #include "base/values.h"
#import "browser/ui/atom_event_processing_window.h" #import "browser/ui/cocoa/event_processing_window.h"
#include "brightray/browser/inspectable_web_contents.h" #include "brightray/browser/inspectable_web_contents.h"
#include "brightray/browser/inspectable_web_contents_view.h" #include "brightray/browser/inspectable_web_contents_view.h"
#include "common/draggable_region.h" #include "common/draggable_region.h"
@ -76,7 +76,7 @@ static const CGFloat kAtomWindowCornerRadius = 4.0;
@end @end
@interface AtomNSWindow : AtomEventProcessingWindow { @interface AtomNSWindow : EventProcessingWindow {
@protected @protected
atom::NativeWindowMac* shell_; atom::NativeWindowMac* shell_;
} }
@ -440,9 +440,9 @@ void NativeWindowMac::HandleKeyboardEvent(
event.type == content::NativeWebKeyboardEvent::Char) event.type == content::NativeWebKeyboardEvent::Char)
return; return;
AtomEventProcessingWindow* event_window = EventProcessingWindow* event_window =
static_cast<AtomEventProcessingWindow*>(window()); static_cast<EventProcessingWindow*>(window());
DCHECK([event_window isKindOfClass:[AtomEventProcessingWindow class]]); DCHECK([event_window isKindOfClass:[EventProcessingWindow class]]);
[event_window redispatchKeyEvent:event.os_event]; [event_window redispatchKeyEvent:event.os_event];
} }

View file

@ -194,17 +194,6 @@ class NativeWindowFramelessView : public views::NonClientFrameView {
DISALLOW_COPY_AND_ASSIGN(NativeWindowFramelessView); DISALLOW_COPY_AND_ASSIGN(NativeWindowFramelessView);
}; };
bool WindowHasModalDialog(HWND parent, HWND except, HWND after = NULL) {
HWND hwnd = ::FindWindowEx(parent, after, NULL, NULL);
if (hwnd != except &&
(::GetWindowLong(hwnd, GWL_STYLE) & (WS_VISIBLE | WS_POPUP)))
return true;
else if (hwnd == NULL)
return false;
else
return WindowHasModalDialog(parent, except, hwnd);
}
} // namespace } // namespace
NativeWindowWin::NativeWindowWin(content::WebContents* web_contents, NativeWindowWin::NativeWindowWin(content::WebContents* web_contents,
@ -370,11 +359,6 @@ bool NativeWindowWin::IsKiosk() {
return IsFullscreen(); return IsFullscreen();
} }
bool NativeWindowWin::HasModalDialog() {
return WindowHasModalDialog(GetNativeWindow(),
GetWebContents()->GetView()->GetNativeView());
}
gfx::NativeWindow NativeWindowWin::GetNativeWindow() { gfx::NativeWindow NativeWindowWin::GetNativeWindow() {
return window_->GetNativeView(); return window_->GetNativeView();
} }
@ -417,7 +401,7 @@ void NativeWindowWin::UpdateDraggableRegions(
void NativeWindowWin::HandleKeyboardEvent( void NativeWindowWin::HandleKeyboardEvent(
content::WebContents*, content::WebContents*,
const content::NativeWebKeyboardEvent& event) { const content::NativeWebKeyboardEvent& event) {
if (event.type == WebKit::WebInputEvent::KeyUp) { if (event.type == WebKit::WebInputEvent::RawKeyDown) {
ui::Accelerator accelerator( ui::Accelerator accelerator(
static_cast<ui::KeyboardCode>(event.windowsKeyCode), static_cast<ui::KeyboardCode>(event.windowsKeyCode),
content::GetModifiersFromNativeWebKeyboardEvent(event)); content::GetModifiersFromNativeWebKeyboardEvent(event));

View file

@ -64,7 +64,6 @@ class NativeWindowWin : public NativeWindow,
virtual void FlashFrame(bool flash) OVERRIDE; virtual void FlashFrame(bool flash) OVERRIDE;
virtual void SetKiosk(bool kiosk) OVERRIDE; virtual void SetKiosk(bool kiosk) OVERRIDE;
virtual bool IsKiosk() OVERRIDE; virtual bool IsKiosk() OVERRIDE;
virtual bool HasModalDialog() OVERRIDE;
virtual gfx::NativeWindow GetNativeWindow() OVERRIDE; virtual gfx::NativeWindow GetNativeWindow() OVERRIDE;
void OnMenuCommand(int position, HMENU menu); void OnMenuCommand(int position, HMENU menu);

View file

@ -39,13 +39,13 @@ AtomURLRequestContextGetter::AtomURLRequestContextGetter(
const base::FilePath& base_path, const base::FilePath& base_path,
base::MessageLoop* io_loop, base::MessageLoop* io_loop,
base::MessageLoop* file_loop, base::MessageLoop* file_loop,
scoped_ptr<brightray::NetworkDelegate> network_delegate, base::Callback<scoped_ptr<brightray::NetworkDelegate>(void)> factory,
content::ProtocolHandlerMap* protocol_handlers) content::ProtocolHandlerMap* protocol_handlers)
: base_path_(base_path), : base_path_(base_path),
io_loop_(io_loop), io_loop_(io_loop),
file_loop_(file_loop), file_loop_(file_loop),
job_factory_(NULL), job_factory_(NULL),
network_delegate_(network_delegate.Pass()) { network_delegate_factory_(factory) {
// Must first be created on the UI thread. // Must first be created on the UI thread.
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
@ -68,6 +68,7 @@ net::URLRequestContext* AtomURLRequestContextGetter::GetURLRequestContext() {
if (!url_request_context_.get()) { if (!url_request_context_.get()) {
url_request_context_.reset(new net::URLRequestContext()); url_request_context_.reset(new net::URLRequestContext());
network_delegate_ = network_delegate_factory_.Run().Pass();
url_request_context_->set_network_delegate(network_delegate_.get()); url_request_context_->set_network_delegate(network_delegate_.get());
storage_.reset( storage_.reset(
new net::URLRequestContextStorage(url_request_context_.get())); new net::URLRequestContextStorage(url_request_context_.get()));
@ -89,6 +90,7 @@ net::URLRequestContext* AtomURLRequestContextGetter::GetURLRequestContext() {
net::DhcpProxyScriptFetcherFactory dhcp_factory; net::DhcpProxyScriptFetcherFactory dhcp_factory;
storage_->set_cert_verifier(net::CertVerifier::CreateDefault()); storage_->set_cert_verifier(net::CertVerifier::CreateDefault());
storage_->set_transport_security_state(new net::TransportSecurityState);
storage_->set_proxy_service( storage_->set_proxy_service(
net::CreateProxyServiceUsingV8ProxyResolver( net::CreateProxyServiceUsingV8ProxyResolver(
proxy_config_service_.release(), proxy_config_service_.release(),
@ -116,6 +118,8 @@ net::URLRequestContext* AtomURLRequestContextGetter::GetURLRequestContext() {
net::HttpNetworkSession::Params network_session_params; net::HttpNetworkSession::Params network_session_params;
network_session_params.cert_verifier = network_session_params.cert_verifier =
url_request_context_->cert_verifier(); url_request_context_->cert_verifier();
network_session_params.transport_security_state =
url_request_context_->transport_security_state();
network_session_params.server_bound_cert_service = network_session_params.server_bound_cert_service =
url_request_context_->server_bound_cert_service(); url_request_context_->server_bound_cert_service();
network_session_params.proxy_service = network_session_params.proxy_service =

View file

@ -5,6 +5,7 @@
#ifndef ATOM_BROWSER_NET_ATOM_URL_REQUEST_CONTEXT_GETTER_H_ #ifndef ATOM_BROWSER_NET_ATOM_URL_REQUEST_CONTEXT_GETTER_H_
#define ATOM_BROWSER_NET_ATOM_URL_REQUEST_CONTEXT_GETTER_H_ #define ATOM_BROWSER_NET_ATOM_URL_REQUEST_CONTEXT_GETTER_H_
#include "base/callback.h"
#include "base/files/file_path.h" #include "base/files/file_path.h"
#include "base/memory/scoped_ptr.h" #include "base/memory/scoped_ptr.h"
#include "content/public/browser/content_browser_client.h" #include "content/public/browser/content_browser_client.h"
@ -34,7 +35,7 @@ class AtomURLRequestContextGetter : public net::URLRequestContextGetter {
const base::FilePath& base_path, const base::FilePath& base_path,
base::MessageLoop* io_loop, base::MessageLoop* io_loop,
base::MessageLoop* file_loop, base::MessageLoop* file_loop,
scoped_ptr<brightray::NetworkDelegate> network_delegate, base::Callback<scoped_ptr<brightray::NetworkDelegate>(void)>,
content::ProtocolHandlerMap* protocol_handlers); content::ProtocolHandlerMap* protocol_handlers);
// net::URLRequestContextGetter implementations: // net::URLRequestContextGetter implementations:
@ -53,7 +54,10 @@ class AtomURLRequestContextGetter : public net::URLRequestContextGetter {
base::FilePath base_path_; base::FilePath base_path_;
base::MessageLoop* io_loop_; base::MessageLoop* io_loop_;
base::MessageLoop* file_loop_; base::MessageLoop* file_loop_;
AtomURLRequestJobFactory* job_factory_; AtomURLRequestJobFactory* job_factory_;
base::Callback<scoped_ptr<brightray::NetworkDelegate>(void)>
network_delegate_factory_;
scoped_ptr<net::ProxyConfigService> proxy_config_service_; scoped_ptr<net::ProxyConfigService> proxy_config_service_;
scoped_ptr<brightray::NetworkDelegate> network_delegate_; scoped_ptr<brightray::NetworkDelegate> network_delegate_;

View file

@ -11,7 +11,7 @@
<key>CFBundleIconFile</key> <key>CFBundleIconFile</key>
<string>atom.icns</string> <string>atom.icns</string>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>0.8.5</string> <string>0.9.2</string>
<key>NSMainNibFile</key> <key>NSMainNibFile</key>
<string>MainMenu</string> <string>MainMenu</string>
<key>NSPrincipalClass</key> <key>NSPrincipalClass</key>

View file

Before

Width:  |  Height:  |  Size: 345 KiB

After

Width:  |  Height:  |  Size: 345 KiB

View file

@ -50,8 +50,8 @@ END
// //
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION 0,8,5,0 FILEVERSION 0,9,2,0
PRODUCTVERSION 0,8,5,0 PRODUCTVERSION 0,9,2,0
FILEFLAGSMASK 0x3fL FILEFLAGSMASK 0x3fL
#ifdef _DEBUG #ifdef _DEBUG
FILEFLAGS 0x1L FILEFLAGS 0x1L
@ -68,12 +68,12 @@ BEGIN
BEGIN BEGIN
VALUE "CompanyName", "GitHub, Inc." VALUE "CompanyName", "GitHub, Inc."
VALUE "FileDescription", "Atom-Shell" VALUE "FileDescription", "Atom-Shell"
VALUE "FileVersion", "0.8.5" VALUE "FileVersion", "0.9.2"
VALUE "InternalName", "atom.exe" VALUE "InternalName", "atom.exe"
VALUE "LegalCopyright", "Copyright (C) 2013 GitHub, Inc. All rights reserved." VALUE "LegalCopyright", "Copyright (C) 2013 GitHub, Inc. All rights reserved."
VALUE "OriginalFilename", "atom.exe" VALUE "OriginalFilename", "atom.exe"
VALUE "ProductName", "Atom-Shell" VALUE "ProductName", "Atom-Shell"
VALUE "ProductVersion", "0.8.5" VALUE "ProductVersion", "0.9.2"
END END
END END
BLOCK "VarFileInfo" BLOCK "VarFileInfo"

View file

@ -3,8 +3,8 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#ifndef ATOM_BROWSER_UI_ATOM_MENU_CONTROLLER_MAC_H_ #ifndef ATOM_BROWSER_UI_COCOA_ATOM_MENU_CONTROLLER_H_
#define ATOM_BROWSER_UI_ATOM_MENU_CONTROLLER_MAC_H_ #define ATOM_BROWSER_UI_COCOA_ATOM_MENU_CONTROLLER_H_
#import <Cocoa/Cocoa.h> #import <Cocoa/Cocoa.h>
@ -69,4 +69,4 @@ class MenuModel;
- (NSMenu*)menuFromModel:(ui::MenuModel*)model; - (NSMenu*)menuFromModel:(ui::MenuModel*)model;
@end @end
#endif // ATOM_BROWSER_UI_ATOM_MENU_CONTROLLER_MAC_H_ #endif // ATOM_BROWSER_UI_COCOA_ATOM_MENU_CONTROLLER_H_

View file

@ -3,7 +3,7 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#import "browser/ui/atom_menu_controller_mac.h" #import "browser/ui/cocoa/atom_menu_controller.h"
#include "base/logging.h" #include "base/logging.h"
#include "base/strings/sys_string_conversions.h" #include "base/strings/sys_string_conversions.h"

View file

@ -2,15 +2,15 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#ifndef ATOM_BROWSER_UI_ATOM_EVENT_PROCESSING_WINDOW_H_ #ifndef ATOM_BROWSER_UI_COCOA_EVENT_PROCESSING_WINDOW_H_
#define ATOM_BROWSER_UI_ATOM_EVENT_PROCESSING_WINDOW_H_ #define ATOM_BROWSER_UI_COCOA_EVENT_PROCESSING_WINDOW_H_
#import <Cocoa/Cocoa.h> #import <Cocoa/Cocoa.h>
// Override NSWindow to access unhandled keyboard events (for command // Override NSWindow to access unhandled keyboard events (for command
// processing); subclassing NSWindow is the only method to do // processing); subclassing NSWindow is the only method to do
// this. // this.
@interface AtomEventProcessingWindow : NSWindow { @interface EventProcessingWindow : NSWindow {
@private @private
BOOL redispatchingEvent_; BOOL redispatchingEvent_;
BOOL eventHandled_; BOOL eventHandled_;
@ -27,4 +27,4 @@
- (BOOL)performKeyEquivalent:(NSEvent*)theEvent; - (BOOL)performKeyEquivalent:(NSEvent*)theEvent;
@end @end
#endif // ATOM_BROWSER_UI_ATOM_EVENT_PROCESSING_WINDOW_H_ #endif // ATOM_BROWSER_UI_COCOA_EVENT_PROCESSING_WINDOW_H_

View file

@ -2,17 +2,17 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#import "browser/ui/atom_event_processing_window.h" #import "browser/ui/cocoa/event_processing_window.h"
#include "base/logging.h" #include "base/logging.h"
#import "content/public/browser/render_widget_host_view_mac_base.h" #import "content/public/browser/render_widget_host_view_mac_base.h"
@interface AtomEventProcessingWindow () @interface EventProcessingWindow ()
// Duplicate the given key event, but changing the associated window. // Duplicate the given key event, but changing the associated window.
- (NSEvent*)keyEventForWindow:(NSWindow*)window fromKeyEvent:(NSEvent*)event; - (NSEvent*)keyEventForWindow:(NSWindow*)window fromKeyEvent:(NSEvent*)event;
@end @end
@implementation AtomEventProcessingWindow @implementation EventProcessingWindow
- (BOOL)redispatchKeyEvent:(NSEvent*)event { - (BOOL)redispatchKeyEvent:(NSEvent*)event {
DCHECK(event); DCHECK(event);
@ -103,4 +103,4 @@
return NO; return NO;
} }
@end // AtomEventProcessingWindow @end // EventProcessingWindow

View file

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#import "browser/ui/nsalert_synchronous_sheet_mac.h" #import "browser/ui/cocoa/nsalert_synchronous_sheet.h"
// Private methods -- use prefixes to avoid collisions with Apple's methods // Private methods -- use prefixes to avoid collisions with Apple's methods
@interface NSAlert (SynchronousSheetPrivate) @interface NSAlert (SynchronousSheetPrivate)

View file

@ -163,6 +163,7 @@ class FileDialog {
} }
bool Show(atom::NativeWindow* parent_window) { bool Show(atom::NativeWindow* parent_window) {
atom::NativeWindow::DialogScope dialog_scope(parent_window);
HWND window = parent_window ? parent_window->GetNativeWindow() : NULL; HWND window = parent_window ? parent_window->GetNativeWindow() : NULL;
return dialog_->DoModal(window) == IDOK; return dialog_->DoModal(window) == IDOK;
} }

View file

@ -9,7 +9,7 @@
#include "base/callback.h" #include "base/callback.h"
#include "base/strings/sys_string_conversions.h" #include "base/strings/sys_string_conversions.h"
#include "browser/native_window.h" #include "browser/native_window.h"
#include "browser/ui/nsalert_synchronous_sheet_mac.h" #include "browser/ui/cocoa/nsalert_synchronous_sheet.h"
@interface ModalDelegate : NSObject { @interface ModalDelegate : NSObject {
@private @private

View file

@ -76,6 +76,7 @@ class MessageDialog : public base::MessageLoop::Dispatcher,
string16 title_; string16 title_;
views::Widget* widget_; views::Widget* widget_;
views::MessageBoxView* message_box_view_; views::MessageBoxView* message_box_view_;
scoped_ptr<NativeWindow::DialogScope> dialog_scope_;
std::vector<views::LabelButton*> buttons_; std::vector<views::LabelButton*> buttons_;
MessageBoxCallback callback_; MessageBoxCallback callback_;
@ -96,7 +97,8 @@ MessageDialog::MessageDialog(NativeWindow* parent_window,
result_(-1), result_(-1),
title_(UTF8ToUTF16(title)), title_(UTF8ToUTF16(title)),
widget_(NULL), widget_(NULL),
message_box_view_(NULL) { message_box_view_(NULL),
dialog_scope_(new NativeWindow::DialogScope(parent_window)) {
DCHECK_GT(buttons.size(), 0u); DCHECK_GT(buttons.size(), 0u);
set_owned_by_client(); set_owned_by_client();
@ -174,6 +176,7 @@ string16 MessageDialog::GetWindowTitle() const {
void MessageDialog::WindowClosing() { void MessageDialog::WindowClosing() {
should_close_ = true; should_close_ = true;
dialog_scope_.reset();
if (delete_on_close_) { if (delete_on_close_) {
callback_.Run(GetResult()); callback_.Run(GetResult());

View file

@ -223,5 +223,14 @@
}, },
}, },
}], # OS=="win" }], # OS=="win"
# The breakdpad on Mac assumes Release_Base configuration.
['OS=="mac"', {
'target_defaults': {
'configurations': {
'Release_Base': {
},
},
},
}], # OS=="mac"
], ],
} }

View file

@ -74,8 +74,6 @@ void Clipboard::Clear(const v8::FunctionCallbackInfo<v8::Value>& args) {
// static // static
void Clipboard::Initialize(v8::Handle<v8::Object> target) { void Clipboard::Initialize(v8::Handle<v8::Object> target) {
v8::HandleScope handle_scope(node_isolate);
NODE_SET_METHOD(target, "has", Has); NODE_SET_METHOD(target, "has", Has);
NODE_SET_METHOD(target, "read", Read); NODE_SET_METHOD(target, "read", Read);
NODE_SET_METHOD(target, "readText", ReadText); NODE_SET_METHOD(target, "readText", ReadText);

View file

@ -21,6 +21,11 @@ EventEmitter::EventEmitter(v8::Handle<v8::Object> wrapper) {
} }
EventEmitter::~EventEmitter() { EventEmitter::~EventEmitter() {
// Use Locker in browser process.
scoped_ptr<v8::Locker> locker;
if (node::g_standalone_mode)
locker.reset(new v8::Locker(node_isolate));
// Clear the aligned pointer, it should have been done by ObjectWrap but // Clear the aligned pointer, it should have been done by ObjectWrap but
// somehow node v0.11.x changed this behaviour. // somehow node v0.11.x changed this behaviour.
v8::HandleScope handle_scope(node_isolate); v8::HandleScope handle_scope(node_isolate);
@ -33,6 +38,11 @@ bool EventEmitter::Emit(const std::string& name) {
} }
bool EventEmitter::Emit(const std::string& name, base::ListValue* args) { bool EventEmitter::Emit(const std::string& name, base::ListValue* args) {
// Use Locker in browser process.
scoped_ptr<v8::Locker> locker;
if (node::g_standalone_mode)
locker.reset(new v8::Locker(node_isolate));
v8::HandleScope handle_scope(node_isolate); v8::HandleScope handle_scope(node_isolate);
v8::Handle<v8::Context> context = v8::Context::GetCurrent(); v8::Handle<v8::Context> context = v8::Context::GetCurrent();

View file

@ -122,8 +122,6 @@ void IDWeakMap::Remove(const v8::FunctionCallbackInfo<v8::Value>& args) {
// static // static
void IDWeakMap::Initialize(v8::Handle<v8::Object> target) { void IDWeakMap::Initialize(v8::Handle<v8::Object> target) {
v8::HandleScope handle_scope(node_isolate);
v8::Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(New); v8::Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(New);
t->InstanceTemplate()->SetInternalFieldCount(1); t->InstanceTemplate()->SetInternalFieldCount(1);
t->SetClassName(v8::String::NewSymbol("IDWeakMap")); t->SetClassName(v8::String::NewSymbol("IDWeakMap"));

View file

@ -67,8 +67,6 @@ void Screen::GetPrimaryDisplay(
// static // static
void Screen::Initialize(v8::Handle<v8::Object> target) { void Screen::Initialize(v8::Handle<v8::Object> target) {
v8::HandleScope handle_scope(v8::Isolate::GetCurrent());
v8::Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(New); v8::Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(New);
t->InstanceTemplate()->SetInternalFieldCount(1); t->InstanceTemplate()->SetInternalFieldCount(1);
t->SetClassName(v8::String::NewSymbol("Screen")); t->SetClassName(v8::String::NewSymbol("Screen"));

View file

@ -60,8 +60,6 @@ void Shell::Beep(const v8::FunctionCallbackInfo<v8::Value>& args) {
// static // static
void Shell::Initialize(v8::Handle<v8::Object> target) { void Shell::Initialize(v8::Handle<v8::Object> target) {
v8::HandleScope handle_scope(node_isolate);
NODE_SET_METHOD(target, "showItemInFolder", ShowItemInFolder); NODE_SET_METHOD(target, "showItemInFolder", ShowItemInFolder);
NODE_SET_METHOD(target, "openItem", OpenItem); NODE_SET_METHOD(target, "openItem", OpenItem);
NODE_SET_METHOD(target, "openExternal", OpenExternal); NODE_SET_METHOD(target, "openExternal", OpenExternal);

View file

@ -46,8 +46,6 @@ void TakeHeapSnapshot(const v8::FunctionCallbackInfo<v8::Value>& args) {
} // namespace } // namespace
void InitializeV8Util(v8::Handle<v8::Object> target) { void InitializeV8Util(v8::Handle<v8::Object> target) {
v8::HandleScope handle_scope(node_isolate);
NODE_SET_METHOD(target, "createObjectWithName", CreateObjectWithName); NODE_SET_METHOD(target, "createObjectWithName", CreateObjectWithName);
NODE_SET_METHOD(target, "getHiddenValue", GetHiddenValue); NODE_SET_METHOD(target, "getHiddenValue", GetHiddenValue);
NODE_SET_METHOD(target, "setHiddenValue", SetHiddenValue); NODE_SET_METHOD(target, "setHiddenValue", SetHiddenValue);

View file

@ -53,6 +53,13 @@ void UvOnCallback(uv_async_t* handle, int status) {
g_v8_callback->NewHandle()->Call(global, 0, NULL); g_v8_callback->NewHandle()->Call(global, 0, NULL);
} }
// Called when there is a fatal error in V8, we just crash the process here so
// we can get the stack trace.
void FatalErrorCallback(const char* location, const char* message) {
LOG(ERROR) << "Fatal error in V8: " << location << " " << message;
static_cast<DummyClass*>(NULL)->crash = true;
}
v8::Handle<v8::Object> DumpStackFrame(v8::Handle<v8::StackFrame> stack_frame) { v8::Handle<v8::Object> DumpStackFrame(v8::Handle<v8::StackFrame> stack_frame) {
v8::Local<v8::Object> result = v8::Object::New(); v8::Local<v8::Object> result = v8::Object::New();
result->Set(ToV8Value("line"), ToV8Value(stack_frame->GetLineNumber())); result->Set(ToV8Value("line"), ToV8Value(stack_frame->GetLineNumber()));
@ -76,14 +83,13 @@ node::node_module_struct* GetBuiltinModule(const char *name, bool is_browser);
AtomBindings::AtomBindings() { AtomBindings::AtomBindings() {
uv_async_init(uv_default_loop(), &g_next_tick_uv_handle, UvCallNextTick); uv_async_init(uv_default_loop(), &g_next_tick_uv_handle, UvCallNextTick);
uv_async_init(uv_default_loop(), &g_callback_uv_handle, UvOnCallback); uv_async_init(uv_default_loop(), &g_callback_uv_handle, UvOnCallback);
v8::V8::SetFatalErrorHandler(FatalErrorCallback);
} }
AtomBindings::~AtomBindings() { AtomBindings::~AtomBindings() {
} }
void AtomBindings::BindTo(v8::Handle<v8::Object> process) { void AtomBindings::BindTo(v8::Handle<v8::Object> process) {
v8::HandleScope handle_scope(node_isolate);
NODE_SET_METHOD(process, "atomBinding", Binding); NODE_SET_METHOD(process, "atomBinding", Binding);
NODE_SET_METHOD(process, "crash", Crash); NODE_SET_METHOD(process, "crash", Crash);
NODE_SET_METHOD(process, "activateUvLoop", ActivateUVLoop); NODE_SET_METHOD(process, "activateUvLoop", ActivateUVLoop);
@ -152,18 +158,13 @@ void AtomBindings::ActivateUVLoop(
// static // static
void AtomBindings::Log(const v8::FunctionCallbackInfo<v8::Value>& args) { void AtomBindings::Log(const v8::FunctionCallbackInfo<v8::Value>& args) {
std::string message; v8::String::Utf8Value str(args[0]);
for (int i = 0; i < args.Length(); ++i) logging::LogMessage("CONSOLE", 0, 0).stream() << *str;
message += *v8::String::Utf8Value(args[i]);
logging::LogMessage("CONSOLE", 0, 0).stream() << message;
} }
// static // static
void AtomBindings::GetCurrentStackTrace( void AtomBindings::GetCurrentStackTrace(
const v8::FunctionCallbackInfo<v8::Value>& args) { const v8::FunctionCallbackInfo<v8::Value>& args) {
v8::HandleScope handle_scope(args.GetIsolate());
int stack_limit = kMaxCallStackSize; int stack_limit = kMaxCallStackSize;
FromV8Arguments(args, &stack_limit); FromV8Arguments(args, &stack_limit);

View file

@ -6,8 +6,8 @@
#define ATOM_VERSION_H #define ATOM_VERSION_H
#define ATOM_MAJOR_VERSION 0 #define ATOM_MAJOR_VERSION 0
#define ATOM_MINOR_VERSION 8 #define ATOM_MINOR_VERSION 9
#define ATOM_PATCH_VERSION 5 #define ATOM_PATCH_VERSION 2
#define ATOM_VERSION_IS_RELEASE 1 #define ATOM_VERSION_IS_RELEASE 1

View file

@ -19,10 +19,3 @@ wrapWithActivateUvLoop = (func) ->
process.nextTick = wrapWithActivateUvLoop process.nextTick process.nextTick = wrapWithActivateUvLoop process.nextTick
global.setImmediate = wrapWithActivateUvLoop timers.setImmediate global.setImmediate = wrapWithActivateUvLoop timers.setImmediate
global.clearImmediate = timers.clearImmediate global.clearImmediate = timers.clearImmediate
# The child_process module also needs to activate the uv loop to make the ipc
# channel setup.
# TODO(zcbenz): Find out why this is needed.
childProcess = require 'child_process'
childProcess.spawn = wrapWithActivateUvLoop childProcess.spawn
childProcess.fork = wrapWithActivateUvLoop childProcess.fork

View file

@ -194,6 +194,11 @@ void NodeBindings::RunMessageLoop() {
void NodeBindings::UvRunOnce() { void NodeBindings::UvRunOnce() {
DCHECK(!is_browser_ || BrowserThread::CurrentlyOn(BrowserThread::UI)); DCHECK(!is_browser_ || BrowserThread::CurrentlyOn(BrowserThread::UI));
// Use Locker in browser process.
scoped_ptr<v8::Locker> locker;
if (is_browser_)
locker.reset(new v8::Locker(node_isolate));
v8::HandleScope handle_scope(node_isolate); v8::HandleScope handle_scope(node_isolate);
// Enter node context while dealing with uv events, by default the global // Enter node context while dealing with uv events, by default the global

View file

@ -26,6 +26,23 @@ NodeBindingsMac::NodeBindingsMac(bool is_browser)
NodeBindingsMac::~NodeBindingsMac() { NodeBindingsMac::~NodeBindingsMac() {
} }
void NodeBindingsMac::RunMessageLoop() {
// Get notified when libuv's watcher queue changes.
uv_loop_->data = this;
uv_loop_->on_watcher_queue_updated = OnWatcherQueueChanged;
NodeBindings::RunMessageLoop();
}
// static
void NodeBindingsMac::OnWatcherQueueChanged(uv_loop_t* loop) {
NodeBindingsMac* self = static_cast<NodeBindingsMac*>(loop->data);
// We need to break the io polling in the kqueue thread when loop's watcher
// queue changes, otherwise new events cannot be notified.
self->WakeupEmbedThread();
}
void NodeBindingsMac::PollEvents() { void NodeBindingsMac::PollEvents() {
struct timespec spec; struct timespec spec;
int timeout = uv_backend_timeout(uv_loop_); int timeout = uv_backend_timeout(uv_loop_);

View file

@ -15,7 +15,12 @@ class NodeBindingsMac : public NodeBindings {
explicit NodeBindingsMac(bool is_browser); explicit NodeBindingsMac(bool is_browser);
virtual ~NodeBindingsMac(); virtual ~NodeBindingsMac();
virtual void RunMessageLoop() OVERRIDE;
private: private:
// Called when uv's watcher queue changes.
static void OnWatcherQueueChanged(uv_loop_t* loop);
virtual void PollEvents() OVERRIDE; virtual void PollEvents() OVERRIDE;
// Kqueue to poll for uv's backend fd. // Kqueue to poll for uv's backend fd.

View file

@ -31,6 +31,8 @@ const char kKiosk[] = "kiosk";
// Make windows stays on the top of all other windows. // Make windows stays on the top of all other windows.
const char kAlwaysOnTop[] = "always-on-top"; const char kAlwaysOnTop[] = "always-on-top";
const char kNodeIntegration[] = "node-integration";
} // namespace switches } // namespace switches
} // namespace atom } // namespace atom

View file

@ -26,6 +26,7 @@ extern const char kResizable[];
extern const char kFullscreen[]; extern const char kFullscreen[];
extern const char kKiosk[]; extern const char kKiosk[];
extern const char kAlwaysOnTop[]; extern const char kAlwaysOnTop[];
extern const char kNodeIntegration[];
} // namespace switches } // namespace switches

View file

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleExecutable</key>
<string>Atom Framework</string>
<key>CFBundleIdentifier</key>
<string>com.github.AtomFramework</string>
<key>CFBundleName</key>
<string>Atom Framework</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
</dict>
</plist>

View file

@ -1,42 +1,42 @@
# auto-updater # auto-updater
`auto-updater` module is a simple wrap around the Sparkle framework, it The `auto-updater` module is a simple wrap around the
provides auto update service for the application. [Squirrel](https://github.com/Squirrel/Squirrel.Mac) framework, you should
follow Squirrel's instructions on setting the server.
Before using this module, you should edit the `Info.plist` following ## Event: checking-for-update
https://github.com/andymatuschak/Sparkle/wiki.
## Event: will-install-update Emitted when checking for update has started.
## Event: update-available
Emitted when there is an available update, the update would be downloaded
automatically.
## Event: update-not-available
Emitted when there is no available update.
## Event: update-downloaded
* `event` Event * `event` Event
* `version` String * `releaseNotes` String
* `continueUpdate` Function * `releaseName` String
* `releaseDate` Date
This event is emitted when the update is found and going to be installed. * `updateUrl` String
Calling `event.preventDefault()` would pause it, and you can call
`continueUpdate` to continue the update.
## Event: ready-for-update-on-quit
* `event` Event
* `version` String
* `quitAndUpdate` Function * `quitAndUpdate` Function
This event is emitted when user chose to delay the update until the quit. Emitted when update has been downloaded, calling `quitAndUpdate()` would restart
Calling `quitAndUpdate()` would quit the application and install the update. the application and install the update.
## autoUpdater.setFeedUrl(url) ## autoUpdater.setFeedUrl(url)
* `url` String * `url` String
## autoUpdater.setAutomaticallyChecksForUpdates(flag) Set the `url` and initialize the auto updater. The `url` could not be changed
once it is set.
* `flag` Boolean
## autoUpdater.setAutomaticallyDownloadsUpdates(flag)
* `flag` Boolean
## autoUpdater.checkForUpdates() ## autoUpdater.checkForUpdates()
## autoUpdater.checkForUpdatesInBackground() Ask the server whether there is an update, you have to call `setFeedUrl` before
using this API.

View file

@ -18,9 +18,6 @@ win.show();
You can also create a window without chrome by using You can also create a window without chrome by using
[Frameless Window](frameless-window.md) API. [Frameless Window](frameless-window.md) API.
**Note:** Be careful not to use `window` as the variable name.
## Class: BrowserWindow ## Class: BrowserWindow
`BrowserWindow` is an `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 * `show` Boolean - Whether window should be shown when created
* `frame` Boolean - Specify `false` to create a * `frame` Boolean - Specify `false` to create a
[Frameless Window](frameless-window.md) [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`. Creates a new `BrowserWindow` with native properties set by the `options`.
Usually you only need to set the `width` and `height`, other properties will Usually you only need to set the `width` and `height`, other properties will
have decent default values. 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
<!-- iframe with node integration enabled -->
<iframe name="gh-enable-node-integration" src="https://github.com"></iframe>
<!-- iframe with node integration disabled -->
<iframe src="http://jandan.net"></iframe>
```
### Event: 'page-title-updated' ### Event: 'page-title-updated'
* `event` Event * `event` Event

View file

@ -15,17 +15,24 @@ to understand the source code better.
program. program.
* **browser** - The frontend including the main window, UI, and all browser * **browser** - The frontend including the main window, UI, and all browser
side things. This talks to the renderer to manage web pages. side things. This talks to the renderer to manage web pages.
* **lib** - Javascript part of browser initialization code.
* **ui** - Implementation of UI stuff for different platforms. * **ui** - Implementation of UI stuff for different platforms.
* **atom** - Initializes the javascript environment of browser. * **cocoa** - Cocoa specific source code.
* **gtk** - GTK+ specific source code.
* **win** - Windows GUI specific source code.
* **default_app** - The default page to show when atom-shell is started * **default_app** - The default page to show when atom-shell is started
without providing an app. without providing an app.
* **api** - The implementation of browser side APIs. * **api** - The implementation of browser side APIs.
* **lib** - Javascript part of the API implementation. * **lib** - Javascript part of the API implementation.
* **net** - Network related code.
* **renderer** - Code that runs in renderer. * **renderer** - Code that runs in renderer.
* **lib** - Javascript part of renderer initialization code.
* **api** - The implementation of renderer side APIs. * **api** - The implementation of renderer side APIs.
* **lib** - Javascript part of the API implementation. * **lib** - Javascript part of the API implementation.
* **common** - Code that used by both browser and renderer, including some * **common** - Code that used by both browser and renderer, including some
utility functions and code to integrate node's message loop into Chromium's message loop. utility functions and code to integrate node's message loop into Chromium's message loop.
* **lib** - Common Javascript initialization code.
* **v8** - Utility functions for using V8 and node APIs.
* **api** - The implementation of common APIs, and foundations of * **api** - The implementation of common APIs, and foundations of
atom-shell's built-in modules. atom-shell's built-in modules.
* **lib** - Javascript part of the API implementation. * **lib** - Javascript part of the API implementation.
@ -35,7 +42,7 @@ to understand the source code better.
## Structure of other directories ## Structure of other directories
* **vendor** - Build dependencies. * **vendor** - Build dependencies.
* **tools** - Helper scripts to build atom-shell. * **tools** - Helper scripts used by gyp files.
* **node_modules** - Third party node modules used for building or running * **node_modules** - Third party node modules used for building or running
specs. specs.
* **out** - Output directory for `ninja`. * **out** - Output directory for `ninja`.

View file

@ -1,17 +1,17 @@
{ {
"name": "atom-shell", "name": "atom-shell",
"version": "0.8.5", "version": "0.9.2",
"devDependencies": { "devDependencies": {
"coffee-script": "~1.6.3", "coffee-script": "~1.6.3",
"coffeelint": "~0.6.1", "coffeelint": "~0.6.1",
"formidable": "~1.0.14",
"mocha": "~1.13.0", "mocha": "~1.13.0",
"pathwatcher": "0.14.0", "pathwatcher": "0.14.0",
"q": "0.9.7", "q": "0.9.7",
"walkdir": "~0.0.7",
"runas": "0.3.0", "runas": "0.3.0",
"formidable": "~1.0.14", "temp": "~0.6.0",
"temp": "~0.6.0" "walkdir": "~0.0.7"
}, },
"private": true, "private": true,

View file

@ -5,12 +5,14 @@
#include "renderer/atom_render_view_observer.h" #include "renderer/atom_render_view_observer.h"
#include "common/api/api_messages.h" #include "common/api/api_messages.h"
#include "content/public/renderer/render_view.h"
#include "ipc/ipc_message_macros.h" #include "ipc/ipc_message_macros.h"
#include "renderer/api/atom_renderer_bindings.h" #include "renderer/api/atom_renderer_bindings.h"
#include "renderer/atom_renderer_client.h" #include "renderer/atom_renderer_client.h"
#include "third_party/WebKit/public/web/WebDraggableRegion.h" #include "third_party/WebKit/public/web/WebDraggableRegion.h"
#include "third_party/WebKit/public/web/WebDocument.h" #include "third_party/WebKit/public/web/WebDocument.h"
#include "third_party/WebKit/public/web/WebFrame.h" #include "third_party/WebKit/public/web/WebFrame.h"
#include "third_party/WebKit/public/web/WebView.h"
#include "common/v8/node_common.h" #include "common/v8/node_common.h"
@ -53,6 +55,13 @@ bool AtomRenderViewObserver::OnMessageReceived(const IPC::Message& message) {
void AtomRenderViewObserver::OnBrowserMessage(const string16& channel, void AtomRenderViewObserver::OnBrowserMessage(const string16& channel,
const base::ListValue& args) { const base::ListValue& args) {
if (!render_view()->GetWebView())
return;
WebKit::WebFrame* frame = render_view()->GetWebView()->mainFrame();
if (!renderer_client_->IsNodeBindingEnabled(frame))
return;
renderer_client_->atom_bindings()->OnBrowserMessage( renderer_client_->atom_bindings()->OnBrowserMessage(
render_view(), channel, args); render_view(), channel, args);
} }

View file

@ -6,23 +6,52 @@
#include <algorithm> #include <algorithm>
#include "base/command_line.h"
#include "common/node_bindings.h" #include "common/node_bindings.h"
#include "common/options_switches.h"
#include "renderer/api/atom_renderer_bindings.h" #include "renderer/api/atom_renderer_bindings.h"
#include "renderer/atom_render_view_observer.h" #include "renderer/atom_render_view_observer.h"
#include "third_party/WebKit/public/web/WebFrame.h"
#include "common/v8/node_common.h" #include "common/v8/node_common.h"
namespace atom { 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() AtomRendererClient::AtomRendererClient()
: node_bindings_(NodeBindings::Create(false)), : node_integration_(ALL),
atom_bindings_(new AtomRendererBindings) { main_frame_(NULL) {
// Translate the token.
std::string token = CommandLine::ForCurrentProcess()->
GetSwitchValueASCII(switches::kNodeIntegration);
if (token == kExceptIframe)
node_integration_ = EXCEPT_IFRAME;
else if (token == kManualEnableIframe)
node_integration_ = MANUAL_ENABLE_IFRAME;
else if (token == kDisable)
node_integration_ = DISABLE;
if (IsNodeBindingEnabled()) {
node_bindings_.reset(NodeBindings::Create(false));
atom_bindings_.reset(new AtomRendererBindings);
}
} }
AtomRendererClient::~AtomRendererClient() { AtomRendererClient::~AtomRendererClient() {
} }
void AtomRendererClient::RenderThreadStarted() { void AtomRendererClient::RenderThreadStarted() {
if (!IsNodeBindingEnabled())
return;
node_bindings_->Initialize(); node_bindings_->Initialize();
node_bindings_->PrepareMessageLoop(); node_bindings_->PrepareMessageLoop();
@ -43,6 +72,13 @@ void AtomRendererClient::DidCreateScriptContext(WebKit::WebFrame* frame,
v8::Handle<v8::Context> context, v8::Handle<v8::Context> context,
int extension_group, int extension_group,
int world_id) { int world_id) {
// The first web frame is the main frame.
if (main_frame_ == NULL)
main_frame_ = frame;
if (!IsNodeBindingEnabled(frame))
return;
v8::Context::Scope scope(context); v8::Context::Scope scope(context);
// Check the existance of process object to prevent duplicate initialization. // Check the existance of process object to prevent duplicate initialization.
@ -70,6 +106,9 @@ void AtomRendererClient::WillReleaseScriptContext(
WebKit::WebFrame* frame, WebKit::WebFrame* frame,
v8::Handle<v8::Context> context, v8::Handle<v8::Context> context,
int world_id) { int world_id) {
if (!IsNodeBindingEnabled(frame))
return;
node::Environment* env = node::Environment::GetCurrent(context); node::Environment* env = node::Environment::GetCurrent(context);
if (env == NULL) { if (env == NULL) {
LOG(ERROR) << "Encounter a non-node context when releasing script context"; LOG(ERROR) << "Encounter a non-node context when releasing script context";
@ -108,4 +147,21 @@ bool AtomRendererClient::ShouldFork(WebKit::WebFrame* frame,
return true; return true;
} }
bool AtomRendererClient::IsNodeBindingEnabled(WebKit::WebFrame* frame) {
if (node_integration_ == DISABLE)
return false;
// 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(kEnableNodeIntegration)
== std::string::npos)
return false;
else if (node_integration_ == EXCEPT_IFRAME && frame != NULL)
return false;
else
return true;
}
} // namespace atom } // namespace atom

View file

@ -23,9 +23,18 @@ class AtomRendererClient : public content::ContentRendererClient {
AtomRendererClient(); AtomRendererClient();
virtual ~AtomRendererClient(); virtual ~AtomRendererClient();
bool IsNodeBindingEnabled(WebKit::WebFrame* frame = NULL);
AtomRendererBindings* atom_bindings() const { return atom_bindings_.get(); } AtomRendererBindings* atom_bindings() const { return atom_bindings_.get(); }
private: private:
enum NodeIntegration {
ALL,
EXCEPT_IFRAME,
MANUAL_ENABLE_IFRAME,
DISABLE,
};
virtual void RenderThreadStarted() OVERRIDE; virtual void RenderThreadStarted() OVERRIDE;
virtual void RenderViewCreated(content::RenderView*) OVERRIDE; virtual void RenderViewCreated(content::RenderView*) OVERRIDE;
virtual void DidCreateScriptContext(WebKit::WebFrame* frame, virtual void DidCreateScriptContext(WebKit::WebFrame* frame,
@ -47,6 +56,12 @@ class AtomRendererClient : public content::ContentRendererClient {
scoped_ptr<NodeBindings> node_bindings_; scoped_ptr<NodeBindings> node_bindings_;
scoped_ptr<AtomRendererBindings> atom_bindings_; scoped_ptr<AtomRendererBindings> atom_bindings_;
// The level of node integration we should support.
NodeIntegration node_integration_;
// The main frame.
WebKit::WebFrame* main_frame_;
DISALLOW_COPY_AND_ASSIGN(AtomRendererClient); DISALLOW_COPY_AND_ASSIGN(AtomRendererClient);
}; };

View file

@ -25,11 +25,12 @@ global.module = module
# Set the __filename to the path of html file if it's file:// protocol. # Set the __filename to the path of html file if it's file:// protocol.
if window.location.protocol is 'file:' if window.location.protocol is 'file:'
global.__filename = pathname =
if process.platform is 'win32' if process.platform is 'win32'
window.location.pathname.substr 1 window.location.pathname.substr 1
else else
window.location.pathname window.location.pathname
global.__filename = decodeURIComponent pathname
global.__dirname = path.dirname global.__filename global.__dirname = path.dirname global.__filename
# Set module's filename so relative require can work as expected. # Set module's filename so relative require can work as expected.

View file

@ -5,12 +5,12 @@ import os
import subprocess import subprocess
import sys import sys
from lib.config import LIBCHROMIUMCONTENT_COMMIT, BASE_URL
from lib.util import scoped_cwd from lib.util import scoped_cwd
SOURCE_ROOT = os.path.abspath(os.path.dirname(os.path.dirname(__file__))) SOURCE_ROOT = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))
VENDOR_DIR = os.path.join(SOURCE_ROOT, 'vendor') 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' PYTHON_26_URL = 'https://chromium.googlesource.com/chromium/deps/python_26'
@ -52,7 +52,8 @@ def update_submodules():
def bootstrap_brightray(url): def bootstrap_brightray(url):
bootstrap = os.path.join(VENDOR_DIR, 'brightray', 'script', 'bootstrap') 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(): def update_apm():

View file

@ -5,34 +5,51 @@ import re
import subprocess import subprocess
import sys import sys
from lib.util import get_atom_shell_version, scoped_cwd
SOURCE_ROOT = os.path.abspath(os.path.dirname(os.path.dirname(__file__))) SOURCE_ROOT = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))
def main(): def main():
if len(sys.argv) != 2: if len(sys.argv) != 2 or sys.argv[1] == '-h':
print 'Usage: bump-version.py version' print 'Usage: bump-version.py [<version> | major | minor | patch]'
return 1 return 1
version = sys.argv[1] option = sys.argv[1]
if version[0] == 'v': increments = ['major', 'minor', 'patch', 'build']
version = version[1:] if option in increments:
versions = parse_version(version) version = get_atom_shell_version()
versions = parse_version(version.split('-')[0])
versions = increase_version(versions, increments.index(option))
else:
versions = parse_version(option)
os.chdir(SOURCE_ROOT) version = '.'.join(versions[:3])
with scoped_cwd(SOURCE_ROOT):
update_package_json(version) update_package_json(version)
update_win_rc(version, versions) update_win_rc(version, versions)
update_version_h(versions) update_version_h(versions)
update_info_plist(version) update_info_plist(version)
tag_version(version) tag_version(version)
git_push()
def parse_version(version): def parse_version(version):
if version[0] == 'v':
version = version[1:]
vs = version.split('.') vs = version.split('.')
if len(vs) > 4: if len(vs) > 4:
return vs[0:4] return vs[0:4]
else: else:
return vs + [0] * (4 - len(vs)) return vs + ['0'] * (4 - len(vs))
def increase_version(versions, index):
versions[index] = str(int(versions[index]) + 1)
return versions
def update_package_json(version): def update_package_json(version):
@ -54,7 +71,7 @@ def update_win_rc(version, versions):
pattern_fvs = re.compile(' *VALUE "FileVersion", "[0-9.]+"') pattern_fvs = re.compile(' *VALUE "FileVersion", "[0-9.]+"')
pattern_pvs = re.compile(' *VALUE "ProductVersion", "[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: with open(win_rc, 'r') as f:
lines = f.readlines() lines = f.readlines()
@ -92,7 +109,7 @@ def update_version_h(versions):
def update_info_plist(version): 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: with open(info_plist, 'r') as f:
lines = f.readlines() lines = f.readlines()
@ -112,5 +129,9 @@ def tag_version(version):
subprocess.check_call(['git', 'tag', 'v{0}'.format(version)]) subprocess.check_call(['git', 'tag', 'v{0}'.format(version)])
def git_push():
subprocess.check_call(['git', 'push'])
if __name__ == '__main__': if __name__ == '__main__':
sys.exit(main()) sys.exit(main())

View file

@ -13,6 +13,7 @@ SOURCE_ROOT = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))
def main(): def main():
rm_rf(os.path.join(SOURCE_ROOT, 'out')) rm_rf(os.path.join(SOURCE_ROOT, 'out'))
rm_rf(os.path.join(SOURCE_ROOT, 'node_modules')) rm_rf(os.path.join(SOURCE_ROOT, 'node_modules'))
rm_rf(os.path.join(SOURCE_ROOT, 'frameworks'))
rm_rf(os.path.join(SOURCE_ROOT, 'vendor', 'brightray', 'vendor', 'download', rm_rf(os.path.join(SOURCE_ROOT, 'vendor', 'brightray', 'vendor', 'download',
'libchromiumcontent')) 'libchromiumcontent'))

8
script/cpplint.py vendored
View file

@ -6,13 +6,13 @@ import subprocess
import sys import sys
IGNORE_FILES = [ IGNORE_FILES = [
'app/win/resource.h',
'browser/atom_application_mac.h', 'browser/atom_application_mac.h',
'browser/atom_application_delegate_mac.h', 'browser/atom_application_delegate_mac.h',
'browser/native_window_mac.h', 'browser/native_window_mac.h',
'browser/ui/atom_event_processing_window.h', 'browser/resources/win/resource.h',
'browser/ui/atom_menu_controller_mac.h', 'browser/ui/cocoa/event_processing_window.h',
'browser/ui/nsalert_synchronous_sheet_mac.h', 'browser/ui/cocoa/atom_menu_controller.h',
'browser/ui/cocoa/nsalert_synchronous_sheet.h',
'common/api/api_messages.cc', 'common/api/api_messages.cc',
'common/api/api_messages.h', 'common/api/api_messages.h',
'common/atom_version.h', 'common/atom_version.h',

View file

@ -7,13 +7,12 @@ import subprocess
import sys import sys
import tarfile 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, \ from lib.util import scoped_cwd, rm_rf, get_atom_shell_version, make_zip, \
safe_mkdir safe_mkdir
ATOM_SHELL_VRESION = get_atom_shell_version() ATOM_SHELL_VRESION = get_atom_shell_version()
NODE_VERSION = 'v0.11.10'
BASE_URL = 'https://gh-contractor-zcbenz.s3.amazonaws.com/libchromiumcontent'
SOURCE_ROOT = os.path.abspath(os.path.dirname(os.path.dirname(__file__))) SOURCE_ROOT = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))
DIST_DIR = os.path.join(SOURCE_ROOT, 'dist') DIST_DIR = os.path.join(SOURCE_ROOT, 'dist')
@ -163,7 +162,8 @@ def download_libchromiumcontent_symbols(url):
download = os.path.join(brightray_dir, 'libchromiumcontent', 'script', download = os.path.join(brightray_dir, 'libchromiumcontent', 'script',
'download') '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(): def create_symbols():

5
script/lib/config.py Normal file
View file

@ -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'

View file

@ -1,54 +0,0 @@
#!/usr/bin/env coffee
# Usage:
# Copy the crash log into pasteboard and then run
# pbpaste | ./script/translate-crash-log-addresses.coffee
atos = (addresses, callback) ->
path = require 'path'
exec = require('child_process').exec
exec 'atos -o vendor/brightray/vendor/download/libchromiumcontent/Release/libchromiumcontent.dylib -arch i386 '.concat(addresses...), (error, stdout, stderr) ->
throw error if error?
callback stdout.split('\n')
parse_stack_trace = (raw) ->
lines = {}
addresses = []
for line in raw
columns = line.split /\ +/
if columns[1] == 'libchromiumcontent.dylib' and /0x[a-f0-9]+/.test columns[3]
lines[columns[0]] = addresses.length
addresses.push '0x' + parseInt(columns[5]).toString(16) + ' '
atos addresses, (parsed) ->
for line in raw
columns = line.split /\ +/
frame = columns[0]
if lines[frame]?
console.log frame, parsed[lines[frame]]
else
console.log line
parse_log_file = (content) ->
state = 'start'
stack_trace = []
lines = content.split /\r?\n/
for line in lines
if state == 'start'
if /Thread \d+ Crashed::/.test line
console.log line
state = 'parse'
else if state == 'parse'
break if line == ''
stack_trace.push line
parse_stack_trace stack_trace
input = ''
process.stdin.resume()
process.stdin.setEncoding 'utf8'
process.stdin.on 'data', (chunk) ->
input += chunk
process.stdin.on 'end', ->
parse_log_file input

View file

@ -7,13 +7,15 @@ from lib.util import safe_mkdir, extract_zip, tempdir, download
SOURCE_ROOT = os.path.abspath(os.path.dirname(os.path.dirname(__file__))) SOURCE_ROOT = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))
FRAMEWORKS_URL = 'https://gh-contractor-zcbenz.s3.amazonaws.com/frameworks' FRAMEWORKS_URL = 'http://atom-alpha.s3.amazonaws.com'
def main(): def main():
os.chdir(SOURCE_ROOT) os.chdir(SOURCE_ROOT)
safe_mkdir('frameworks') safe_mkdir('frameworks')
download_and_unzip('Sparkle') download_and_unzip('Mantle')
download_and_unzip('ReactiveCocoa')
download_and_unzip('Squirrel')
def download_and_unzip(framework): def download_and_unzip(framework):

View file

@ -8,6 +8,7 @@ import subprocess
import sys import sys
import tempfile import tempfile
from lib.config import NODE_VERSION
from lib.util import get_atom_shell_version, scoped_cwd, safe_mkdir from lib.util import get_atom_shell_version, scoped_cwd, safe_mkdir
from lib.github import GitHub from lib.github import GitHub
@ -21,7 +22,6 @@ TARGET_PLATFORM = {
ATOM_SHELL_REPO = 'atom/atom-shell' ATOM_SHELL_REPO = 'atom/atom-shell'
ATOM_SHELL_VRESION = get_atom_shell_version() ATOM_SHELL_VRESION = get_atom_shell_version()
NODE_VERSION = 'v0.11.10'
SOURCE_ROOT = os.path.abspath(os.path.dirname(os.path.dirname(__file__))) SOURCE_ROOT = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))
OUT_DIR = os.path.join(SOURCE_ROOT, 'out', 'Release') OUT_DIR = os.path.join(SOURCE_ROOT, 'out', 'Release')

2
vendor/apm vendored

@ -1 +1 @@
Subproject commit 35edbb07fb4abba49dd97d12a1ad8c4adb71625f Subproject commit af40a0ed55a5df3e8f7a7707e17ab2493edb94a3

2
vendor/brightray vendored

@ -1 +1 @@
Subproject commit d7dd5547919eee15e5003c6d05e31183503418ed Subproject commit 569ea3f1e14b9214528be09dfc2117e387c0a03f

2
vendor/node vendored

@ -1 +1 @@
Subproject commit 184a341c2b959a092f64b168e3d55b11d13583bf Subproject commit 80c5e17c09fdf2fc0b74353b285bb33a6ecf5e62