Merge pull request #101 from atom/no-blocking-browser
Make the browser non-blocking
This commit is contained in:
commit
6aefb0f76f
38 changed files with 999 additions and 412 deletions
1
atom.gyp
1
atom.gyp
|
@ -157,6 +157,7 @@
|
|||
'common/platform_util.h',
|
||||
'common/platform_util_mac.mm',
|
||||
'common/platform_util_win.cc',
|
||||
'common/v8_conversions.h',
|
||||
'common/v8_value_converter_impl.cc',
|
||||
'common/v8_value_converter_impl.h',
|
||||
'renderer/api/atom_api_renderer_ipc.cc',
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include "base/values.h"
|
||||
#include "base/command_line.h"
|
||||
#include "browser/browser.h"
|
||||
#include "common/v8_conversions.h"
|
||||
#include "vendor/node/src/node.h"
|
||||
|
||||
namespace atom {
|
||||
|
@ -111,14 +112,14 @@ v8::Handle<v8::Value> App::GetVersion(const v8::Arguments &args) {
|
|||
v8::Handle<v8::Value> App::AppendSwitch(const v8::Arguments &args) {
|
||||
v8::HandleScope scope;
|
||||
|
||||
if (!args[0]->IsString())
|
||||
std::string switch_string;
|
||||
if (!FromV8Arguments(args, &switch_string))
|
||||
return node::ThrowError("Bad argument");
|
||||
|
||||
std::string switch_string(*v8::String::Utf8Value(args[0]));
|
||||
if (args.Length() == 1) {
|
||||
CommandLine::ForCurrentProcess()->AppendSwitch(switch_string);
|
||||
} else {
|
||||
std::string value(*v8::String::Utf8Value(args[1]));
|
||||
std::string value = FromV8Value(args[1]);
|
||||
CommandLine::ForCurrentProcess()->AppendSwitchASCII(
|
||||
switch_string, value);
|
||||
}
|
||||
|
@ -130,10 +131,10 @@ v8::Handle<v8::Value> App::AppendSwitch(const v8::Arguments &args) {
|
|||
v8::Handle<v8::Value> App::AppendArgument(const v8::Arguments &args) {
|
||||
v8::HandleScope scope;
|
||||
|
||||
if (!args[0]->IsString())
|
||||
std::string value;
|
||||
if (!FromV8Arguments(args, &value))
|
||||
return node::ThrowError("Bad argument");
|
||||
|
||||
std::string value(*v8::String::Utf8Value(args[0]));
|
||||
CommandLine::ForCurrentProcess()->AppendArg(value);
|
||||
|
||||
return v8::Undefined();
|
||||
|
@ -143,7 +144,7 @@ v8::Handle<v8::Value> App::AppendArgument(const v8::Arguments &args) {
|
|||
|
||||
// static
|
||||
v8::Handle<v8::Value> App::DockBounce(const v8::Arguments& args) {
|
||||
std::string type(*v8::String::Utf8Value(args[0]));
|
||||
std::string type = FromV8Value(args[0]);
|
||||
int request_id = -1;
|
||||
|
||||
if (type == "critical")
|
||||
|
@ -158,21 +159,20 @@ v8::Handle<v8::Value> App::DockBounce(const v8::Arguments& args) {
|
|||
|
||||
// static
|
||||
v8::Handle<v8::Value> App::DockCancelBounce(const v8::Arguments& args) {
|
||||
Browser::Get()->DockCancelBounce(args[0]->IntegerValue());
|
||||
Browser::Get()->DockCancelBounce(FromV8Value(args[0]));
|
||||
return v8::Undefined();
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> App::DockSetBadgeText(const v8::Arguments& args) {
|
||||
std::string label(*v8::String::Utf8Value(args[0]));
|
||||
Browser::Get()->DockSetBadgeText(label);
|
||||
Browser::Get()->DockSetBadgeText(FromV8Value(args[0]));
|
||||
return v8::Undefined();
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> App::DockGetBadgeText(const v8::Arguments& args) {
|
||||
std::string text(Browser::Get()->DockGetBadgeText());
|
||||
return v8::String::New(text.data(), text.size());
|
||||
return ToV8Value(text);
|
||||
}
|
||||
|
||||
#endif // defined(OS_MACOSX)
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
#include "base/values.h"
|
||||
#include "browser/auto_updater.h"
|
||||
#include "common/v8_conversions.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
|
@ -56,7 +57,7 @@ v8::Handle<v8::Value> AutoUpdater::New(const v8::Arguments &args) {
|
|||
|
||||
// static
|
||||
v8::Handle<v8::Value> AutoUpdater::SetFeedURL(const v8::Arguments &args) {
|
||||
auto_updater::AutoUpdater::SetFeedURL(*v8::String::Utf8Value(args[0]));
|
||||
auto_updater::AutoUpdater::SetFeedURL(FromV8Value(args[0]));
|
||||
return v8::Undefined();
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
#include "base/values.h"
|
||||
#include "common/api/api_messages.h"
|
||||
#include "common/v8_conversions.h"
|
||||
#include "common/v8_value_converter_impl.h"
|
||||
#include "content/public/browser/render_view_host.h"
|
||||
#include "vendor/node/src/node.h"
|
||||
|
@ -22,13 +23,11 @@ namespace api {
|
|||
v8::Handle<v8::Value> BrowserIPC::Send(const v8::Arguments &args) {
|
||||
v8::HandleScope scope;
|
||||
|
||||
if (!args[0]->IsString() || !args[1]->IsNumber() || !args[2]->IsNumber())
|
||||
string16 channel;
|
||||
int process_id, routing_id;
|
||||
if (!FromV8Arguments(args, &channel, &process_id, &routing_id))
|
||||
return node::ThrowTypeError("Bad argument");
|
||||
|
||||
std::string channel(*v8::String::Utf8Value(args[0]));
|
||||
int process_id = args[1]->IntegerValue();
|
||||
int routing_id = args[2]->IntegerValue();
|
||||
|
||||
RenderViewHost* render_view_host(RenderViewHost::FromID(
|
||||
process_id, routing_id));
|
||||
if (!render_view_host)
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include "browser/api/atom_api_crash_reporter.h"
|
||||
|
||||
#include "browser/crash_reporter.h"
|
||||
#include "common/v8_conversions.h"
|
||||
#include "vendor/node/src/node.h"
|
||||
#include "vendor/node/src/node_internals.h"
|
||||
|
||||
|
@ -14,22 +15,20 @@ namespace api {
|
|||
|
||||
// static
|
||||
v8::Handle<v8::Value> CrashReporter::SetCompanyName(const v8::Arguments &args) {
|
||||
std::string name(*v8::String::Utf8Value(args[0]));
|
||||
crash_reporter::CrashReporter::SetCompanyName(name);
|
||||
crash_reporter::CrashReporter::SetCompanyName(FromV8Value(args[0]));
|
||||
return v8::Undefined();
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> CrashReporter::SetSubmissionURL(
|
||||
const v8::Arguments &args) {
|
||||
std::string url(*v8::String::Utf8Value(args[0]));
|
||||
crash_reporter::CrashReporter::SetSubmissionURL(url);
|
||||
crash_reporter::CrashReporter::SetSubmissionURL(FromV8Value(args[0]));
|
||||
return v8::Undefined();
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> CrashReporter::SetAutoSubmit(const v8::Arguments &args) {
|
||||
crash_reporter::CrashReporter::SetAutoSubmit(args[0]->BooleanValue());
|
||||
crash_reporter::CrashReporter::SetAutoSubmit(FromV8Value(args[0]));
|
||||
return v8::Undefined();
|
||||
}
|
||||
|
||||
|
|
|
@ -4,14 +4,14 @@
|
|||
|
||||
#include "browser/api/atom_api_dialog.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "base/utf_string_conversions.h"
|
||||
#include "base/values.h"
|
||||
#include "browser/api/atom_api_window.h"
|
||||
#include "base/bind.h"
|
||||
#include "browser/native_window.h"
|
||||
#include "browser/ui/file_dialog.h"
|
||||
#include "browser/ui/message_box.h"
|
||||
#include "common/v8_conversions.h"
|
||||
#include "vendor/node/src/node_internals.h"
|
||||
|
||||
using node::node_isolate;
|
||||
|
||||
namespace atom {
|
||||
|
||||
|
@ -19,14 +19,24 @@ namespace api {
|
|||
|
||||
namespace {
|
||||
|
||||
base::FilePath V8ValueToFilePath(v8::Handle<v8::Value> path) {
|
||||
std::string path_string(*v8::String::Utf8Value(path));
|
||||
return base::FilePath::FromUTF8Unsafe(path_string);
|
||||
template<typename T>
|
||||
void CallV8Function(v8::Persistent<v8::Function> callback, T arg) {
|
||||
DCHECK(!callback.IsEmpty());
|
||||
|
||||
v8::HandleScope scope;
|
||||
v8::Handle<v8::Value> value = ToV8Value(arg);
|
||||
callback->Call(callback, 1, &value);
|
||||
callback.Dispose(node_isolate);
|
||||
}
|
||||
|
||||
v8::Handle<v8::Value> FilePathToV8Value(const base::FilePath path) {
|
||||
std::string path_string(path.AsUTF8Unsafe());
|
||||
return v8::String::New(path_string.data(), path_string.size());
|
||||
template<typename T>
|
||||
void CallV8Function2(v8::Persistent<v8::Function> callback,
|
||||
bool result,
|
||||
T arg) {
|
||||
if (result)
|
||||
return CallV8Function<T>(callback, arg);
|
||||
else
|
||||
return CallV8Function<void*>(callback, NULL);
|
||||
}
|
||||
|
||||
void Initialize(v8::Handle<v8::Object> target) {
|
||||
|
@ -42,84 +52,103 @@ void Initialize(v8::Handle<v8::Object> target) {
|
|||
v8::Handle<v8::Value> ShowMessageBox(const v8::Arguments &args) {
|
||||
v8::HandleScope scope;
|
||||
|
||||
if (!args[0]->IsNumber() || // type
|
||||
!args[1]->IsArray() || // buttons
|
||||
!args[2]->IsString() || // title
|
||||
!args[3]->IsString() || // message
|
||||
!args[4]->IsString()) // detail
|
||||
int type;
|
||||
std::vector<std::string> buttons;
|
||||
std::string title, message, detail;
|
||||
if (!FromV8Arguments(args, &type, &buttons, &title, &message, &detail))
|
||||
return node::ThrowTypeError("Bad argument");
|
||||
|
||||
NativeWindow* native_window = NULL;
|
||||
if (args[5]->IsObject()) {
|
||||
Window* window = Window::Unwrap<Window>(args[5]->ToObject());
|
||||
if (!window || !window->window())
|
||||
return node::ThrowError("Invalid window");
|
||||
NativeWindow* native_window = FromV8Value(args[5]);
|
||||
v8::Persistent<v8::Function> callback = FromV8Value(args[6]);
|
||||
|
||||
native_window = window->window();
|
||||
if (callback.IsEmpty()) {
|
||||
int chosen = atom::ShowMessageBox(
|
||||
native_window,
|
||||
(MessageBoxType)type,
|
||||
buttons,
|
||||
title,
|
||||
message,
|
||||
detail);
|
||||
return scope.Close(v8::Integer::New(chosen));
|
||||
} else {
|
||||
atom::ShowMessageBox(
|
||||
native_window,
|
||||
(MessageBoxType)type,
|
||||
buttons,
|
||||
title,
|
||||
message,
|
||||
detail,
|
||||
base::Bind(&CallV8Function<int>, callback));
|
||||
return v8::Undefined();
|
||||
}
|
||||
|
||||
MessageBoxType type = (MessageBoxType)(args[0]->IntegerValue());
|
||||
|
||||
std::vector<std::string> buttons;
|
||||
v8::Handle<v8::Array> v8_buttons = v8::Handle<v8::Array>::Cast(args[1]);
|
||||
for (uint32_t i = 0; i < v8_buttons->Length(); ++i)
|
||||
buttons.push_back(*v8::String::Utf8Value(v8_buttons->Get(i)));
|
||||
|
||||
std::string title(*v8::String::Utf8Value(args[2]));
|
||||
std::string message(*v8::String::Utf8Value(args[3]));
|
||||
std::string detail(*v8::String::Utf8Value(args[4]));
|
||||
|
||||
int chosen = atom::ShowMessageBox(
|
||||
native_window, type, buttons, title, message, detail);
|
||||
return scope.Close(v8::Integer::New(chosen));
|
||||
}
|
||||
|
||||
v8::Handle<v8::Value> ShowOpenDialog(const v8::Arguments &args) {
|
||||
v8::HandleScope scope;
|
||||
|
||||
if (!args[0]->IsString() || // title
|
||||
!args[1]->IsString() || // default_path
|
||||
!args[2]->IsNumber()) // properties
|
||||
std::string title;
|
||||
base::FilePath default_path;
|
||||
int properties;
|
||||
if (!FromV8Arguments(args, &title, &default_path, &properties))
|
||||
return node::ThrowTypeError("Bad argument");
|
||||
|
||||
std::string title(*v8::String::Utf8Value(args[0]));
|
||||
base::FilePath default_path(V8ValueToFilePath(args[1]));
|
||||
int properties = args[2]->IntegerValue();
|
||||
NativeWindow* native_window = FromV8Value(args[3]);
|
||||
v8::Persistent<v8::Function> callback = FromV8Value(args[4]);
|
||||
|
||||
std::vector<base::FilePath> paths;
|
||||
if (!file_dialog::ShowOpenDialog(title, default_path, properties, &paths))
|
||||
if (callback.IsEmpty()) {
|
||||
std::vector<base::FilePath> paths;
|
||||
if (!file_dialog::ShowOpenDialog(native_window,
|
||||
title,
|
||||
default_path,
|
||||
properties,
|
||||
&paths))
|
||||
return v8::Undefined();
|
||||
|
||||
v8::Handle<v8::Array> result = v8::Array::New(paths.size());
|
||||
for (size_t i = 0; i < paths.size(); ++i)
|
||||
result->Set(i, ToV8Value(paths[i]));
|
||||
|
||||
return scope.Close(result);
|
||||
} else {
|
||||
file_dialog::ShowOpenDialog(
|
||||
native_window,
|
||||
title,
|
||||
default_path,
|
||||
properties,
|
||||
base::Bind(&CallV8Function2<const std::vector<base::FilePath>&>,
|
||||
callback));
|
||||
return v8::Undefined();
|
||||
|
||||
v8::Handle<v8::Array> result = v8::Array::New(paths.size());
|
||||
for (size_t i = 0; i < paths.size(); ++i)
|
||||
result->Set(i, FilePathToV8Value(paths[i]));
|
||||
|
||||
return scope.Close(result);
|
||||
}
|
||||
}
|
||||
|
||||
v8::Handle<v8::Value> ShowSaveDialog(const v8::Arguments &args) {
|
||||
v8::HandleScope scope;
|
||||
|
||||
if (!args[0]->IsObject() || // window
|
||||
!args[1]->IsString() || // title
|
||||
!args[2]->IsString()) // default_path
|
||||
std::string title;
|
||||
base::FilePath default_path;
|
||||
if (!FromV8Arguments(args, &title, &default_path))
|
||||
return node::ThrowTypeError("Bad argument");
|
||||
|
||||
Window* window = Window::Unwrap<Window>(args[0]->ToObject());
|
||||
if (!window || !window->window())
|
||||
return node::ThrowError("Invalid window");
|
||||
NativeWindow* native_window = FromV8Value(args[2]);
|
||||
v8::Persistent<v8::Function> callback = FromV8Value(args[3]);
|
||||
|
||||
std::string title(*v8::String::Utf8Value(args[1]));
|
||||
base::FilePath default_path(V8ValueToFilePath(args[2]));
|
||||
if (callback.IsEmpty()) {
|
||||
base::FilePath path;
|
||||
if (!file_dialog::ShowSaveDialog(native_window,
|
||||
title,
|
||||
default_path,
|
||||
&path))
|
||||
return v8::Undefined();
|
||||
|
||||
base::FilePath path;
|
||||
if (!file_dialog::ShowSaveDialog(window->window(),
|
||||
title,
|
||||
default_path,
|
||||
&path))
|
||||
return scope.Close(ToV8Value(path));
|
||||
} else {
|
||||
file_dialog::ShowSaveDialog(
|
||||
native_window,
|
||||
title,
|
||||
default_path,
|
||||
base::Bind(&CallV8Function2<const base::FilePath&>, callback));
|
||||
return v8::Undefined();
|
||||
|
||||
return scope.Close(FilePathToV8Value(path));
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
|
|
@ -4,6 +4,10 @@
|
|||
|
||||
#include "browser/api/atom_api_event.h"
|
||||
|
||||
#include "browser/native_window.h"
|
||||
#include "common/api/api_messages.h"
|
||||
#include "common/v8_conversions.h"
|
||||
|
||||
using node::node_isolate;
|
||||
|
||||
namespace atom {
|
||||
|
@ -13,10 +17,14 @@ namespace api {
|
|||
v8::Persistent<v8::FunctionTemplate> Event::constructor_template_;
|
||||
|
||||
Event::Event()
|
||||
: prevent_default_(false) {
|
||||
: sender_(NULL),
|
||||
message_(NULL),
|
||||
prevent_default_(false) {
|
||||
}
|
||||
|
||||
Event::~Event() {
|
||||
if (sender_)
|
||||
sender_->RemoveObserver(this);
|
||||
}
|
||||
|
||||
// static
|
||||
|
@ -31,6 +39,7 @@ v8::Handle<v8::Object> Event::CreateV8Object() {
|
|||
constructor_template_->SetClassName(v8::String::NewSymbol("Event"));
|
||||
|
||||
NODE_SET_PROTOTYPE_METHOD(t, "preventDefault", PreventDefault);
|
||||
NODE_SET_PROTOTYPE_METHOD(t, "sendReply", SendReply);
|
||||
}
|
||||
|
||||
v8::Handle<v8::Object> v8_event =
|
||||
|
@ -39,14 +48,30 @@ v8::Handle<v8::Object> Event::CreateV8Object() {
|
|||
return scope.Close(v8_event);
|
||||
}
|
||||
|
||||
v8::Handle<v8::Value> Event::New(const v8::Arguments &args) {
|
||||
void Event::SetSenderAndMessage(NativeWindow* sender, IPC::Message* message) {
|
||||
DCHECK(!sender_);
|
||||
DCHECK(!message_);
|
||||
sender_ = sender;
|
||||
message_ = message;
|
||||
|
||||
sender_->AddObserver(this);
|
||||
}
|
||||
|
||||
void Event::OnWindowClosed() {
|
||||
sender_ = NULL;
|
||||
message_ = NULL;
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> Event::New(const v8::Arguments& args) {
|
||||
Event* event = new Event;
|
||||
event->Wrap(args.This());
|
||||
|
||||
return args.This();
|
||||
}
|
||||
|
||||
v8::Handle<v8::Value> Event::PreventDefault(const v8::Arguments &args) {
|
||||
// static
|
||||
v8::Handle<v8::Value> Event::PreventDefault(const v8::Arguments& args) {
|
||||
Event* event = Unwrap<Event>(args.This());
|
||||
if (event == NULL)
|
||||
return node::ThrowError("Event is already destroyed");
|
||||
|
@ -56,6 +81,24 @@ v8::Handle<v8::Value> Event::PreventDefault(const v8::Arguments &args) {
|
|||
return v8::Undefined();
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> Event::SendReply(const v8::Arguments& args) {
|
||||
Event* event = Unwrap<Event>(args.This());
|
||||
if (event == NULL)
|
||||
return node::ThrowError("Event is already destroyed");
|
||||
|
||||
if (event->message_ == NULL)
|
||||
return node::ThrowError("Can only send reply to synchronous events once");
|
||||
|
||||
string16 json = FromV8Value(args[0]);
|
||||
|
||||
AtomViewHostMsg_Message_Sync::WriteReplyParams(event->message_, json);
|
||||
event->sender_->Send(event->message_);
|
||||
|
||||
event->message_ = NULL;
|
||||
return v8::Undefined();
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
|
|
|
@ -6,19 +6,32 @@
|
|||
#define ATOM_BROWSER_ATOM_API_EVENT_H_
|
||||
|
||||
#include "base/basictypes.h"
|
||||
#include "base/compiler_specific.h"
|
||||
#include "base/string16.h"
|
||||
#include "browser/native_window_observer.h"
|
||||
#include "vendor/node/src/node_object_wrap.h"
|
||||
|
||||
namespace IPC {
|
||||
class Message;
|
||||
}
|
||||
|
||||
namespace atom {
|
||||
|
||||
class NativeWindow;
|
||||
|
||||
namespace api {
|
||||
|
||||
class Event : public node::ObjectWrap {
|
||||
class Event : public node::ObjectWrap,
|
||||
public NativeWindowObserver {
|
||||
public:
|
||||
virtual ~Event();
|
||||
|
||||
// Create a V8 Event object.
|
||||
static v8::Handle<v8::Object> CreateV8Object();
|
||||
|
||||
// Pass the sender and message to be replied.
|
||||
void SetSenderAndMessage(NativeWindow* sender, IPC::Message* message);
|
||||
|
||||
// Accessor to return handle_, this follows Google C++ Style.
|
||||
v8::Persistent<v8::Object>& handle() { return handle_; }
|
||||
|
||||
|
@ -28,12 +41,21 @@ class Event : public node::ObjectWrap {
|
|||
protected:
|
||||
Event();
|
||||
|
||||
// NativeWindowObserver implementations:
|
||||
virtual void OnWindowClosed() OVERRIDE;
|
||||
|
||||
private:
|
||||
static v8::Handle<v8::Value> New(const v8::Arguments &args);
|
||||
static v8::Handle<v8::Value> PreventDefault(const v8::Arguments &args);
|
||||
static v8::Handle<v8::Value> New(const v8::Arguments& args);
|
||||
|
||||
static v8::Handle<v8::Value> PreventDefault(const v8::Arguments& args);
|
||||
static v8::Handle<v8::Value> SendReply(const v8::Arguments& args);
|
||||
|
||||
static v8::Persistent<v8::FunctionTemplate> constructor_template_;
|
||||
|
||||
// Replyer for the synchronous messages.
|
||||
NativeWindow* sender_;
|
||||
IPC::Message* message_;
|
||||
|
||||
bool prevent_default_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(Event);
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
|
||||
#include "browser/api/atom_api_menu.h"
|
||||
|
||||
#include "browser/api/atom_api_window.h"
|
||||
#include "browser/ui/accelerator_util.h"
|
||||
#include "common/v8_conversions.h"
|
||||
|
||||
#define UNWRAP_MEMNU_AND_CHECK \
|
||||
Menu* self = ObjectWrap::Unwrap<Menu>(args.This()); \
|
||||
|
@ -18,17 +18,6 @@ namespace api {
|
|||
|
||||
namespace {
|
||||
|
||||
// Converts a V8 value to a string16.
|
||||
string16 V8ValueToUTF16(v8::Handle<v8::Value> value) {
|
||||
v8::String::Value s(value);
|
||||
return string16(reinterpret_cast<const char16*>(*s), s.length());
|
||||
}
|
||||
|
||||
// Converts string16 to V8 String.
|
||||
v8::Handle<v8::Value> UTF16ToV8Value(const string16& s) {
|
||||
return v8::String::New(reinterpret_cast<const uint16_t*>(s.data()), s.size());
|
||||
}
|
||||
|
||||
// Call method of delegate object.
|
||||
v8::Handle<v8::Value> CallDelegate(v8::Handle<v8::Value> default_value,
|
||||
v8::Handle<v8::Object> menu,
|
||||
|
@ -93,7 +82,7 @@ bool Menu::GetAcceleratorForCommandId(int command_id,
|
|||
"getAcceleratorForCommandId",
|
||||
command_id);
|
||||
if (shortcut->IsString()) {
|
||||
std::string shortcut_str(*v8::String::Utf8Value(shortcut));
|
||||
std::string shortcut_str = FromV8Value(shortcut);
|
||||
return accelerator_util::StringToAccelerator(shortcut_str, accelerator);
|
||||
}
|
||||
|
||||
|
@ -110,18 +99,18 @@ bool Menu::IsItemForCommandIdDynamic(int command_id) const {
|
|||
|
||||
string16 Menu::GetLabelForCommandId(int command_id) const {
|
||||
v8::HandleScope scope;
|
||||
return V8ValueToUTF16(CallDelegate(v8::False(),
|
||||
handle(),
|
||||
"getLabelForCommandId",
|
||||
command_id));
|
||||
return FromV8Value(CallDelegate(v8::False(),
|
||||
handle(),
|
||||
"getLabelForCommandId",
|
||||
command_id));
|
||||
}
|
||||
|
||||
string16 Menu::GetSublabelForCommandId(int command_id) const {
|
||||
v8::HandleScope scope;
|
||||
return V8ValueToUTF16(CallDelegate(v8::False(),
|
||||
handle(),
|
||||
"getSubLabelForCommandId",
|
||||
command_id));
|
||||
return FromV8Value(CallDelegate(v8::False(),
|
||||
handle(),
|
||||
"getSubLabelForCommandId",
|
||||
command_id));
|
||||
}
|
||||
|
||||
void Menu::ExecuteCommand(int command_id, int event_flags) {
|
||||
|
@ -145,16 +134,15 @@ v8::Handle<v8::Value> Menu::New(const v8::Arguments &args) {
|
|||
v8::Handle<v8::Value> Menu::InsertItem(const v8::Arguments &args) {
|
||||
UNWRAP_MEMNU_AND_CHECK;
|
||||
|
||||
if (!args[0]->IsNumber() || !args[1]->IsNumber() || !args[2]->IsString())
|
||||
int index, command_id;
|
||||
string16 label;
|
||||
if (!FromV8Arguments(args, &index, &command_id, &label))
|
||||
return node::ThrowTypeError("Bad argument");
|
||||
|
||||
int index = args[0]->IntegerValue();
|
||||
|
||||
if (index < 0)
|
||||
self->model_->AddItem(args[1]->IntegerValue(), V8ValueToUTF16(args[2]));
|
||||
self->model_->AddItem(command_id, label);
|
||||
else
|
||||
self->model_->InsertItemAt(
|
||||
index, args[1]->IntegerValue(), V8ValueToUTF16(args[2]));
|
||||
self->model_->InsertItemAt(index, command_id, label);
|
||||
|
||||
return v8::Undefined();
|
||||
}
|
||||
|
@ -163,16 +151,15 @@ v8::Handle<v8::Value> Menu::InsertItem(const v8::Arguments &args) {
|
|||
v8::Handle<v8::Value> Menu::InsertCheckItem(const v8::Arguments &args) {
|
||||
UNWRAP_MEMNU_AND_CHECK;
|
||||
|
||||
if (!args[0]->IsNumber() || !args[1]->IsNumber() || !args[2]->IsString())
|
||||
int index, command_id;
|
||||
string16 label;
|
||||
if (!FromV8Arguments(args, &index, &command_id, &label))
|
||||
return node::ThrowTypeError("Bad argument");
|
||||
|
||||
int index = args[0]->IntegerValue();
|
||||
int command_id = args[1]->IntegerValue();
|
||||
|
||||
if (index < 0)
|
||||
self->model_->AddCheckItem(command_id, V8ValueToUTF16(args[2]));
|
||||
self->model_->AddCheckItem(command_id, label);
|
||||
else
|
||||
self->model_->InsertCheckItemAt(index, command_id, V8ValueToUTF16(args[2]));
|
||||
self->model_->InsertCheckItemAt(index, command_id, label);
|
||||
|
||||
return v8::Undefined();
|
||||
}
|
||||
|
@ -181,21 +168,15 @@ v8::Handle<v8::Value> Menu::InsertCheckItem(const v8::Arguments &args) {
|
|||
v8::Handle<v8::Value> Menu::InsertRadioItem(const v8::Arguments &args) {
|
||||
UNWRAP_MEMNU_AND_CHECK;
|
||||
|
||||
if (!args[0]->IsNumber() ||
|
||||
!args[1]->IsNumber() ||
|
||||
!args[2]->IsString() ||
|
||||
!args[3]->IsNumber())
|
||||
int index, command_id, group_id;
|
||||
string16 label;
|
||||
if (!FromV8Arguments(args, &index, &command_id, &label, &group_id))
|
||||
return node::ThrowTypeError("Bad argument");
|
||||
|
||||
int index = args[0]->IntegerValue();
|
||||
int command_id = args[1]->IntegerValue();
|
||||
int group_id = args[3]->IntegerValue();
|
||||
|
||||
if (index < 0)
|
||||
self->model_->AddRadioItem(command_id, V8ValueToUTF16(args[2]), group_id);
|
||||
self->model_->AddRadioItem(command_id, label, group_id);
|
||||
else
|
||||
self->model_->InsertRadioItemAt(
|
||||
index, command_id, V8ValueToUTF16(args[2]), group_id);
|
||||
self->model_->InsertRadioItemAt(index, command_id, label, group_id);
|
||||
|
||||
return v8::Undefined();
|
||||
}
|
||||
|
@ -204,11 +185,10 @@ v8::Handle<v8::Value> Menu::InsertRadioItem(const v8::Arguments &args) {
|
|||
v8::Handle<v8::Value> Menu::InsertSeparator(const v8::Arguments &args) {
|
||||
UNWRAP_MEMNU_AND_CHECK;
|
||||
|
||||
if (!args[0]->IsNumber())
|
||||
int index;
|
||||
if (!FromV8Arguments(args, &index))
|
||||
return node::ThrowTypeError("Bad argument");
|
||||
|
||||
int index = args[0]->IntegerValue();
|
||||
|
||||
if (index < 0)
|
||||
self->model_->AddSeparator(ui::NORMAL_SEPARATOR);
|
||||
else
|
||||
|
@ -221,25 +201,20 @@ v8::Handle<v8::Value> Menu::InsertSeparator(const v8::Arguments &args) {
|
|||
v8::Handle<v8::Value> Menu::InsertSubMenu(const v8::Arguments &args) {
|
||||
UNWRAP_MEMNU_AND_CHECK;
|
||||
|
||||
if (!args[0]->IsNumber() ||
|
||||
!args[1]->IsNumber() ||
|
||||
!args[2]->IsString() ||
|
||||
!args[3]->IsObject())
|
||||
int index, command_id;
|
||||
string16 label;
|
||||
if (!FromV8Arguments(args, &index, &command_id, &label))
|
||||
return node::ThrowTypeError("Bad argument");
|
||||
|
||||
Menu* submenu = ObjectWrap::Unwrap<Menu>(args[3]->ToObject());
|
||||
if (!submenu)
|
||||
return node::ThrowTypeError("The submenu is already destroyed");
|
||||
|
||||
int index = args[0]->IntegerValue();
|
||||
int command_id = args[1]->IntegerValue();
|
||||
|
||||
if (index < 0)
|
||||
self->model_->AddSubMenu(
|
||||
command_id, V8ValueToUTF16(args[2]), submenu->model_.get());
|
||||
self->model_->AddSubMenu(command_id, label, submenu->model_.get());
|
||||
else
|
||||
self->model_->InsertSubMenuAt(
|
||||
index, command_id, V8ValueToUTF16(args[2]), submenu->model_.get());
|
||||
index, command_id, label, submenu->model_.get());
|
||||
|
||||
return v8::Undefined();
|
||||
}
|
||||
|
@ -248,7 +223,9 @@ v8::Handle<v8::Value> Menu::InsertSubMenu(const v8::Arguments &args) {
|
|||
v8::Handle<v8::Value> Menu::SetIcon(const v8::Arguments &args) {
|
||||
UNWRAP_MEMNU_AND_CHECK;
|
||||
|
||||
if (!args[0]->IsNumber() || !args[1]->IsString())
|
||||
int index;
|
||||
base::FilePath path;
|
||||
if (!FromV8Arguments(args, &index, &path))
|
||||
return node::ThrowTypeError("Bad argument");
|
||||
|
||||
// FIXME use webkit_glue's image decoder here.
|
||||
|
@ -260,10 +237,12 @@ v8::Handle<v8::Value> Menu::SetIcon(const v8::Arguments &args) {
|
|||
v8::Handle<v8::Value> Menu::SetSublabel(const v8::Arguments &args) {
|
||||
UNWRAP_MEMNU_AND_CHECK;
|
||||
|
||||
if (!args[0]->IsNumber() || !args[1]->IsString())
|
||||
int index;
|
||||
string16 label;
|
||||
if (!FromV8Arguments(args, &index, &label))
|
||||
return node::ThrowTypeError("Bad argument");
|
||||
|
||||
self->model_->SetSublabel(args[0]->IntegerValue(), V8ValueToUTF16(args[1]));
|
||||
self->model_->SetSublabel(index, label);
|
||||
|
||||
return v8::Undefined();
|
||||
}
|
||||
|
@ -301,14 +280,14 @@ v8::Handle<v8::Value> Menu::GetCommandIdAt(const v8::Arguments &args) {
|
|||
v8::Handle<v8::Value> Menu::GetLabelAt(const v8::Arguments &args) {
|
||||
UNWRAP_MEMNU_AND_CHECK;
|
||||
int index = args[0]->IntegerValue();
|
||||
return UTF16ToV8Value(self->model_->GetLabelAt(index));
|
||||
return ToV8Value(self->model_->GetLabelAt(index));
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> Menu::GetSublabelAt(const v8::Arguments &args) {
|
||||
UNWRAP_MEMNU_AND_CHECK;
|
||||
int index = args[0]->IntegerValue();
|
||||
return UTF16ToV8Value(self->model_->GetSublabelAt(index));
|
||||
return ToV8Value(self->model_->GetSublabelAt(index));
|
||||
}
|
||||
|
||||
// static
|
||||
|
@ -334,11 +313,11 @@ v8::Handle<v8::Value> Menu::IsVisibleAt(const v8::Arguments &args) {
|
|||
v8::Handle<v8::Value> Menu::Popup(const v8::Arguments &args) {
|
||||
UNWRAP_MEMNU_AND_CHECK;
|
||||
|
||||
Window* window = Window::Unwrap<Window>(args[0]->ToObject());
|
||||
if (!window)
|
||||
return node::ThrowTypeError("Invalid window");
|
||||
atom::NativeWindow* window;
|
||||
if (!FromV8Arguments(args, &window))
|
||||
return node::ThrowTypeError("Bad argument");
|
||||
|
||||
self->Popup(window->window());
|
||||
self->Popup(window);
|
||||
return v8::Undefined();
|
||||
}
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include "base/mac/scoped_sending_event.h"
|
||||
#include "base/strings/sys_string_conversions.h"
|
||||
#include "browser/native_window.h"
|
||||
#include "common/v8_conversions.h"
|
||||
#include "content/public/browser/web_contents.h"
|
||||
#include "content/public/browser/web_contents_view.h"
|
||||
|
||||
|
@ -95,10 +96,10 @@ v8::Handle<v8::Value> Menu::SendActionToFirstResponder(
|
|||
const v8::Arguments &args) {
|
||||
v8::HandleScope scope;
|
||||
|
||||
if (!args[0]->IsString())
|
||||
std::string action;
|
||||
if (!FromV8Arguments(args, &action))
|
||||
return node::ThrowTypeError("Bad argument");
|
||||
|
||||
std::string action(*v8::String::Utf8Value(args[0]));
|
||||
MenuMac::SendActionToFirstResponder(action);
|
||||
|
||||
return v8::Undefined();
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include "browser/net/adapter_request_job.h"
|
||||
#include "browser/net/atom_url_request_context_getter.h"
|
||||
#include "browser/net/atom_url_request_job_factory.h"
|
||||
#include "common/v8_conversions.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "net/url_request/url_request_context.h"
|
||||
#include "vendor/node/src/node.h"
|
||||
|
@ -36,9 +37,9 @@ static const char* kEarlyUseProtocolError = "This method can only be used"
|
|||
void EmitEventInUI(const std::string& event, const std::string& parameter) {
|
||||
v8::HandleScope scope;
|
||||
|
||||
v8::Local<v8::Value> argv[] = {
|
||||
v8::String::New(event.data(), event.size()),
|
||||
v8::String::New(parameter.data(), parameter.size()),
|
||||
v8::Handle<v8::Value> argv[] = {
|
||||
ToV8Value(event),
|
||||
ToV8Value(parameter),
|
||||
};
|
||||
node::MakeCallback(g_protocol_object, "emit", arraysize(argv), argv);
|
||||
}
|
||||
|
@ -83,7 +84,7 @@ class CustomProtocolRequestJob : public AdapterRequestJob {
|
|||
|
||||
// Determine the type of the job we are going to create.
|
||||
if (result->IsString()) {
|
||||
std::string data = *v8::String::Utf8Value(result);
|
||||
std::string data = FromV8Value(result);
|
||||
content::BrowserThread::PostTask(
|
||||
content::BrowserThread::IO,
|
||||
FROM_HERE,
|
||||
|
@ -95,14 +96,12 @@ class CustomProtocolRequestJob : public AdapterRequestJob {
|
|||
return;
|
||||
} else if (result->IsObject()) {
|
||||
v8::Handle<v8::Object> obj = result->ToObject();
|
||||
std::string name = *v8::String::Utf8Value(obj->GetConstructorName());
|
||||
std::string name = FromV8Value(obj->GetConstructorName());
|
||||
if (name == "RequestStringJob") {
|
||||
std::string mime_type = *v8::String::Utf8Value(obj->Get(
|
||||
std::string mime_type = FromV8Value(obj->Get(
|
||||
v8::String::New("mimeType")));
|
||||
std::string charset = *v8::String::Utf8Value(obj->Get(
|
||||
v8::String::New("charset")));
|
||||
std::string data = *v8::String::Utf8Value(obj->Get(
|
||||
v8::String::New("data")));
|
||||
std::string charset = FromV8Value(obj->Get(v8::String::New("charset")));
|
||||
std::string data = FromV8Value(obj->Get(v8::String::New("data")));
|
||||
|
||||
content::BrowserThread::PostTask(
|
||||
content::BrowserThread::IO,
|
||||
|
@ -114,8 +113,7 @@ class CustomProtocolRequestJob : public AdapterRequestJob {
|
|||
data));
|
||||
return;
|
||||
} else if (name == "RequestFileJob") {
|
||||
base::FilePath path = base::FilePath::FromUTF8Unsafe(
|
||||
*v8::String::Utf8Value(obj->Get(v8::String::New("path"))));
|
||||
base::FilePath path = FromV8Value(obj->Get(v8::String::New("path")));
|
||||
|
||||
content::BrowserThread::PostTask(
|
||||
content::BrowserThread::IO,
|
||||
|
@ -183,7 +181,11 @@ class CustomProtocolHandler : public ProtocolHandler {
|
|||
|
||||
// static
|
||||
v8::Handle<v8::Value> Protocol::RegisterProtocol(const v8::Arguments& args) {
|
||||
std::string scheme(*v8::String::Utf8Value(args[0]));
|
||||
std::string scheme;
|
||||
v8::Persistent<v8::Function> callback;
|
||||
if (!FromV8Arguments(args, &scheme, &callback))
|
||||
return node::ThrowTypeError("Bad argument");
|
||||
|
||||
if (g_handlers.find(scheme) != g_handlers.end() ||
|
||||
net::URLRequest::IsHandledProtocol(scheme))
|
||||
return node::ThrowError("The scheme is already registered");
|
||||
|
@ -192,10 +194,7 @@ v8::Handle<v8::Value> Protocol::RegisterProtocol(const v8::Arguments& args) {
|
|||
return node::ThrowError(kEarlyUseProtocolError);
|
||||
|
||||
// Store the handler in a map.
|
||||
if (!args[1]->IsFunction())
|
||||
return node::ThrowError("Handler must be a function");
|
||||
g_handlers[scheme] = v8::Persistent<v8::Function>::New(
|
||||
node::node_isolate, v8::Handle<v8::Function>::Cast(args[1]));
|
||||
g_handlers[scheme] = callback;
|
||||
|
||||
content::BrowserThread::PostTask(content::BrowserThread::IO,
|
||||
FROM_HERE,
|
||||
|
@ -206,7 +205,9 @@ v8::Handle<v8::Value> Protocol::RegisterProtocol(const v8::Arguments& args) {
|
|||
|
||||
// static
|
||||
v8::Handle<v8::Value> Protocol::UnregisterProtocol(const v8::Arguments& args) {
|
||||
std::string scheme(*v8::String::Utf8Value(args[0]));
|
||||
std::string scheme;
|
||||
if (!FromV8Arguments(args, &scheme))
|
||||
return node::ThrowTypeError("Bad argument");
|
||||
|
||||
if (AtomBrowserContext::Get()->url_request_context_getter() == NULL)
|
||||
return node::ThrowError(kEarlyUseProtocolError);
|
||||
|
@ -226,13 +227,16 @@ v8::Handle<v8::Value> Protocol::UnregisterProtocol(const v8::Arguments& args) {
|
|||
|
||||
// static
|
||||
v8::Handle<v8::Value> Protocol::IsHandledProtocol(const v8::Arguments& args) {
|
||||
return v8::Boolean::New(net::URLRequest::IsHandledProtocol(
|
||||
*v8::String::Utf8Value(args[0])));
|
||||
return ToV8Value(net::URLRequest::IsHandledProtocol(FromV8Value(args[0])));
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> Protocol::InterceptProtocol(const v8::Arguments& args) {
|
||||
std::string scheme(*v8::String::Utf8Value(args[0]));
|
||||
std::string scheme;
|
||||
v8::Persistent<v8::Function> callback;
|
||||
if (!FromV8Arguments(args, &scheme, &callback))
|
||||
return node::ThrowTypeError("Bad argument");
|
||||
|
||||
if (!GetRequestJobFactory()->HasProtocolHandler(scheme))
|
||||
return node::ThrowError("Cannot intercept procotol");
|
||||
|
||||
|
@ -243,10 +247,7 @@ v8::Handle<v8::Value> Protocol::InterceptProtocol(const v8::Arguments& args) {
|
|||
return node::ThrowError(kEarlyUseProtocolError);
|
||||
|
||||
// Store the handler in a map.
|
||||
if (!args[1]->IsFunction())
|
||||
return node::ThrowError("Handler must be a function");
|
||||
g_handlers[scheme] = v8::Persistent<v8::Function>::New(
|
||||
node::node_isolate, v8::Handle<v8::Function>::Cast(args[1]));
|
||||
g_handlers[scheme] = callback;
|
||||
|
||||
content::BrowserThread::PostTask(content::BrowserThread::IO,
|
||||
FROM_HERE,
|
||||
|
@ -256,7 +257,9 @@ v8::Handle<v8::Value> Protocol::InterceptProtocol(const v8::Arguments& args) {
|
|||
|
||||
// static
|
||||
v8::Handle<v8::Value> Protocol::UninterceptProtocol(const v8::Arguments& args) {
|
||||
std::string scheme(*v8::String::Utf8Value(args[0]));
|
||||
std::string scheme;
|
||||
if (!FromV8Arguments(args, &scheme))
|
||||
return node::ThrowTypeError("Bad argument");
|
||||
|
||||
if (AtomBrowserContext::Get()->url_request_context_getter() == NULL)
|
||||
return node::ThrowError(kEarlyUseProtocolError);
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
#include "base/values.h"
|
||||
#include "browser/native_window.h"
|
||||
#include "common/v8_conversions.h"
|
||||
#include "common/v8_value_converter_impl.h"
|
||||
#include "content/public/browser/navigation_entry.h"
|
||||
#include "content/public/browser/web_contents.h"
|
||||
|
@ -27,15 +28,6 @@ namespace atom {
|
|||
|
||||
namespace api {
|
||||
|
||||
namespace {
|
||||
|
||||
// Converts string16 to V8 String.
|
||||
v8::Handle<v8::String> UTF16ToV8String(const string16& s) {
|
||||
return v8::String::New(reinterpret_cast<const uint16_t*>(s.data()), s.size());
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
Window::Window(v8::Handle<v8::Object> wrapper, base::DictionaryValue* options)
|
||||
: EventEmitter(wrapper),
|
||||
window_(NativeWindow::Create(options)) {
|
||||
|
@ -141,7 +133,7 @@ v8::Handle<v8::Value> Window::Focus(const v8::Arguments &args) {
|
|||
// static
|
||||
v8::Handle<v8::Value> Window::IsFocused(const v8::Arguments &args) {
|
||||
UNWRAP_WINDOW_AND_CHECK;
|
||||
return v8::Boolean::New(self->window_->IsFocused());
|
||||
return ToV8Value(self->window_->IsFocused());
|
||||
}
|
||||
|
||||
// static
|
||||
|
@ -202,10 +194,11 @@ v8::Handle<v8::Value> Window::Restore(const v8::Arguments &args) {
|
|||
v8::Handle<v8::Value> Window::SetFullscreen(const v8::Arguments &args) {
|
||||
UNWRAP_WINDOW_AND_CHECK;
|
||||
|
||||
if (args.Length() < 1 || !args[0]->IsBoolean())
|
||||
bool fs;
|
||||
if (!FromV8Arguments(args, &fs))
|
||||
return node::ThrowTypeError("Bad argument");
|
||||
self->window_->SetFullscreen(args[0]->BooleanValue());
|
||||
|
||||
self->window_->SetFullscreen(fs);
|
||||
return v8::Undefined();
|
||||
}
|
||||
|
||||
|
@ -213,18 +206,18 @@ v8::Handle<v8::Value> Window::SetFullscreen(const v8::Arguments &args) {
|
|||
v8::Handle<v8::Value> Window::IsFullscreen(const v8::Arguments &args) {
|
||||
UNWRAP_WINDOW_AND_CHECK;
|
||||
|
||||
return v8::Boolean::New(self->window_->IsFullscreen());
|
||||
return ToV8Value(self->window_->IsFullscreen());
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> Window::SetSize(const v8::Arguments &args) {
|
||||
UNWRAP_WINDOW_AND_CHECK;
|
||||
|
||||
if (args.Length() < 2)
|
||||
int width, height;
|
||||
if (!FromV8Arguments(args, &width, &height))
|
||||
return node::ThrowTypeError("Bad argument");
|
||||
self->window_->SetSize(
|
||||
gfx::Size(args[0]->IntegerValue(), args[1]->IntegerValue()));
|
||||
|
||||
self->window_->SetSize(gfx::Size(width, height));
|
||||
return v8::Undefined();
|
||||
}
|
||||
|
||||
|
@ -234,8 +227,8 @@ v8::Handle<v8::Value> Window::GetSize(const v8::Arguments &args) {
|
|||
|
||||
gfx::Size size = self->window_->GetSize();
|
||||
v8::Handle<v8::Array> ret = v8::Array::New(2);
|
||||
ret->Set(0, v8::Integer::New(size.width()));
|
||||
ret->Set(1, v8::Integer::New(size.height()));
|
||||
ret->Set(0, ToV8Value(size.width()));
|
||||
ret->Set(1, ToV8Value(size.height()));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -244,11 +237,11 @@ v8::Handle<v8::Value> Window::GetSize(const v8::Arguments &args) {
|
|||
v8::Handle<v8::Value> Window::SetMinimumSize(const v8::Arguments &args) {
|
||||
UNWRAP_WINDOW_AND_CHECK;
|
||||
|
||||
if (args.Length() < 2)
|
||||
int width, height;
|
||||
if (!FromV8Arguments(args, &width, &height))
|
||||
return node::ThrowTypeError("Bad argument");
|
||||
self->window_->SetMinimumSize(
|
||||
gfx::Size(args[0]->IntegerValue(), args[1]->IntegerValue()));
|
||||
|
||||
self->window_->SetMinimumSize(gfx::Size(width, height));
|
||||
return v8::Undefined();
|
||||
}
|
||||
|
||||
|
@ -258,8 +251,8 @@ v8::Handle<v8::Value> Window::GetMinimumSize(const v8::Arguments &args) {
|
|||
|
||||
gfx::Size size = self->window_->GetMinimumSize();
|
||||
v8::Handle<v8::Array> ret = v8::Array::New(2);
|
||||
ret->Set(0, v8::Integer::New(size.width()));
|
||||
ret->Set(1, v8::Integer::New(size.height()));
|
||||
ret->Set(0, ToV8Value(size.width()));
|
||||
ret->Set(1, ToV8Value(size.height()));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -268,11 +261,12 @@ v8::Handle<v8::Value> Window::GetMinimumSize(const v8::Arguments &args) {
|
|||
v8::Handle<v8::Value> Window::SetMaximumSize(const v8::Arguments &args) {
|
||||
UNWRAP_WINDOW_AND_CHECK;
|
||||
|
||||
if (args.Length() < 2)
|
||||
return node::ThrowTypeError("Bad argument");
|
||||
self->window_->SetMaximumSize(
|
||||
gfx::Size(args[0]->IntegerValue(), args[1]->IntegerValue()));
|
||||
|
||||
int width, height;
|
||||
if (!FromV8Arguments(args, &width, &height))
|
||||
return node::ThrowTypeError("Bad argument");
|
||||
|
||||
self->window_->SetMaximumSize(gfx::Size(width, height));
|
||||
return v8::Undefined();
|
||||
}
|
||||
|
||||
|
@ -282,8 +276,8 @@ v8::Handle<v8::Value> Window::GetMaximumSize(const v8::Arguments &args) {
|
|||
|
||||
gfx::Size size = self->window_->GetMaximumSize();
|
||||
v8::Handle<v8::Array> ret = v8::Array::New(2);
|
||||
ret->Set(0, v8::Integer::New(size.width()));
|
||||
ret->Set(1, v8::Integer::New(size.height()));
|
||||
ret->Set(0, ToV8Value(size.width()));
|
||||
ret->Set(1, ToV8Value(size.height()));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -292,10 +286,11 @@ v8::Handle<v8::Value> Window::GetMaximumSize(const v8::Arguments &args) {
|
|||
v8::Handle<v8::Value> Window::SetResizable(const v8::Arguments &args) {
|
||||
UNWRAP_WINDOW_AND_CHECK;
|
||||
|
||||
if (args.Length() < 1 || !args[0]->IsBoolean())
|
||||
bool resizable;
|
||||
if (!FromV8Arguments(args, &resizable))
|
||||
return node::ThrowTypeError("Bad argument");
|
||||
self->window_->SetResizable(args[0]->BooleanValue());
|
||||
|
||||
self->window_->SetResizable(resizable);
|
||||
return v8::Undefined();
|
||||
}
|
||||
|
||||
|
@ -303,17 +298,18 @@ v8::Handle<v8::Value> Window::SetResizable(const v8::Arguments &args) {
|
|||
v8::Handle<v8::Value> Window::IsResizable(const v8::Arguments &args) {
|
||||
UNWRAP_WINDOW_AND_CHECK;
|
||||
|
||||
return v8::Boolean::New(self->window_->IsResizable());
|
||||
return ToV8Value(self->window_->IsResizable());
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> Window::SetAlwaysOnTop(const v8::Arguments &args) {
|
||||
UNWRAP_WINDOW_AND_CHECK;
|
||||
|
||||
if (args.Length() < 1 || !args[0]->IsBoolean())
|
||||
bool top;
|
||||
if (!FromV8Arguments(args, &top))
|
||||
return node::ThrowTypeError("Bad argument");
|
||||
self->window_->SetAlwaysOnTop(args[0]->BooleanValue());
|
||||
|
||||
self->window_->SetAlwaysOnTop(top);
|
||||
return v8::Undefined();
|
||||
}
|
||||
|
||||
|
@ -321,7 +317,7 @@ v8::Handle<v8::Value> Window::SetAlwaysOnTop(const v8::Arguments &args) {
|
|||
v8::Handle<v8::Value> Window::IsAlwaysOnTop(const v8::Arguments &args) {
|
||||
UNWRAP_WINDOW_AND_CHECK;
|
||||
|
||||
return v8::Boolean::New(self->window_->IsAlwaysOnTop());
|
||||
return ToV8Value(self->window_->IsAlwaysOnTop());
|
||||
}
|
||||
|
||||
// static
|
||||
|
@ -337,11 +333,11 @@ v8::Handle<v8::Value> Window::Center(const v8::Arguments &args) {
|
|||
v8::Handle<v8::Value> Window::SetPosition(const v8::Arguments &args) {
|
||||
UNWRAP_WINDOW_AND_CHECK;
|
||||
|
||||
if (args.Length() < 2)
|
||||
int x, y;
|
||||
if (!FromV8Arguments(args, &x, &y))
|
||||
return node::ThrowTypeError("Bad argument");
|
||||
self->window_->SetPosition(
|
||||
gfx::Point(args[0]->IntegerValue(), args[1]->IntegerValue()));
|
||||
|
||||
self->window_->SetPosition(gfx::Point(x, y));
|
||||
return v8::Undefined();
|
||||
}
|
||||
|
||||
|
@ -351,8 +347,8 @@ v8::Handle<v8::Value> Window::GetPosition(const v8::Arguments &args) {
|
|||
|
||||
gfx::Point pos = self->window_->GetPosition();
|
||||
v8::Handle<v8::Array> ret = v8::Array::New(2);
|
||||
ret->Set(0, v8::Integer::New(pos.x()));
|
||||
ret->Set(1, v8::Integer::New(pos.y()));
|
||||
ret->Set(0, ToV8Value(pos.x()));
|
||||
ret->Set(1, ToV8Value(pos.y()));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -361,20 +357,18 @@ v8::Handle<v8::Value> Window::GetPosition(const v8::Arguments &args) {
|
|||
v8::Handle<v8::Value> Window::SetTitle(const v8::Arguments &args) {
|
||||
UNWRAP_WINDOW_AND_CHECK;
|
||||
|
||||
if (args.Length() < 1 || !args[0]->IsString())
|
||||
std::string title;
|
||||
if (!FromV8Arguments(args, &title))
|
||||
return node::ThrowTypeError("Bad argument");
|
||||
self->window_->SetTitle(*v8::String::Utf8Value(args[0]));
|
||||
|
||||
self->window_->SetTitle(title);
|
||||
return v8::Undefined();
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> Window::GetTitle(const v8::Arguments &args) {
|
||||
UNWRAP_WINDOW_AND_CHECK;
|
||||
|
||||
std::string title = self->window_->GetTitle();
|
||||
|
||||
return v8::String::New(title.c_str(), title.size());
|
||||
return ToV8Value(self->window_->GetTitle());
|
||||
}
|
||||
|
||||
// static
|
||||
|
@ -391,10 +385,11 @@ v8::Handle<v8::Value> Window::FlashFrame(const v8::Arguments &args) {
|
|||
v8::Handle<v8::Value> Window::SetKiosk(const v8::Arguments &args) {
|
||||
UNWRAP_WINDOW_AND_CHECK;
|
||||
|
||||
if (args.Length() < 1 || !args[0]->IsBoolean())
|
||||
bool kiosk;
|
||||
if (!FromV8Arguments(args, &kiosk))
|
||||
return node::ThrowTypeError("Bad argument");
|
||||
self->window_->SetKiosk(args[0]->BooleanValue());
|
||||
|
||||
self->window_->SetKiosk(kiosk);
|
||||
return v8::Undefined();
|
||||
}
|
||||
|
||||
|
@ -402,7 +397,7 @@ v8::Handle<v8::Value> Window::SetKiosk(const v8::Arguments &args) {
|
|||
v8::Handle<v8::Value> Window::IsKiosk(const v8::Arguments &args) {
|
||||
UNWRAP_WINDOW_AND_CHECK;
|
||||
|
||||
return v8::Boolean::New(self->window_->IsKiosk());
|
||||
return ToV8Value(self->window_->IsKiosk());
|
||||
}
|
||||
|
||||
// static
|
||||
|
@ -427,9 +422,11 @@ v8::Handle<v8::Value> Window::CloseDevTools(const v8::Arguments &args) {
|
|||
v8::Handle<v8::Value> Window::InspectElement(const v8::Arguments& args) {
|
||||
UNWRAP_WINDOW_AND_CHECK;
|
||||
|
||||
self->window_->InspectElement(args[0]->IntegerValue(),
|
||||
args[1]->IntegerValue());
|
||||
int x, y;
|
||||
if (!FromV8Arguments(args, &x, &y))
|
||||
return node::ThrowTypeError("Bad argument");
|
||||
|
||||
self->window_->InspectElement(x, y);
|
||||
return v8::Undefined();
|
||||
}
|
||||
|
||||
|
@ -454,7 +451,7 @@ v8::Handle<v8::Value> Window::BlurWebView(const v8::Arguments &args) {
|
|||
// static
|
||||
v8::Handle<v8::Value> Window::IsWebViewFocused(const v8::Arguments& args) {
|
||||
UNWRAP_WINDOW_AND_CHECK;
|
||||
return v8::Boolean::New(self->window_->IsWebViewFocused());
|
||||
return ToV8Value(self->window_->IsWebViewFocused());
|
||||
}
|
||||
|
||||
// static
|
||||
|
@ -471,24 +468,21 @@ v8::Handle<v8::Value> Window::RestartHangMonitorTimeout(
|
|||
v8::Handle<v8::Value> Window::GetPageTitle(const v8::Arguments &args) {
|
||||
UNWRAP_WINDOW_AND_CHECK;
|
||||
|
||||
string16 title = self->window_->GetWebContents()->GetTitle();
|
||||
|
||||
return UTF16ToV8String(title);
|
||||
return ToV8Value(self->window_->GetWebContents()->GetTitle());
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> Window::IsLoading(const v8::Arguments &args) {
|
||||
UNWRAP_WINDOW_AND_CHECK;
|
||||
|
||||
return v8::Boolean::New(self->window_->GetWebContents()->IsLoading());
|
||||
return ToV8Value(self->window_->GetWebContents()->IsLoading());
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> Window::IsWaitingForResponse(const v8::Arguments &args) {
|
||||
UNWRAP_WINDOW_AND_CHECK;
|
||||
|
||||
return v8::Boolean::New(
|
||||
self->window_->GetWebContents()->IsWaitingForResponse());
|
||||
return ToV8Value(self->window_->GetWebContents()->IsWaitingForResponse());
|
||||
}
|
||||
|
||||
// static
|
||||
|
@ -504,14 +498,14 @@ v8::Handle<v8::Value> Window::Stop(const v8::Arguments &args) {
|
|||
v8::Handle<v8::Value> Window::GetRoutingID(const v8::Arguments &args) {
|
||||
UNWRAP_WINDOW_AND_CHECK;
|
||||
|
||||
return v8::Integer::New(self->window_->GetWebContents()->GetRoutingID());
|
||||
return ToV8Value(self->window_->GetWebContents()->GetRoutingID());
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> Window::GetProcessID(const v8::Arguments &args) {
|
||||
UNWRAP_WINDOW_AND_CHECK;
|
||||
|
||||
return v8::Integer::New(
|
||||
return ToV8Value(
|
||||
self->window_->GetWebContents()->GetRenderProcessHost()->GetID());
|
||||
}
|
||||
|
||||
|
@ -519,19 +513,20 @@ v8::Handle<v8::Value> Window::GetProcessID(const v8::Arguments &args) {
|
|||
v8::Handle<v8::Value> Window::IsCrashed(const v8::Arguments &args) {
|
||||
UNWRAP_WINDOW_AND_CHECK;
|
||||
|
||||
return v8::Boolean::New(self->window_->GetWebContents()->IsCrashed());
|
||||
return ToV8Value(self->window_->GetWebContents()->IsCrashed());
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> Window::LoadURL(const v8::Arguments &args) {
|
||||
UNWRAP_WINDOW_AND_CHECK;
|
||||
|
||||
if (args.Length() < 1 || !args[0]->IsString())
|
||||
std::string url;
|
||||
if (!FromV8Arguments(args, &url))
|
||||
return node::ThrowTypeError("Bad argument");
|
||||
|
||||
NavigationController& controller =
|
||||
self->window_->GetWebContents()->GetController();
|
||||
controller.LoadURL(GURL(*v8::String::Utf8Value(args[0])),
|
||||
controller.LoadURL(GURL(url),
|
||||
content::Referrer(),
|
||||
content::PAGE_TRANSITION_AUTO_TOPLEVEL,
|
||||
std::string());
|
||||
|
@ -549,7 +544,7 @@ v8::Handle<v8::Value> Window::GetURL(const v8::Arguments &args) {
|
|||
if (controller.GetActiveEntry())
|
||||
url = controller.GetActiveEntry()->GetVirtualURL().spec();
|
||||
|
||||
return v8::String::New(url.c_str(), url.size());
|
||||
return ToV8Value(url);
|
||||
}
|
||||
|
||||
// static
|
||||
|
@ -559,7 +554,7 @@ v8::Handle<v8::Value> Window::CanGoBack(const v8::Arguments &args) {
|
|||
NavigationController& controller =
|
||||
self->window_->GetWebContents()->GetController();
|
||||
|
||||
return v8::Boolean::New(controller.CanGoBack());
|
||||
return ToV8Value(controller.CanGoBack());
|
||||
}
|
||||
|
||||
// static
|
||||
|
@ -569,21 +564,21 @@ v8::Handle<v8::Value> Window::CanGoForward(const v8::Arguments &args) {
|
|||
NavigationController& controller =
|
||||
self->window_->GetWebContents()->GetController();
|
||||
|
||||
return v8::Boolean::New(controller.CanGoForward());
|
||||
return ToV8Value(controller.CanGoForward());
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> Window::CanGoToOffset(const v8::Arguments &args) {
|
||||
UNWRAP_WINDOW_AND_CHECK;
|
||||
|
||||
if (args.Length() < 1)
|
||||
int offset;
|
||||
if (!FromV8Arguments(args, &offset))
|
||||
return node::ThrowTypeError("Bad argument");
|
||||
|
||||
NavigationController& controller =
|
||||
self->window_->GetWebContents()->GetController();
|
||||
int offset = args[0]->IntegerValue();
|
||||
|
||||
return v8::Boolean::New(controller.CanGoToOffset(offset));
|
||||
return ToV8Value(controller.CanGoToOffset(offset));
|
||||
}
|
||||
|
||||
// static
|
||||
|
@ -612,12 +607,13 @@ v8::Handle<v8::Value> Window::GoForward(const v8::Arguments &args) {
|
|||
v8::Handle<v8::Value> Window::GoToIndex(const v8::Arguments &args) {
|
||||
UNWRAP_WINDOW_AND_CHECK;
|
||||
|
||||
if (args.Length() < 1)
|
||||
int index;
|
||||
if (!FromV8Arguments(args, &index))
|
||||
return node::ThrowTypeError("Bad argument");
|
||||
|
||||
NavigationController& controller =
|
||||
self->window_->GetWebContents()->GetController();
|
||||
controller.GoToIndex(args[0]->IntegerValue());
|
||||
controller.GoToIndex(index);
|
||||
|
||||
return v8::Undefined();
|
||||
}
|
||||
|
@ -626,12 +622,13 @@ v8::Handle<v8::Value> Window::GoToIndex(const v8::Arguments &args) {
|
|||
v8::Handle<v8::Value> Window::GoToOffset(const v8::Arguments &args) {
|
||||
UNWRAP_WINDOW_AND_CHECK;
|
||||
|
||||
if (args.Length() < 1)
|
||||
int offset;
|
||||
if (!FromV8Arguments(args, &offset))
|
||||
return node::ThrowTypeError("Bad argument");
|
||||
|
||||
NavigationController& controller =
|
||||
self->window_->GetWebContents()->GetController();
|
||||
controller.GoToOffset(args[0]->IntegerValue());
|
||||
controller.GoToOffset(offset);
|
||||
|
||||
return v8::Undefined();
|
||||
}
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
|
||||
#include "base/logging.h"
|
||||
#include "base/values.h"
|
||||
#include "browser/api/atom_api_event.h"
|
||||
#include "common/v8_conversions.h"
|
||||
#include "common/v8_value_converter_impl.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "vendor/node/src/node.h"
|
||||
|
@ -42,7 +44,7 @@ void AtomBrowserBindings::AfterLoad() {
|
|||
|
||||
void AtomBrowserBindings::OnRendererMessage(int process_id,
|
||||
int routing_id,
|
||||
const std::string& channel,
|
||||
const string16& channel,
|
||||
const base::ListValue& args) {
|
||||
v8::HandleScope scope;
|
||||
|
||||
|
@ -53,7 +55,7 @@ void AtomBrowserBindings::OnRendererMessage(int process_id,
|
|||
// process.emit(channel, 'message', process_id, routing_id);
|
||||
std::vector<v8::Handle<v8::Value>> arguments;
|
||||
arguments.reserve(3 + args.GetSize());
|
||||
arguments.push_back(v8::String::New(channel.c_str(), channel.size()));
|
||||
arguments.push_back(ToV8Value(channel));
|
||||
const base::Value* value;
|
||||
if (args.Get(0, &value))
|
||||
arguments.push_back(converter->ToV8Value(value, context));
|
||||
|
@ -72,21 +74,24 @@ void AtomBrowserBindings::OnRendererMessage(int process_id,
|
|||
void AtomBrowserBindings::OnRendererMessageSync(
|
||||
int process_id,
|
||||
int routing_id,
|
||||
const std::string& channel,
|
||||
const string16& channel,
|
||||
const base::ListValue& args,
|
||||
base::DictionaryValue* result) {
|
||||
NativeWindow* sender,
|
||||
IPC::Message* message) {
|
||||
v8::HandleScope scope;
|
||||
|
||||
v8::Handle<v8::Context> context = v8::Context::GetCurrent();
|
||||
|
||||
scoped_ptr<V8ValueConverter> converter(new V8ValueConverterImpl());
|
||||
|
||||
v8::Handle<v8::Object> event = v8::Object::New();
|
||||
// Create the event object.
|
||||
v8::Handle<v8::Object> event = api::Event::CreateV8Object();
|
||||
api::Event::Unwrap<api::Event>(event)->SetSenderAndMessage(sender, message);
|
||||
|
||||
// process.emit(channel, 'sync-message', event, process_id, routing_id);
|
||||
std::vector<v8::Handle<v8::Value>> arguments;
|
||||
arguments.reserve(3 + args.GetSize());
|
||||
arguments.push_back(v8::String::New(channel.c_str(), channel.size()));
|
||||
arguments.push_back(ToV8Value(channel));
|
||||
const base::Value* value;
|
||||
if (args.Get(0, &value))
|
||||
arguments.push_back(converter->ToV8Value(value, context));
|
||||
|
@ -101,11 +106,6 @@ void AtomBrowserBindings::OnRendererMessageSync(
|
|||
}
|
||||
|
||||
node::MakeCallback(node::process, "emit", arguments.size(), &arguments[0]);
|
||||
|
||||
scoped_ptr<base::Value> base_event(converter->FromV8Value(event, context));
|
||||
DCHECK(base_event && base_event->IsType(base::Value::TYPE_DICTIONARY));
|
||||
|
||||
result->Swap(static_cast<base::DictionaryValue*>(base_event.get()));
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
|
|
|
@ -5,17 +5,21 @@
|
|||
#ifndef ATOM_BROWSER_API_ATOM_BROWSER_BINDINGS_
|
||||
#define ATOM_BROWSER_API_ATOM_BROWSER_BINDINGS_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "base/string16.h"
|
||||
#include "common/api/atom_bindings.h"
|
||||
|
||||
namespace base {
|
||||
class DictionaryValue;
|
||||
class ListValue;
|
||||
}
|
||||
|
||||
namespace IPC {
|
||||
class Message;
|
||||
}
|
||||
|
||||
namespace atom {
|
||||
|
||||
class NativeWindow;
|
||||
|
||||
class AtomBrowserBindings : public AtomBindings {
|
||||
public:
|
||||
AtomBrowserBindings();
|
||||
|
@ -27,15 +31,16 @@ class AtomBrowserBindings : public AtomBindings {
|
|||
// Called when received a message from renderer.
|
||||
void OnRendererMessage(int process_id,
|
||||
int routing_id,
|
||||
const std::string& channel,
|
||||
const string16& channel,
|
||||
const base::ListValue& args);
|
||||
|
||||
// Called when received a synchronous message from renderer.
|
||||
void OnRendererMessageSync(int process_id,
|
||||
int routing_id,
|
||||
const std::string& channel,
|
||||
const string16& channel,
|
||||
const base::ListValue& args,
|
||||
base::DictionaryValue* result);
|
||||
NativeWindow* sender,
|
||||
IPC::Message* message);
|
||||
|
||||
// The require('atom').browserMainParts object.
|
||||
v8::Handle<v8::Object> browser_main_parts() {
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
binding = process.atomBinding 'dialog'
|
||||
v8Util = process.atomBinding 'v8_util'
|
||||
BrowserWindow = require 'browser-window'
|
||||
|
||||
fileDialogProperties =
|
||||
|
@ -7,48 +8,71 @@ fileDialogProperties =
|
|||
messageBoxTypes = ['none', 'info', 'warning']
|
||||
|
||||
module.exports =
|
||||
showOpenDialog: (options) ->
|
||||
options = title: 'Open', properties: ['openFile'] unless options?
|
||||
options.properties = options.properties ? ['openFile']
|
||||
showOpenDialog: (window, options, callback) ->
|
||||
unless window?.constructor is BrowserWindow
|
||||
# Shift.
|
||||
callback = options
|
||||
options = window
|
||||
window = null
|
||||
|
||||
options ?= title: 'Open', properties: ['openFile']
|
||||
options.properties ?= ['openFile']
|
||||
throw new TypeError('Properties need to be array') unless Array.isArray options.properties
|
||||
|
||||
properties = 0
|
||||
for prop, value of fileDialogProperties
|
||||
properties |= value if prop in options.properties
|
||||
|
||||
options.title = options.title ? ''
|
||||
options.defaultPath = options.defaultPath ? ''
|
||||
options.title ?= ''
|
||||
options.defaultPath ?= ''
|
||||
|
||||
binding.showOpenDialog options.title, options.defaultPath, properties
|
||||
binding.showOpenDialog String(options.title),
|
||||
String(options.defaultPath),
|
||||
properties,
|
||||
window,
|
||||
callback
|
||||
|
||||
showSaveDialog: (window, options) ->
|
||||
throw new TypeError('Invalid window') unless window?.constructor is BrowserWindow
|
||||
options = title: 'Save' unless options?
|
||||
|
||||
options.title = options.title ? ''
|
||||
options.defaultPath = options.defaultPath ? ''
|
||||
|
||||
binding.showSaveDialog window, options.title, options.defaultPath
|
||||
|
||||
showMessageBox: (window, options) ->
|
||||
if window? and window.constructor isnt BrowserWindow
|
||||
showSaveDialog: (window, options, callback) ->
|
||||
unless window?.constructor is BrowserWindow
|
||||
# Shift.
|
||||
callback = options
|
||||
options = window
|
||||
window = null
|
||||
|
||||
options = type: 'none' unless options?
|
||||
options.type = options.type ? 'none'
|
||||
options ?= title: 'Save'
|
||||
options.title ?= ''
|
||||
options.defaultPath ?= ''
|
||||
|
||||
binding.showSaveDialog String(options.title),
|
||||
String(options.defaultPath),
|
||||
window,
|
||||
callback
|
||||
|
||||
showMessageBox: (window, options, callback) ->
|
||||
unless window?.constructor is BrowserWindow
|
||||
# Shift.
|
||||
callback = options
|
||||
options = window
|
||||
window = null
|
||||
|
||||
options ?= type: 'none'
|
||||
options.type ?= 'none'
|
||||
options.type = messageBoxTypes.indexOf options.type
|
||||
throw new TypeError('Invalid message box type') unless options.type > -1
|
||||
|
||||
throw new TypeError('Buttons need to be array') unless Array.isArray options.buttons
|
||||
|
||||
options.title = options.title ? ''
|
||||
options.message = options.message ? ''
|
||||
options.detail = options.detail ? ''
|
||||
options.title ?= ''
|
||||
options.message ?= ''
|
||||
options.detail ?= ''
|
||||
|
||||
binding.showMessageBox options.type,
|
||||
options.buttons,
|
||||
String(options.title),
|
||||
String(options.message),
|
||||
String(options.detail),
|
||||
window
|
||||
window,
|
||||
callback
|
||||
|
||||
# Mark standard asynchronous functions.
|
||||
v8Util.setHiddenValue f, 'asynchronous', true for k, f of module.exports
|
||||
|
|
|
@ -14,8 +14,13 @@ class Ipc extends EventEmitter
|
|||
constructor: ->
|
||||
process.on 'ATOM_INTERNAL_MESSAGE', (args...) =>
|
||||
@emit(args...)
|
||||
process.on 'ATOM_INTERNAL_MESSAGE_SYNC', (args...) =>
|
||||
@emit(args...)
|
||||
process.on 'ATOM_INTERNAL_MESSAGE_SYNC', (channel, event, args...) =>
|
||||
set = (value) -> event.sendReply JSON.stringify(value)
|
||||
|
||||
Object.defineProperty event, 'returnValue', {set}
|
||||
Object.defineProperty event, 'result', {set}
|
||||
|
||||
@emit(channel, event, args...)
|
||||
|
||||
send: (processId, routingId, args...) ->
|
||||
@sendChannel(processId, routingId, 'message', args...)
|
||||
|
|
|
@ -61,28 +61,40 @@ unwrapArgs = (processId, routingId, args) ->
|
|||
|
||||
args.map metaToValue
|
||||
|
||||
# Call a function and send reply asynchronously if it's a an asynchronous
|
||||
# style function and the caller didn't pass a callback.
|
||||
callFunction = (event, processId, routingId, func, caller, args) ->
|
||||
if v8Util.getHiddenValue(func, 'asynchronous') and typeof args[args.length - 1] isnt 'function'
|
||||
args.push (ret) ->
|
||||
event.returnValue = valueToMeta processId, routingId, ret
|
||||
func.apply caller, args
|
||||
else
|
||||
ret = func.apply caller, args
|
||||
event.returnValue = valueToMeta processId, routingId, ret
|
||||
|
||||
ipc.on 'ATOM_BROWSER_REQUIRE', (event, processId, routingId, module) ->
|
||||
try
|
||||
event.result = valueToMeta processId, routingId, require(module)
|
||||
event.returnValue = valueToMeta processId, routingId, require(module)
|
||||
catch e
|
||||
event.result = errorToMeta e
|
||||
event.returnValue = errorToMeta e
|
||||
|
||||
ipc.on 'ATOM_BROWSER_GLOBAL', (event, processId, routingId, name) ->
|
||||
try
|
||||
event.result = valueToMeta processId, routingId, global[name]
|
||||
event.returnValue = valueToMeta processId, routingId, global[name]
|
||||
catch e
|
||||
event.result = errorToMeta e
|
||||
event.returnValue = errorToMeta e
|
||||
|
||||
ipc.on 'ATOM_BROWSER_RELEASE_RENDER_VIEW', (event, processId, routingId) ->
|
||||
objectsRegistry.clear processId, routingId
|
||||
event.returnValue = null
|
||||
|
||||
ipc.on 'ATOM_BROWSER_CURRENT_WINDOW', (event, processId, routingId) ->
|
||||
try
|
||||
BrowserWindow = require 'browser-window'
|
||||
window = BrowserWindow.fromProcessIdAndRoutingId processId, routingId
|
||||
event.result = valueToMeta processId, routingId, window
|
||||
event.returnValue = valueToMeta processId, routingId, window
|
||||
catch e
|
||||
event.result = errorToMeta e
|
||||
event.returnValue = errorToMeta e
|
||||
|
||||
ipc.on 'ATOM_BROWSER_CONSTRUCTOR', (event, processId, routingId, id, args) ->
|
||||
try
|
||||
|
@ -91,18 +103,17 @@ ipc.on 'ATOM_BROWSER_CONSTRUCTOR', (event, processId, routingId, id, args) ->
|
|||
# Call new with array of arguments.
|
||||
# http://stackoverflow.com/questions/1606797/use-of-apply-with-new-operator-is-this-possible
|
||||
obj = new (Function::bind.apply(constructor, [null].concat(args)))
|
||||
event.result = valueToMeta processId, routingId, obj
|
||||
event.returnValue = valueToMeta processId, routingId, obj
|
||||
catch e
|
||||
event.result = errorToMeta e
|
||||
event.returnValue = errorToMeta e
|
||||
|
||||
ipc.on 'ATOM_BROWSER_FUNCTION_CALL', (event, processId, routingId, id, args) ->
|
||||
try
|
||||
args = unwrapArgs processId, routingId, args
|
||||
func = objectsRegistry.get id
|
||||
ret = func.apply global, args
|
||||
event.result = valueToMeta processId, routingId, ret
|
||||
callFunction event, processId, routingId, func, global, args
|
||||
catch e
|
||||
event.result = errorToMeta e
|
||||
event.returnValue = errorToMeta e
|
||||
|
||||
ipc.on 'ATOM_BROWSER_MEMBER_CONSTRUCTOR', (event, processId, routingId, id, method, args) ->
|
||||
try
|
||||
|
@ -110,32 +121,32 @@ ipc.on 'ATOM_BROWSER_MEMBER_CONSTRUCTOR', (event, processId, routingId, id, meth
|
|||
constructor = objectsRegistry.get(id)[method]
|
||||
# Call new with array of arguments.
|
||||
obj = new (Function::bind.apply(constructor, [null].concat(args)))
|
||||
event.result = valueToMeta processId, routingId, obj
|
||||
event.returnValue = valueToMeta processId, routingId, obj
|
||||
catch e
|
||||
event.result = errorToMeta e
|
||||
event.returnValue = errorToMeta e
|
||||
|
||||
ipc.on 'ATOM_BROWSER_MEMBER_CALL', (event, processId, routingId, id, method, args) ->
|
||||
try
|
||||
args = unwrapArgs processId, routingId, args
|
||||
obj = objectsRegistry.get id
|
||||
ret = obj[method].apply(obj, args)
|
||||
event.result = valueToMeta processId, routingId, ret
|
||||
callFunction event, processId, routingId, obj[method], obj, args
|
||||
catch e
|
||||
event.result = errorToMeta e
|
||||
event.returnValue = errorToMeta e
|
||||
|
||||
ipc.on 'ATOM_BROWSER_MEMBER_SET', (event, processId, routingId, id, name, value) ->
|
||||
try
|
||||
obj = objectsRegistry.get id
|
||||
obj[name] = value
|
||||
event.returnValue = null
|
||||
catch e
|
||||
event.result = errorToMeta e
|
||||
event.returnValue = errorToMeta e
|
||||
|
||||
ipc.on 'ATOM_BROWSER_MEMBER_GET', (event, processId, routingId, id, name) ->
|
||||
try
|
||||
obj = objectsRegistry.get id
|
||||
event.result = valueToMeta processId, routingId, obj[name]
|
||||
event.returnValue = valueToMeta processId, routingId, obj[name]
|
||||
catch e
|
||||
event.result = errorToMeta e
|
||||
event.returnValue = errorToMeta e
|
||||
|
||||
ipc.on 'ATOM_BROWSER_DEREFERENCE', (processId, routingId, storeId) ->
|
||||
objectsRegistry.remove processId, routingId, storeId
|
||||
|
|
|
@ -300,7 +300,8 @@ bool NativeWindow::OnMessageReceived(const IPC::Message& message) {
|
|||
bool handled = true;
|
||||
IPC_BEGIN_MESSAGE_MAP(NativeWindow, message)
|
||||
IPC_MESSAGE_HANDLER(AtomViewHostMsg_Message, OnRendererMessage)
|
||||
IPC_MESSAGE_HANDLER(AtomViewHostMsg_Message_Sync, OnRendererMessageSync)
|
||||
IPC_MESSAGE_HANDLER_DELAY_REPLY(AtomViewHostMsg_Message_Sync,
|
||||
OnRendererMessageSync)
|
||||
IPC_MESSAGE_HANDLER(AtomViewHostMsg_UpdateDraggableRegions,
|
||||
UpdateDraggableRegions)
|
||||
IPC_MESSAGE_UNHANDLED(handled = false)
|
||||
|
@ -340,7 +341,7 @@ void NativeWindow::Observe(int type,
|
|||
}
|
||||
}
|
||||
|
||||
void NativeWindow::OnRendererMessage(const std::string& channel,
|
||||
void NativeWindow::OnRendererMessage(const string16& channel,
|
||||
const base::ListValue& args) {
|
||||
AtomBrowserMainParts::Get()->atom_bindings()->OnRendererMessage(
|
||||
GetWebContents()->GetRenderProcessHost()->GetID(),
|
||||
|
@ -349,15 +350,16 @@ void NativeWindow::OnRendererMessage(const std::string& channel,
|
|||
args);
|
||||
}
|
||||
|
||||
void NativeWindow::OnRendererMessageSync(const std::string& channel,
|
||||
void NativeWindow::OnRendererMessageSync(const string16& channel,
|
||||
const base::ListValue& args,
|
||||
base::DictionaryValue* result) {
|
||||
IPC::Message* reply_msg) {
|
||||
AtomBrowserMainParts::Get()->atom_bindings()->OnRendererMessageSync(
|
||||
GetWebContents()->GetRenderProcessHost()->GetID(),
|
||||
GetWebContents()->GetRoutingID(),
|
||||
channel,
|
||||
args,
|
||||
result);
|
||||
this,
|
||||
reply_msg);
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
|
|
|
@ -35,6 +35,10 @@ class Rect;
|
|||
class Size;
|
||||
}
|
||||
|
||||
namespace IPC {
|
||||
class Message;
|
||||
}
|
||||
|
||||
namespace atom {
|
||||
|
||||
class AtomJavaScriptDialogManager;
|
||||
|
@ -173,12 +177,12 @@ class NativeWindow : public brightray::DefaultWebContentsDelegate,
|
|||
private:
|
||||
void RendererUnresponsiveDelayed();
|
||||
|
||||
void OnRendererMessage(const std::string& channel,
|
||||
void OnRendererMessage(const string16& channel,
|
||||
const base::ListValue& args);
|
||||
|
||||
void OnRendererMessageSync(const std::string& channel,
|
||||
void OnRendererMessageSync(const string16& channel,
|
||||
const base::ListValue& args,
|
||||
base::DictionaryValue* result);
|
||||
IPC::Message* reply_msg);
|
||||
|
||||
// Notification manager.
|
||||
content::NotificationRegistrar registrar_;
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "base/callback_forward.h"
|
||||
#include "base/files/file_path.h"
|
||||
|
||||
namespace atom {
|
||||
|
@ -23,16 +24,34 @@ enum FileDialogProperty {
|
|||
FILE_DIALOG_CREATE_DIRECTORY = 8,
|
||||
};
|
||||
|
||||
bool ShowOpenDialog(const std::string& title,
|
||||
typedef base::Callback<void(
|
||||
bool result, const std::vector<base::FilePath>& paths)> OpenDialogCallback;
|
||||
|
||||
typedef base::Callback<void(
|
||||
bool result, const base::FilePath& path)> SaveDialogCallback;
|
||||
|
||||
bool ShowOpenDialog(atom::NativeWindow* parent_window,
|
||||
const std::string& title,
|
||||
const base::FilePath& default_path,
|
||||
int properties,
|
||||
std::vector<base::FilePath>* paths);
|
||||
|
||||
bool ShowSaveDialog(atom::NativeWindow* window,
|
||||
void ShowOpenDialog(atom::NativeWindow* parent_window,
|
||||
const std::string& title,
|
||||
const base::FilePath& default_path,
|
||||
int properties,
|
||||
const OpenDialogCallback& callback);
|
||||
|
||||
bool ShowSaveDialog(atom::NativeWindow* parent_window,
|
||||
const std::string& title,
|
||||
const base::FilePath& default_path,
|
||||
base::FilePath* path);
|
||||
|
||||
void ShowSaveDialog(atom::NativeWindow* parent_window,
|
||||
const std::string& title,
|
||||
const base::FilePath& default_path,
|
||||
const SaveDialogCallback& callback);
|
||||
|
||||
} // namespace file_dialog
|
||||
|
||||
#endif // BROWSER_UI_FILE_DIALOG_H_
|
||||
|
|
|
@ -38,20 +38,11 @@ void SetupDialog(NSSavePanel* dialog,
|
|||
if (default_filename)
|
||||
[dialog setNameFieldStringValue:default_filename];
|
||||
|
||||
[dialog setCanSelectHiddenExtension:YES];
|
||||
[dialog setAllowsOtherFileTypes:YES];
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
bool ShowOpenDialog(const std::string& title,
|
||||
const base::FilePath& default_path,
|
||||
int properties,
|
||||
std::vector<base::FilePath>* paths) {
|
||||
DCHECK(paths);
|
||||
NSOpenPanel* dialog = [NSOpenPanel openPanel];
|
||||
|
||||
SetupDialog(dialog, title, default_path);
|
||||
|
||||
void SetupDialogForProperties(NSOpenPanel* dialog, int properties) {
|
||||
[dialog setCanChooseFiles:(properties & FILE_DIALOG_OPEN_FILE)];
|
||||
if (properties & FILE_DIALOG_OPEN_DIRECTORY)
|
||||
[dialog setCanChooseDirectories:YES];
|
||||
|
@ -59,49 +50,119 @@ bool ShowOpenDialog(const std::string& title,
|
|||
[dialog setCanCreateDirectories:YES];
|
||||
if (properties & FILE_DIALOG_MULTI_SELECTIONS)
|
||||
[dialog setAllowsMultipleSelection:YES];
|
||||
}
|
||||
|
||||
if ([dialog runModal] == NSFileHandlingPanelCancelButton)
|
||||
return false;
|
||||
// Run modal dialog with parent window and return user's choice.
|
||||
int RunModalDialog(NSSavePanel* dialog, atom::NativeWindow* parent_window) {
|
||||
__block int chosen = NSFileHandlingPanelCancelButton;
|
||||
if (parent_window == NULL) {
|
||||
chosen = [dialog runModal];
|
||||
} else {
|
||||
NSWindow* window = parent_window->GetNativeWindow();
|
||||
|
||||
[dialog beginSheetModalForWindow:window
|
||||
completionHandler:^(NSInteger c) {
|
||||
chosen = c;
|
||||
[NSApp stopModal];
|
||||
}];
|
||||
[NSApp runModalForWindow:window];
|
||||
}
|
||||
|
||||
return chosen;
|
||||
}
|
||||
|
||||
void ReadDialogPaths(NSOpenPanel* dialog, std::vector<base::FilePath>* paths) {
|
||||
NSArray* urls = [dialog URLs];
|
||||
for (NSURL* url in urls)
|
||||
if ([url isFileURL])
|
||||
paths->push_back(base::FilePath(base::SysNSStringToUTF8([url path])));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
bool ShowOpenDialog(atom::NativeWindow* parent_window,
|
||||
const std::string& title,
|
||||
const base::FilePath& default_path,
|
||||
int properties,
|
||||
std::vector<base::FilePath>* paths) {
|
||||
DCHECK(paths);
|
||||
NSOpenPanel* dialog = [NSOpenPanel openPanel];
|
||||
|
||||
SetupDialog(dialog, title, default_path);
|
||||
SetupDialogForProperties(dialog, properties);
|
||||
|
||||
int chosen = RunModalDialog(dialog, parent_window);
|
||||
if (chosen == NSFileHandlingPanelCancelButton)
|
||||
return false;
|
||||
|
||||
ReadDialogPaths(dialog, paths);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ShowSaveDialog(atom::NativeWindow* window,
|
||||
void ShowOpenDialog(atom::NativeWindow* parent_window,
|
||||
const std::string& title,
|
||||
const base::FilePath& default_path,
|
||||
int properties,
|
||||
const OpenDialogCallback& c) {
|
||||
NSOpenPanel* dialog = [NSOpenPanel openPanel];
|
||||
|
||||
SetupDialog(dialog, title, default_path);
|
||||
SetupDialogForProperties(dialog, properties);
|
||||
|
||||
// Duplicate the callback object here since c is a reference and gcd would
|
||||
// only store the pointer, by duplication we can force gcd to store a copy.
|
||||
__block OpenDialogCallback callback = c;
|
||||
|
||||
NSWindow* window = parent_window ? parent_window->GetNativeWindow() : NULL;
|
||||
[dialog beginSheetModalForWindow:window
|
||||
completionHandler:^(NSInteger chosen) {
|
||||
if (chosen == NSFileHandlingPanelCancelButton) {
|
||||
callback.Run(false, std::vector<base::FilePath>());
|
||||
} else {
|
||||
std::vector<base::FilePath> paths;
|
||||
ReadDialogPaths(dialog, &paths);
|
||||
callback.Run(true, paths);
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
bool ShowSaveDialog(atom::NativeWindow* parent_window,
|
||||
const std::string& title,
|
||||
const base::FilePath& default_path,
|
||||
base::FilePath* path) {
|
||||
DCHECK(window);
|
||||
DCHECK(path);
|
||||
NSSavePanel* dialog = [NSSavePanel savePanel];
|
||||
|
||||
SetupDialog(dialog, title, default_path);
|
||||
|
||||
[dialog setCanSelectHiddenExtension:YES];
|
||||
int chosen = RunModalDialog(dialog, parent_window);
|
||||
if (chosen == NSFileHandlingPanelCancelButton || ![[dialog URL] isFileURL])
|
||||
return false;
|
||||
|
||||
__block bool result = false;
|
||||
__block base::FilePath ret_path;
|
||||
[dialog beginSheetModalForWindow:window->GetNativeWindow()
|
||||
*path = base::FilePath(base::SysNSStringToUTF8([[dialog URL] path]));
|
||||
return true;
|
||||
}
|
||||
|
||||
void ShowSaveDialog(atom::NativeWindow* parent_window,
|
||||
const std::string& title,
|
||||
const base::FilePath& default_path,
|
||||
const SaveDialogCallback& c) {
|
||||
NSSavePanel* dialog = [NSSavePanel savePanel];
|
||||
|
||||
SetupDialog(dialog, title, default_path);
|
||||
|
||||
__block SaveDialogCallback callback = c;
|
||||
|
||||
NSWindow* window = parent_window ? parent_window->GetNativeWindow() : NULL;
|
||||
[dialog beginSheetModalForWindow:window
|
||||
completionHandler:^(NSInteger chosen) {
|
||||
if (chosen == NSFileHandlingPanelCancelButton ||
|
||||
![[dialog URL] isFileURL]) {
|
||||
result = false;
|
||||
if (chosen == NSFileHandlingPanelCancelButton) {
|
||||
callback.Run(false, base::FilePath());
|
||||
} else {
|
||||
result = true;
|
||||
ret_path = base::FilePath(base::SysNSStringToUTF8([[dialog URL] path]));
|
||||
std::string path = base::SysNSStringToUTF8([[dialog URL] path]);
|
||||
callback.Run(true, base::FilePath(path));
|
||||
}
|
||||
|
||||
[NSApp stopModal];
|
||||
}];
|
||||
|
||||
[NSApp runModalForWindow:window->GetNativeWindow()];
|
||||
|
||||
*path = ret_path;
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace file_dialog
|
||||
|
|
|
@ -162,7 +162,8 @@ class FileDialog {
|
|||
SetDefaultFolder(default_path);
|
||||
}
|
||||
|
||||
bool Show(HWND window) {
|
||||
bool Show(atom::NativeWindow* parent_window) {
|
||||
HWND window = parent_window ? parent_window->GetNativeWindow() : NULL;
|
||||
return dialog_->DoModal(window) == IDOK;
|
||||
}
|
||||
|
||||
|
@ -198,7 +199,8 @@ class FileDialog {
|
|||
|
||||
} // namespace
|
||||
|
||||
bool ShowOpenDialog(const std::string& title,
|
||||
bool ShowOpenDialog(atom::NativeWindow* parent_window,
|
||||
const std::string& title,
|
||||
const base::FilePath& default_path,
|
||||
int properties,
|
||||
std::vector<base::FilePath>* paths) {
|
||||
|
@ -214,7 +216,7 @@ bool ShowOpenDialog(const std::string& title,
|
|||
options,
|
||||
std::vector<std::wstring>(),
|
||||
std::vector<std::wstring>());
|
||||
if (!open_dialog.Show(::GetActiveWindow()))
|
||||
if (!open_dialog.Show(parent_window))
|
||||
return false;
|
||||
|
||||
ATL::CComPtr<IShellItemArray> items;
|
||||
|
@ -247,7 +249,21 @@ bool ShowOpenDialog(const std::string& title,
|
|||
return true;
|
||||
}
|
||||
|
||||
bool ShowSaveDialog(atom::NativeWindow* window,
|
||||
void ShowOpenDialog(atom::NativeWindow* parent_window,
|
||||
const std::string& title,
|
||||
const base::FilePath& default_path,
|
||||
int properties,
|
||||
const OpenDialogCallback& callback) {
|
||||
std::vector<base::FilePath> paths;
|
||||
bool result = ShowOpenDialog(parent_window,
|
||||
title,
|
||||
default_path,
|
||||
properties,
|
||||
&paths);
|
||||
callback.Run(result, paths);
|
||||
}
|
||||
|
||||
bool ShowSaveDialog(atom::NativeWindow* parent_window,
|
||||
const std::string& title,
|
||||
const base::FilePath& default_path,
|
||||
base::FilePath* path) {
|
||||
|
@ -263,7 +279,7 @@ bool ShowSaveDialog(atom::NativeWindow* window,
|
|||
FOS_FORCEFILESYSTEM | FOS_PATHMUSTEXIST | FOS_OVERWRITEPROMPT,
|
||||
file_ext,
|
||||
std::vector<std::wstring>());
|
||||
if (!save_dialog.Show(window->GetNativeWindow()))
|
||||
if (!save_dialog.Show(parent_window))
|
||||
return false;
|
||||
|
||||
wchar_t file_name[MAX_PATH];
|
||||
|
@ -290,4 +306,13 @@ bool ShowSaveDialog(atom::NativeWindow* window,
|
|||
return true;
|
||||
}
|
||||
|
||||
void ShowSaveDialog(atom::NativeWindow* parent_window,
|
||||
const std::string& title,
|
||||
const base::FilePath& default_path,
|
||||
const SaveDialogCallback& callback) {
|
||||
base::FilePath path;
|
||||
bool result = ShowSaveDialog(parent_window, title, default_path, &path);
|
||||
callback.Run(result, path);
|
||||
}
|
||||
|
||||
} // namespace file_dialog
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "base/callback_forward.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
class NativeWindow;
|
||||
|
@ -18,6 +20,8 @@ enum MessageBoxType {
|
|||
MESSAGE_BOX_TYPE_WARNING
|
||||
};
|
||||
|
||||
typedef base::Callback<void(int code)> MessageBoxCallback;
|
||||
|
||||
int ShowMessageBox(NativeWindow* parent_window,
|
||||
MessageBoxType type,
|
||||
const std::vector<std::string>& buttons,
|
||||
|
@ -25,6 +29,14 @@ int ShowMessageBox(NativeWindow* parent_window,
|
|||
const std::string& message,
|
||||
const std::string& detail);
|
||||
|
||||
void ShowMessageBox(NativeWindow* parent_window,
|
||||
MessageBoxType type,
|
||||
const std::vector<std::string>& buttons,
|
||||
const std::string& title,
|
||||
const std::string& message,
|
||||
const std::string& detail,
|
||||
const MessageBoxCallback& callback);
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // BROWSER_UI_MESSAGE_BOX_H_
|
||||
|
|
|
@ -6,20 +6,53 @@
|
|||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
#include "base/callback.h"
|
||||
#include "base/strings/sys_string_conversions.h"
|
||||
#include "browser/native_window.h"
|
||||
#include "browser/ui/nsalert_synchronous_sheet_mac.h"
|
||||
|
||||
@interface ModalDelegate : NSObject {
|
||||
@private
|
||||
atom::MessageBoxCallback callback_;
|
||||
NSAlert* alert_;
|
||||
}
|
||||
- (id)initWithCallback:(const atom::MessageBoxCallback&)callback
|
||||
andAlert:(NSAlert*)alert;
|
||||
@end
|
||||
|
||||
@implementation ModalDelegate
|
||||
|
||||
- (id)initWithCallback:(const atom::MessageBoxCallback&)callback
|
||||
andAlert:(NSAlert*)alert {
|
||||
if ((self = [super init])) {
|
||||
callback_ = callback;
|
||||
alert_ = alert;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)alertDidEnd:(NSAlert*)alert
|
||||
returnCode:(NSInteger)returnCode
|
||||
contextInfo:(void*)contextInfo {
|
||||
callback_.Run(returnCode);
|
||||
[alert_ release];
|
||||
[self release];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
namespace atom {
|
||||
|
||||
int ShowMessageBox(NativeWindow* parent_window,
|
||||
MessageBoxType type,
|
||||
const std::vector<std::string>& buttons,
|
||||
const std::string& title,
|
||||
const std::string& message,
|
||||
const std::string& detail) {
|
||||
namespace {
|
||||
|
||||
NSAlert* CreateNSAlert(NativeWindow* parent_window,
|
||||
MessageBoxType type,
|
||||
const std::vector<std::string>& buttons,
|
||||
const std::string& title,
|
||||
const std::string& message,
|
||||
const std::string& detail) {
|
||||
// Ignore the title; it's the window title on other platforms and ignorable.
|
||||
NSAlert* alert = [[[NSAlert alloc] init] autorelease];
|
||||
NSAlert* alert = [[NSAlert alloc] init];
|
||||
[alert setMessageText:base::SysUTF8ToNSString(message)];
|
||||
[alert setInformativeText:base::SysUTF8ToNSString(detail)];
|
||||
|
||||
|
@ -40,10 +73,44 @@ int ShowMessageBox(NativeWindow* parent_window,
|
|||
[button setTag:i];
|
||||
}
|
||||
|
||||
return alert;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
int ShowMessageBox(NativeWindow* parent_window,
|
||||
MessageBoxType type,
|
||||
const std::vector<std::string>& buttons,
|
||||
const std::string& title,
|
||||
const std::string& message,
|
||||
const std::string& detail) {
|
||||
NSAlert* alert = CreateNSAlert(
|
||||
parent_window, type, buttons, title, message, detail);
|
||||
[alert autorelease];
|
||||
|
||||
if (parent_window)
|
||||
return [alert runModalSheetForWindow:parent_window->GetNativeWindow()];
|
||||
else
|
||||
return [alert runModal];
|
||||
}
|
||||
|
||||
void ShowMessageBox(NativeWindow* parent_window,
|
||||
MessageBoxType type,
|
||||
const std::vector<std::string>& buttons,
|
||||
const std::string& title,
|
||||
const std::string& message,
|
||||
const std::string& detail,
|
||||
const MessageBoxCallback& callback) {
|
||||
NSAlert* alert = CreateNSAlert(
|
||||
parent_window, type, buttons, title, message, detail);
|
||||
ModalDelegate* delegate = [[ModalDelegate alloc] initWithCallback:callback
|
||||
andAlert:alert];
|
||||
|
||||
NSWindow* window = parent_window ? parent_window->GetNativeWindow() : nil;
|
||||
[alert beginSheetModalForWindow:window
|
||||
modalDelegate:delegate
|
||||
didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:)
|
||||
contextInfo:nil];
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
#include "browser/ui/message_box.h"
|
||||
|
||||
#include "base/callback.h"
|
||||
#include "base/message_loop.h"
|
||||
#include "base/run_loop.h"
|
||||
#include "base/string_util.h"
|
||||
|
@ -38,7 +39,14 @@ class MessageDialog : public base::MessageLoop::Dispatcher,
|
|||
const std::string& detail);
|
||||
virtual ~MessageDialog();
|
||||
|
||||
int result() const { return result_; }
|
||||
void Show();
|
||||
|
||||
int GetResult() const;
|
||||
|
||||
void set_callback(const MessageBoxCallback& callback) {
|
||||
delete_on_close_ = true;
|
||||
callback_ = callback;
|
||||
}
|
||||
|
||||
private:
|
||||
// Overridden from MessageLoop::Dispatcher:
|
||||
|
@ -63,11 +71,13 @@ class MessageDialog : public base::MessageLoop::Dispatcher,
|
|||
const ui::Event& event) OVERRIDE;
|
||||
|
||||
bool should_close_;
|
||||
bool delete_on_close_;
|
||||
int result_;
|
||||
string16 title_;
|
||||
views::Widget* widget_;
|
||||
views::MessageBoxView* message_box_view_;
|
||||
std::vector<views::LabelButton*> buttons_;
|
||||
MessageBoxCallback callback_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(MessageDialog);
|
||||
};
|
||||
|
@ -82,6 +92,7 @@ MessageDialog::MessageDialog(NativeWindow* parent_window,
|
|||
const std::string& message,
|
||||
const std::string& detail)
|
||||
: should_close_(false),
|
||||
delete_on_close_(false),
|
||||
result_(-1),
|
||||
title_(UTF8ToUTF16(title)),
|
||||
widget_(NULL),
|
||||
|
@ -124,12 +135,30 @@ MessageDialog::MessageDialog(NativeWindow* parent_window,
|
|||
|
||||
set_background(views::Background::CreateSolidBackground(
|
||||
skia::COLORREFToSkColor(GetSysColor(COLOR_WINDOW))));
|
||||
widget_->Show();
|
||||
}
|
||||
|
||||
MessageDialog::~MessageDialog() {
|
||||
}
|
||||
|
||||
void MessageDialog::Show() {
|
||||
widget_->Show();
|
||||
}
|
||||
|
||||
int MessageDialog::GetResult() const {
|
||||
// When the dialog is closed without choosing anything, we think the user
|
||||
// chose 'Cancel', otherwise we think the default behavior is chosen.
|
||||
if (result_ == -1) {
|
||||
for (size_t i = 0; i < buttons_.size(); ++i)
|
||||
if (LowerCaseEqualsASCII(buttons_[i]->GetText(), "cancel")) {
|
||||
return i;
|
||||
}
|
||||
|
||||
return 0;
|
||||
} else {
|
||||
return result_;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// MessageDialog, private:
|
||||
|
||||
|
@ -145,6 +174,11 @@ string16 MessageDialog::GetWindowTitle() const {
|
|||
|
||||
void MessageDialog::WindowClosing() {
|
||||
should_close_ = true;
|
||||
|
||||
if (delete_on_close_) {
|
||||
callback_.Run(GetResult());
|
||||
base::MessageLoop::current()->DeleteSoon(FROM_HERE, this);
|
||||
}
|
||||
}
|
||||
|
||||
views::Widget* MessageDialog::GetWidget() {
|
||||
|
@ -232,6 +266,7 @@ int ShowMessageBox(NativeWindow* parent_window,
|
|||
const std::string& message,
|
||||
const std::string& detail) {
|
||||
MessageDialog dialog(parent_window, type, buttons, title, message, detail);
|
||||
dialog.Show();
|
||||
{
|
||||
base::MessageLoop::ScopedNestableTaskAllower allow(
|
||||
base::MessageLoopForUI::current());
|
||||
|
@ -239,18 +274,21 @@ int ShowMessageBox(NativeWindow* parent_window,
|
|||
run_loop.Run();
|
||||
}
|
||||
|
||||
// When the dialog is closed without choosing anything, we think the user
|
||||
// chose 'Cancel', otherwise we think the default behavior is chosen.
|
||||
if (dialog.result() == -1) {
|
||||
for (size_t i = 0; i < buttons.size(); ++i)
|
||||
if (LowerCaseEqualsASCII(buttons[i], "cancel")) {
|
||||
return i;
|
||||
}
|
||||
return dialog.GetResult();
|
||||
}
|
||||
|
||||
return 0;
|
||||
} else {
|
||||
return dialog.result();
|
||||
}
|
||||
void ShowMessageBox(NativeWindow* parent_window,
|
||||
MessageBoxType type,
|
||||
const std::vector<std::string>& buttons,
|
||||
const std::string& title,
|
||||
const std::string& message,
|
||||
const std::string& detail,
|
||||
const MessageBoxCallback& callback) {
|
||||
// The dialog would be deleted when the dialog is closed.
|
||||
MessageDialog* dialog = new MessageDialog(
|
||||
parent_window, type, buttons, title, message, detail);
|
||||
dialog->set_callback(callback);
|
||||
dialog->Show();
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
|
|
|
@ -4,8 +4,7 @@
|
|||
|
||||
// Multiply-included file, no traditional include guard.
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "base/string16.h"
|
||||
#include "base/values.h"
|
||||
#include "common/draggable_region.h"
|
||||
#include "content/public/common/common_param_traits.h"
|
||||
|
@ -22,16 +21,16 @@ IPC_STRUCT_TRAITS_BEGIN(atom::DraggableRegion)
|
|||
IPC_STRUCT_TRAITS_END()
|
||||
|
||||
IPC_MESSAGE_ROUTED2(AtomViewHostMsg_Message,
|
||||
std::string /* channel */,
|
||||
string16 /* channel */,
|
||||
ListValue /* arguments */)
|
||||
|
||||
IPC_SYNC_MESSAGE_ROUTED2_1(AtomViewHostMsg_Message_Sync,
|
||||
std::string /* channel */,
|
||||
string16 /* channel */,
|
||||
ListValue /* arguments */,
|
||||
DictionaryValue /* result */)
|
||||
string16 /* result (in JSON) */)
|
||||
|
||||
IPC_MESSAGE_ROUTED2(AtomViewMsg_Message,
|
||||
std::string /* channel */,
|
||||
string16 /* channel */,
|
||||
ListValue /* arguments */)
|
||||
|
||||
// Sent by the renderer when the draggable regions are updated.
|
||||
|
|
228
common/v8_conversions.h
Normal file
228
common/v8_conversions.h
Normal file
|
@ -0,0 +1,228 @@
|
|||
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef COMMON_V8_CONVERSIONS_H_
|
||||
#define COMMON_V8_CONVERSIONS_H_
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "base/files/file_path.h"
|
||||
#include "base/string16.h"
|
||||
#include "browser/api/atom_api_window.h"
|
||||
#include "v8/include/v8.h"
|
||||
|
||||
// Convert V8 value to arbitrary supported types.
|
||||
struct FromV8Value {
|
||||
explicit FromV8Value(v8::Handle<v8::Value> value) : value_(value) {}
|
||||
|
||||
operator int() {
|
||||
return value_->IntegerValue();
|
||||
}
|
||||
|
||||
operator bool() {
|
||||
return value_->BooleanValue();
|
||||
}
|
||||
|
||||
operator std::string() {
|
||||
return *v8::String::Utf8Value(value_);
|
||||
}
|
||||
|
||||
operator string16() {
|
||||
v8::String::Value s(value_);
|
||||
return string16(reinterpret_cast<const char16*>(*s), s.length());
|
||||
}
|
||||
|
||||
operator base::FilePath() {
|
||||
return base::FilePath::FromUTF8Unsafe(FromV8Value(value_));
|
||||
}
|
||||
|
||||
operator std::vector<std::string>() {
|
||||
std::vector<std::string> array;
|
||||
v8::Handle<v8::Array> v8_array = v8::Handle<v8::Array>::Cast(value_);
|
||||
for (uint32_t i = 0; i < v8_array->Length(); ++i)
|
||||
array.push_back(FromV8Value(v8_array->Get(i)));
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
operator atom::NativeWindow*() {
|
||||
using atom::api::Window;
|
||||
if (value_->IsObject()) {
|
||||
Window* window = Window::Unwrap<Window>(value_->ToObject());
|
||||
if (window && window->window())
|
||||
return window->window();
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
operator v8::Persistent<v8::Function>() {
|
||||
return value_->IsFunction() ?
|
||||
v8::Persistent<v8::Function>::New(
|
||||
node::node_isolate,
|
||||
v8::Handle<v8::Function>::Cast(value_)) :
|
||||
v8::Persistent<v8::Function>();
|
||||
}
|
||||
|
||||
v8::Handle<v8::Value> value_;
|
||||
};
|
||||
|
||||
// Convert arbitrary supported native type to V8 value.
|
||||
inline v8::Handle<v8::Value> ToV8Value(int i) {
|
||||
return v8::Integer::New(i);
|
||||
}
|
||||
|
||||
inline v8::Handle<v8::Value> ToV8Value(bool b) {
|
||||
return v8::Boolean::New(b);
|
||||
}
|
||||
|
||||
inline v8::Handle<v8::Value> ToV8Value(const std::string& s) {
|
||||
return v8::String::New(s.data(), s.size());
|
||||
}
|
||||
|
||||
inline v8::Handle<v8::Value> ToV8Value(const string16& s) {
|
||||
return v8::String::New(reinterpret_cast<const uint16_t*>(s.data()), s.size());
|
||||
}
|
||||
|
||||
inline v8::Handle<v8::Value> ToV8Value(const base::FilePath& path) {
|
||||
std::string path_string(path.AsUTF8Unsafe());
|
||||
return v8::String::New(path_string.data(), path_string.size());
|
||||
}
|
||||
|
||||
inline v8::Handle<v8::Value> ToV8Value(void* whatever) {
|
||||
return v8::Undefined();
|
||||
}
|
||||
|
||||
inline
|
||||
v8::Handle<v8::Value> ToV8Value(const std::vector<base::FilePath>& paths) {
|
||||
v8::Handle<v8::Array> result = v8::Array::New(paths.size());
|
||||
for (size_t i = 0; i < paths.size(); ++i)
|
||||
result->Set(i, ToV8Value(paths[i]));
|
||||
return result;
|
||||
}
|
||||
|
||||
// Check if a V8 Value is of specified type.
|
||||
template<class T> inline
|
||||
bool V8ValueCanBeConvertedTo(v8::Handle<v8::Value> value) {
|
||||
return false;
|
||||
}
|
||||
|
||||
template<> inline
|
||||
bool V8ValueCanBeConvertedTo<int>(v8::Handle<v8::Value> value) {
|
||||
return value->IsNumber();
|
||||
}
|
||||
|
||||
template<> inline
|
||||
bool V8ValueCanBeConvertedTo<bool>(v8::Handle<v8::Value> value) {
|
||||
return value->IsBoolean();
|
||||
}
|
||||
|
||||
template<> inline
|
||||
bool V8ValueCanBeConvertedTo<std::string>(v8::Handle<v8::Value> value) {
|
||||
return value->IsString();
|
||||
}
|
||||
|
||||
template<> inline
|
||||
bool V8ValueCanBeConvertedTo<string16>(v8::Handle<v8::Value> value) {
|
||||
return V8ValueCanBeConvertedTo<std::string>(value);
|
||||
}
|
||||
|
||||
template<> inline
|
||||
bool V8ValueCanBeConvertedTo<base::FilePath>(v8::Handle<v8::Value> value) {
|
||||
return V8ValueCanBeConvertedTo<std::string>(value);
|
||||
}
|
||||
|
||||
template<> inline
|
||||
bool V8ValueCanBeConvertedTo<std::vector<std::string>>(
|
||||
v8::Handle<v8::Value> value) {
|
||||
return value->IsArray();
|
||||
}
|
||||
|
||||
template<> inline
|
||||
bool V8ValueCanBeConvertedTo<atom::NativeWindow*>(v8::Handle<v8::Value> value) {
|
||||
using atom::api::Window;
|
||||
if (value->IsObject()) {
|
||||
Window* window = Window::Unwrap<Window>(value->ToObject());
|
||||
if (window && window->window())
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template<> inline
|
||||
bool V8ValueCanBeConvertedTo<v8::Persistent<v8::Function>>(
|
||||
v8::Handle<v8::Value> value) {
|
||||
return value->IsFunction();
|
||||
}
|
||||
|
||||
// Check and convert V8's Arguments to native types.
|
||||
template<typename T1> inline
|
||||
bool FromV8Arguments(const v8::Arguments& args, T1* value, int index = 0) {
|
||||
if (!V8ValueCanBeConvertedTo<T1>(args[index]))
|
||||
return false;
|
||||
*value = static_cast<const T1&>(FromV8Value(args[index]));
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename T1, typename T2> inline
|
||||
bool FromV8Arguments(const v8::Arguments& args, T1* a1, T2* a2) {
|
||||
return FromV8Arguments<T1>(args, a1) && FromV8Arguments<T2>(args, a2, 1);
|
||||
}
|
||||
|
||||
template<typename T1, typename T2, typename T3> inline
|
||||
bool FromV8Arguments(const v8::Arguments& args, T1* a1, T2* a2, T3* a3) {
|
||||
return FromV8Arguments<T1, T2>(args, a1, a2) &&
|
||||
FromV8Arguments<T3>(args, a3, 2);
|
||||
}
|
||||
|
||||
template<typename T1, typename T2, typename T3, typename T4> inline
|
||||
bool FromV8Arguments(const v8::Arguments& args,
|
||||
T1* a1,
|
||||
T2* a2,
|
||||
T3* a3,
|
||||
T4* a4) {
|
||||
return FromV8Arguments<T1, T2, T3>(args, a1, a2, a3) &&
|
||||
FromV8Arguments<T4>(args, a4, 3);
|
||||
}
|
||||
|
||||
template<typename T1, typename T2, typename T3, typename T4, typename T5> inline
|
||||
bool FromV8Arguments(const v8::Arguments& args,
|
||||
T1* a1,
|
||||
T2* a2,
|
||||
T3* a3,
|
||||
T4* a4,
|
||||
T5* a5) {
|
||||
return FromV8Arguments<T1, T2, T3, T4>(args, a1, a2, a3, a4) &&
|
||||
FromV8Arguments<T5>(args, a5, 4);
|
||||
}
|
||||
|
||||
template<typename T1, typename T2, typename T3, typename T4, typename T5,
|
||||
typename T6> inline
|
||||
bool FromV8Arguments(const v8::Arguments& args,
|
||||
T1* a1,
|
||||
T2* a2,
|
||||
T3* a3,
|
||||
T4* a4,
|
||||
T5* a5,
|
||||
T6* a6) {
|
||||
return FromV8Arguments<T1, T2, T3, T4, T5>(args, a1, a2, a3, a4, a5) &&
|
||||
FromV8Arguments<T6>(args, a6, 5);
|
||||
}
|
||||
|
||||
template<typename T1, typename T2, typename T3, typename T4, typename T5,
|
||||
typename T6, typename T7> inline
|
||||
bool FromV8Arguments(const v8::Arguments& args,
|
||||
T1* a1,
|
||||
T2* a2,
|
||||
T3* a3,
|
||||
T4* a4,
|
||||
T5* a5,
|
||||
T6* a6,
|
||||
T7* a7) {
|
||||
return
|
||||
FromV8Arguments<T1, T2, T3, T4, T5, T6>(args, a1, a2, a3, a4, a5, a6) &&
|
||||
FromV8Arguments<T7>(args, a7, 6);
|
||||
}
|
||||
|
||||
#endif // COMMON_V8_CONVERSIONS_H_
|
|
@ -18,7 +18,7 @@ Emitted when renderer sent a message to the browser.
|
|||
* `routingId` Integer
|
||||
|
||||
Emitted when renderer sent a synchronous message to the browser. The receiver
|
||||
should store the result in `event.result`.
|
||||
should store the result in `event.returnValue`.
|
||||
|
||||
**Note:** Due to the limitation of `EventEmitter`, returning value in the
|
||||
event handler has no effect, so we have to store the result by using the
|
||||
|
|
|
@ -30,7 +30,7 @@ An example of sending synchronous message from renderer to browser:
|
|||
// In browser:
|
||||
var ipc = require('ipc');
|
||||
ipc.on('browser-data-request', function(event, processId, routingId, message) {
|
||||
event.result = 'THIS SOME DATA FROM THE BROWSER';
|
||||
event.returnValue = 'THIS SOME DATA FROM THE BROWSER';
|
||||
});
|
||||
```
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
#include "base/values.h"
|
||||
#include "common/api/api_messages.h"
|
||||
#include "common/v8_conversions.h"
|
||||
#include "content/public/renderer/render_view.h"
|
||||
#include "content/public/renderer/v8_value_converter.h"
|
||||
#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
|
||||
|
@ -47,8 +48,7 @@ v8::Handle<v8::Value> RendererIPC::Send(const v8::Arguments &args) {
|
|||
if (!args[0]->IsString())
|
||||
return node::ThrowTypeError("Bad argument");
|
||||
|
||||
std::string channel(*v8::String::Utf8Value(args[0]));
|
||||
|
||||
string16 channel = FromV8Value(args[0]);
|
||||
RenderView* render_view = GetCurrentRenderView();
|
||||
|
||||
// Convert Arguments to Array, so we can use V8ValueConverter to convert it
|
||||
|
@ -82,7 +82,7 @@ v8::Handle<v8::Value> RendererIPC::SendSync(const v8::Arguments &args) {
|
|||
return node::ThrowTypeError("Bad argument");
|
||||
|
||||
v8::Handle<v8::Context> context = v8::Context::GetCurrent();
|
||||
std::string channel(*v8::String::Utf8Value(args[0]));
|
||||
string16 channel = FromV8Value(args[0]);
|
||||
|
||||
// Convert Arguments to Array, so we can use V8ValueConverter to convert it
|
||||
// to ListValue.
|
||||
|
@ -97,12 +97,12 @@ v8::Handle<v8::Value> RendererIPC::SendSync(const v8::Arguments &args) {
|
|||
|
||||
RenderView* render_view = GetCurrentRenderView();
|
||||
|
||||
base::DictionaryValue result;
|
||||
string16 json;
|
||||
IPC::SyncMessage* message = new AtomViewHostMsg_Message_Sync(
|
||||
render_view->GetRoutingID(),
|
||||
channel,
|
||||
*static_cast<base::ListValue*>(arguments.get()),
|
||||
&result);
|
||||
&json);
|
||||
// Enable the UI thread in browser to receive messages.
|
||||
message->EnableMessagePumping();
|
||||
bool success = render_view->Send(message);
|
||||
|
@ -110,7 +110,7 @@ v8::Handle<v8::Value> RendererIPC::SendSync(const v8::Arguments &args) {
|
|||
if (!success)
|
||||
return node::ThrowError("Unable to send AtomViewHostMsg_Message_Sync");
|
||||
|
||||
return scope.Close(converter->ToV8Value(&result, context));
|
||||
return scope.Close(ToV8Value(json));
|
||||
}
|
||||
|
||||
// static
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
#include "base/logging.h"
|
||||
#include "base/values.h"
|
||||
#include "common/v8_conversions.h"
|
||||
#include "content/public/renderer/render_view.h"
|
||||
#include "content/public/renderer/v8_value_converter.h"
|
||||
#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
|
||||
|
@ -51,7 +52,7 @@ void AtomRendererBindings::BindToFrame(WebFrame* frame) {
|
|||
AtomBindings::BindTo(GetProcessObject(context));
|
||||
}
|
||||
|
||||
void AtomRendererBindings::OnBrowserMessage(const std::string& channel,
|
||||
void AtomRendererBindings::OnBrowserMessage(const string16& channel,
|
||||
const base::ListValue& args) {
|
||||
if (!render_view_->GetWebView())
|
||||
return;
|
||||
|
@ -70,7 +71,7 @@ void AtomRendererBindings::OnBrowserMessage(const std::string& channel,
|
|||
|
||||
std::vector<v8::Handle<v8::Value>> arguments;
|
||||
arguments.reserve(1 + args.GetSize());
|
||||
arguments.push_back(v8::String::New(channel.c_str(), channel.size()));
|
||||
arguments.push_back(ToV8Value(channel));
|
||||
|
||||
for (size_t i = 0; i < args.GetSize(); i++) {
|
||||
const base::Value* value;
|
||||
|
|
|
@ -5,10 +5,10 @@
|
|||
#ifndef ATOM_RENDERER_API_ATOM_RENDERER_BINDINGS_H_
|
||||
#define ATOM_RENDERER_API_ATOM_RENDERER_BINDINGS_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "common/api/atom_bindings.h"
|
||||
|
||||
#include "base/string16.h"
|
||||
|
||||
namespace base {
|
||||
class ListValue;
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ class AtomRendererBindings : public AtomBindings {
|
|||
void BindToFrame(WebKit::WebFrame* frame);
|
||||
|
||||
// Dispatch messages from browser.
|
||||
void OnBrowserMessage(const std::string& channel,
|
||||
void OnBrowserMessage(const string16& channel,
|
||||
const base::ListValue& args);
|
||||
|
||||
private:
|
||||
|
|
|
@ -16,9 +16,11 @@ class Ipc extends EventEmitter
|
|||
ipc.send('ATOM_INTERNAL_MESSAGE', args...)
|
||||
|
||||
sendSync: (args...) ->
|
||||
ipc.sendSync('ATOM_INTERNAL_MESSAGE_SYNC', 'sync-message', args...).result
|
||||
msg = ipc.sendSync('ATOM_INTERNAL_MESSAGE_SYNC', 'sync-message', args...)
|
||||
JSON.parse(msg)
|
||||
|
||||
sendChannelSync: (args...) ->
|
||||
ipc.sendSync('ATOM_INTERNAL_MESSAGE_SYNC', args...).result
|
||||
msg = ipc.sendSync('ATOM_INTERNAL_MESSAGE_SYNC', args...)
|
||||
JSON.parse(msg)
|
||||
|
||||
module.exports = new Ipc
|
||||
|
|
|
@ -72,6 +72,7 @@ metaToValue = (meta) ->
|
|||
ret.__defineSetter__ member.name, (value) ->
|
||||
# Set member data.
|
||||
ipc.sendChannelSync 'ATOM_BROWSER_MEMBER_SET', meta.id, member.name, value
|
||||
value
|
||||
|
||||
ret.__defineGetter__ member.name, ->
|
||||
# Get member data.
|
||||
|
|
|
@ -101,7 +101,7 @@ bool AtomRenderViewObserver::OnMessageReceived(const IPC::Message& message) {
|
|||
return handled;
|
||||
}
|
||||
|
||||
void AtomRenderViewObserver::OnBrowserMessage(const std::string& channel,
|
||||
void AtomRenderViewObserver::OnBrowserMessage(const string16& channel,
|
||||
const base::ListValue& args) {
|
||||
atom_bindings()->OnBrowserMessage(channel, args);
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ class AtomRenderViewObserver : content::RenderViewObserver {
|
|||
virtual void DraggableRegionsChanged(WebKit::WebFrame* frame) OVERRIDE;
|
||||
virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
|
||||
|
||||
void OnBrowserMessage(const std::string& channel,
|
||||
void OnBrowserMessage(const string16& channel,
|
||||
const base::ListValue& args);
|
||||
|
||||
scoped_ptr<AtomRendererBindings> atom_bindings_;
|
||||
|
|
|
@ -49,7 +49,12 @@ describe 'ipc', ->
|
|||
describe 'ipc.send', ->
|
||||
it 'should work when sending an object containing id property', (done) ->
|
||||
obj = id: 1, name: 'ly'
|
||||
ipc.on 'message', (message) ->
|
||||
ipc.once 'message', (message) ->
|
||||
assert.deepEqual message, obj
|
||||
done()
|
||||
ipc.send obj
|
||||
|
||||
describe 'ipc.sendSync', ->
|
||||
it 'can be replied by setting event.returnValue', ->
|
||||
msg = ipc.sendChannelSync 'echo', 'test'
|
||||
assert.equal msg, 'test'
|
||||
|
|
|
@ -23,7 +23,11 @@ ipc.on('process.exit', function(pid, rid, code) {
|
|||
});
|
||||
|
||||
ipc.on('eval', function(ev, pid, rid, script) {
|
||||
ev.result = eval(script);
|
||||
ev.returnValue = eval(script);
|
||||
});
|
||||
|
||||
ipc.on('echo', function(ev, pid, rid, msg) {
|
||||
ev.returnValue = msg;
|
||||
});
|
||||
|
||||
process.on('uncaughtException', function() {
|
||||
|
|
Loading…
Reference in a new issue