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.h',
|
||||||
'common/platform_util_mac.mm',
|
'common/platform_util_mac.mm',
|
||||||
'common/platform_util_win.cc',
|
'common/platform_util_win.cc',
|
||||||
|
'common/v8_conversions.h',
|
||||||
'common/v8_value_converter_impl.cc',
|
'common/v8_value_converter_impl.cc',
|
||||||
'common/v8_value_converter_impl.h',
|
'common/v8_value_converter_impl.h',
|
||||||
'renderer/api/atom_api_renderer_ipc.cc',
|
'renderer/api/atom_api_renderer_ipc.cc',
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include "base/values.h"
|
#include "base/values.h"
|
||||||
#include "base/command_line.h"
|
#include "base/command_line.h"
|
||||||
#include "browser/browser.h"
|
#include "browser/browser.h"
|
||||||
|
#include "common/v8_conversions.h"
|
||||||
#include "vendor/node/src/node.h"
|
#include "vendor/node/src/node.h"
|
||||||
|
|
||||||
namespace atom {
|
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::Handle<v8::Value> App::AppendSwitch(const v8::Arguments &args) {
|
||||||
v8::HandleScope scope;
|
v8::HandleScope scope;
|
||||||
|
|
||||||
if (!args[0]->IsString())
|
std::string switch_string;
|
||||||
|
if (!FromV8Arguments(args, &switch_string))
|
||||||
return node::ThrowError("Bad argument");
|
return node::ThrowError("Bad argument");
|
||||||
|
|
||||||
std::string switch_string(*v8::String::Utf8Value(args[0]));
|
|
||||||
if (args.Length() == 1) {
|
if (args.Length() == 1) {
|
||||||
CommandLine::ForCurrentProcess()->AppendSwitch(switch_string);
|
CommandLine::ForCurrentProcess()->AppendSwitch(switch_string);
|
||||||
} else {
|
} else {
|
||||||
std::string value(*v8::String::Utf8Value(args[1]));
|
std::string value = FromV8Value(args[1]);
|
||||||
CommandLine::ForCurrentProcess()->AppendSwitchASCII(
|
CommandLine::ForCurrentProcess()->AppendSwitchASCII(
|
||||||
switch_string, value);
|
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::Handle<v8::Value> App::AppendArgument(const v8::Arguments &args) {
|
||||||
v8::HandleScope scope;
|
v8::HandleScope scope;
|
||||||
|
|
||||||
if (!args[0]->IsString())
|
std::string value;
|
||||||
|
if (!FromV8Arguments(args, &value))
|
||||||
return node::ThrowError("Bad argument");
|
return node::ThrowError("Bad argument");
|
||||||
|
|
||||||
std::string value(*v8::String::Utf8Value(args[0]));
|
|
||||||
CommandLine::ForCurrentProcess()->AppendArg(value);
|
CommandLine::ForCurrentProcess()->AppendArg(value);
|
||||||
|
|
||||||
return v8::Undefined();
|
return v8::Undefined();
|
||||||
|
@ -143,7 +144,7 @@ v8::Handle<v8::Value> App::AppendArgument(const v8::Arguments &args) {
|
||||||
|
|
||||||
// static
|
// static
|
||||||
v8::Handle<v8::Value> App::DockBounce(const v8::Arguments& args) {
|
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;
|
int request_id = -1;
|
||||||
|
|
||||||
if (type == "critical")
|
if (type == "critical")
|
||||||
|
@ -158,21 +159,20 @@ v8::Handle<v8::Value> App::DockBounce(const v8::Arguments& args) {
|
||||||
|
|
||||||
// static
|
// static
|
||||||
v8::Handle<v8::Value> App::DockCancelBounce(const v8::Arguments& args) {
|
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();
|
return v8::Undefined();
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
v8::Handle<v8::Value> App::DockSetBadgeText(const v8::Arguments& args) {
|
v8::Handle<v8::Value> App::DockSetBadgeText(const v8::Arguments& args) {
|
||||||
std::string label(*v8::String::Utf8Value(args[0]));
|
Browser::Get()->DockSetBadgeText(FromV8Value(args[0]));
|
||||||
Browser::Get()->DockSetBadgeText(label);
|
|
||||||
return v8::Undefined();
|
return v8::Undefined();
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
v8::Handle<v8::Value> App::DockGetBadgeText(const v8::Arguments& args) {
|
v8::Handle<v8::Value> App::DockGetBadgeText(const v8::Arguments& args) {
|
||||||
std::string text(Browser::Get()->DockGetBadgeText());
|
std::string text(Browser::Get()->DockGetBadgeText());
|
||||||
return v8::String::New(text.data(), text.size());
|
return ToV8Value(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // defined(OS_MACOSX)
|
#endif // defined(OS_MACOSX)
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
#include "base/values.h"
|
#include "base/values.h"
|
||||||
#include "browser/auto_updater.h"
|
#include "browser/auto_updater.h"
|
||||||
|
#include "common/v8_conversions.h"
|
||||||
|
|
||||||
namespace atom {
|
namespace atom {
|
||||||
|
|
||||||
|
@ -56,7 +57,7 @@ v8::Handle<v8::Value> AutoUpdater::New(const v8::Arguments &args) {
|
||||||
|
|
||||||
// static
|
// static
|
||||||
v8::Handle<v8::Value> AutoUpdater::SetFeedURL(const v8::Arguments &args) {
|
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();
|
return v8::Undefined();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
#include "base/values.h"
|
#include "base/values.h"
|
||||||
#include "common/api/api_messages.h"
|
#include "common/api/api_messages.h"
|
||||||
|
#include "common/v8_conversions.h"
|
||||||
#include "common/v8_value_converter_impl.h"
|
#include "common/v8_value_converter_impl.h"
|
||||||
#include "content/public/browser/render_view_host.h"
|
#include "content/public/browser/render_view_host.h"
|
||||||
#include "vendor/node/src/node.h"
|
#include "vendor/node/src/node.h"
|
||||||
|
@ -22,13 +23,11 @@ namespace api {
|
||||||
v8::Handle<v8::Value> BrowserIPC::Send(const v8::Arguments &args) {
|
v8::Handle<v8::Value> BrowserIPC::Send(const v8::Arguments &args) {
|
||||||
v8::HandleScope scope;
|
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");
|
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(
|
RenderViewHost* render_view_host(RenderViewHost::FromID(
|
||||||
process_id, routing_id));
|
process_id, routing_id));
|
||||||
if (!render_view_host)
|
if (!render_view_host)
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include "browser/api/atom_api_crash_reporter.h"
|
#include "browser/api/atom_api_crash_reporter.h"
|
||||||
|
|
||||||
#include "browser/crash_reporter.h"
|
#include "browser/crash_reporter.h"
|
||||||
|
#include "common/v8_conversions.h"
|
||||||
#include "vendor/node/src/node.h"
|
#include "vendor/node/src/node.h"
|
||||||
#include "vendor/node/src/node_internals.h"
|
#include "vendor/node/src/node_internals.h"
|
||||||
|
|
||||||
|
@ -14,22 +15,20 @@ namespace api {
|
||||||
|
|
||||||
// static
|
// static
|
||||||
v8::Handle<v8::Value> CrashReporter::SetCompanyName(const v8::Arguments &args) {
|
v8::Handle<v8::Value> CrashReporter::SetCompanyName(const v8::Arguments &args) {
|
||||||
std::string name(*v8::String::Utf8Value(args[0]));
|
crash_reporter::CrashReporter::SetCompanyName(FromV8Value(args[0]));
|
||||||
crash_reporter::CrashReporter::SetCompanyName(name);
|
|
||||||
return v8::Undefined();
|
return v8::Undefined();
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
v8::Handle<v8::Value> CrashReporter::SetSubmissionURL(
|
v8::Handle<v8::Value> CrashReporter::SetSubmissionURL(
|
||||||
const v8::Arguments &args) {
|
const v8::Arguments &args) {
|
||||||
std::string url(*v8::String::Utf8Value(args[0]));
|
crash_reporter::CrashReporter::SetSubmissionURL(FromV8Value(args[0]));
|
||||||
crash_reporter::CrashReporter::SetSubmissionURL(url);
|
|
||||||
return v8::Undefined();
|
return v8::Undefined();
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
v8::Handle<v8::Value> CrashReporter::SetAutoSubmit(const v8::Arguments &args) {
|
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();
|
return v8::Undefined();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,14 +4,14 @@
|
||||||
|
|
||||||
#include "browser/api/atom_api_dialog.h"
|
#include "browser/api/atom_api_dialog.h"
|
||||||
|
|
||||||
#include <string>
|
#include "base/bind.h"
|
||||||
|
|
||||||
#include "base/utf_string_conversions.h"
|
|
||||||
#include "base/values.h"
|
|
||||||
#include "browser/api/atom_api_window.h"
|
|
||||||
#include "browser/native_window.h"
|
#include "browser/native_window.h"
|
||||||
#include "browser/ui/file_dialog.h"
|
#include "browser/ui/file_dialog.h"
|
||||||
#include "browser/ui/message_box.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 {
|
namespace atom {
|
||||||
|
|
||||||
|
@ -19,14 +19,24 @@ namespace api {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
base::FilePath V8ValueToFilePath(v8::Handle<v8::Value> path) {
|
template<typename T>
|
||||||
std::string path_string(*v8::String::Utf8Value(path));
|
void CallV8Function(v8::Persistent<v8::Function> callback, T arg) {
|
||||||
return base::FilePath::FromUTF8Unsafe(path_string);
|
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) {
|
template<typename T>
|
||||||
std::string path_string(path.AsUTF8Unsafe());
|
void CallV8Function2(v8::Persistent<v8::Function> callback,
|
||||||
return v8::String::New(path_string.data(), path_string.size());
|
bool result,
|
||||||
|
T arg) {
|
||||||
|
if (result)
|
||||||
|
return CallV8Function<T>(callback, arg);
|
||||||
|
else
|
||||||
|
return CallV8Function<void*>(callback, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Initialize(v8::Handle<v8::Object> target) {
|
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::Handle<v8::Value> ShowMessageBox(const v8::Arguments &args) {
|
||||||
v8::HandleScope scope;
|
v8::HandleScope scope;
|
||||||
|
|
||||||
if (!args[0]->IsNumber() || // type
|
int type;
|
||||||
!args[1]->IsArray() || // buttons
|
std::vector<std::string> buttons;
|
||||||
!args[2]->IsString() || // title
|
std::string title, message, detail;
|
||||||
!args[3]->IsString() || // message
|
if (!FromV8Arguments(args, &type, &buttons, &title, &message, &detail))
|
||||||
!args[4]->IsString()) // detail
|
|
||||||
return node::ThrowTypeError("Bad argument");
|
return node::ThrowTypeError("Bad argument");
|
||||||
|
|
||||||
NativeWindow* native_window = NULL;
|
NativeWindow* native_window = FromV8Value(args[5]);
|
||||||
if (args[5]->IsObject()) {
|
v8::Persistent<v8::Function> callback = FromV8Value(args[6]);
|
||||||
Window* window = Window::Unwrap<Window>(args[5]->ToObject());
|
|
||||||
if (!window || !window->window())
|
|
||||||
return node::ThrowError("Invalid window");
|
|
||||||
|
|
||||||
native_window = window->window();
|
|
||||||
}
|
|
||||||
|
|
||||||
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]));
|
|
||||||
|
|
||||||
|
if (callback.IsEmpty()) {
|
||||||
int chosen = atom::ShowMessageBox(
|
int chosen = atom::ShowMessageBox(
|
||||||
native_window, type, buttons, title, message, detail);
|
native_window,
|
||||||
|
(MessageBoxType)type,
|
||||||
|
buttons,
|
||||||
|
title,
|
||||||
|
message,
|
||||||
|
detail);
|
||||||
return scope.Close(v8::Integer::New(chosen));
|
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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
v8::Handle<v8::Value> ShowOpenDialog(const v8::Arguments &args) {
|
v8::Handle<v8::Value> ShowOpenDialog(const v8::Arguments &args) {
|
||||||
v8::HandleScope scope;
|
v8::HandleScope scope;
|
||||||
|
|
||||||
if (!args[0]->IsString() || // title
|
std::string title;
|
||||||
!args[1]->IsString() || // default_path
|
base::FilePath default_path;
|
||||||
!args[2]->IsNumber()) // properties
|
int properties;
|
||||||
|
if (!FromV8Arguments(args, &title, &default_path, &properties))
|
||||||
return node::ThrowTypeError("Bad argument");
|
return node::ThrowTypeError("Bad argument");
|
||||||
|
|
||||||
std::string title(*v8::String::Utf8Value(args[0]));
|
NativeWindow* native_window = FromV8Value(args[3]);
|
||||||
base::FilePath default_path(V8ValueToFilePath(args[1]));
|
v8::Persistent<v8::Function> callback = FromV8Value(args[4]);
|
||||||
int properties = args[2]->IntegerValue();
|
|
||||||
|
|
||||||
|
if (callback.IsEmpty()) {
|
||||||
std::vector<base::FilePath> paths;
|
std::vector<base::FilePath> paths;
|
||||||
if (!file_dialog::ShowOpenDialog(title, default_path, properties, &paths))
|
if (!file_dialog::ShowOpenDialog(native_window,
|
||||||
|
title,
|
||||||
|
default_path,
|
||||||
|
properties,
|
||||||
|
&paths))
|
||||||
return v8::Undefined();
|
return v8::Undefined();
|
||||||
|
|
||||||
v8::Handle<v8::Array> result = v8::Array::New(paths.size());
|
v8::Handle<v8::Array> result = v8::Array::New(paths.size());
|
||||||
for (size_t i = 0; i < paths.size(); ++i)
|
for (size_t i = 0; i < paths.size(); ++i)
|
||||||
result->Set(i, FilePathToV8Value(paths[i]));
|
result->Set(i, ToV8Value(paths[i]));
|
||||||
|
|
||||||
return scope.Close(result);
|
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::Value> ShowSaveDialog(const v8::Arguments &args) {
|
v8::Handle<v8::Value> ShowSaveDialog(const v8::Arguments &args) {
|
||||||
v8::HandleScope scope;
|
v8::HandleScope scope;
|
||||||
|
|
||||||
if (!args[0]->IsObject() || // window
|
std::string title;
|
||||||
!args[1]->IsString() || // title
|
base::FilePath default_path;
|
||||||
!args[2]->IsString()) // default_path
|
if (!FromV8Arguments(args, &title, &default_path))
|
||||||
return node::ThrowTypeError("Bad argument");
|
return node::ThrowTypeError("Bad argument");
|
||||||
|
|
||||||
Window* window = Window::Unwrap<Window>(args[0]->ToObject());
|
NativeWindow* native_window = FromV8Value(args[2]);
|
||||||
if (!window || !window->window())
|
v8::Persistent<v8::Function> callback = FromV8Value(args[3]);
|
||||||
return node::ThrowError("Invalid window");
|
|
||||||
|
|
||||||
std::string title(*v8::String::Utf8Value(args[1]));
|
|
||||||
base::FilePath default_path(V8ValueToFilePath(args[2]));
|
|
||||||
|
|
||||||
|
if (callback.IsEmpty()) {
|
||||||
base::FilePath path;
|
base::FilePath path;
|
||||||
if (!file_dialog::ShowSaveDialog(window->window(),
|
if (!file_dialog::ShowSaveDialog(native_window,
|
||||||
title,
|
title,
|
||||||
default_path,
|
default_path,
|
||||||
&path))
|
&path))
|
||||||
return v8::Undefined();
|
return v8::Undefined();
|
||||||
|
|
||||||
return scope.Close(FilePathToV8Value(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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace api
|
} // namespace api
|
||||||
|
|
|
@ -4,6 +4,10 @@
|
||||||
|
|
||||||
#include "browser/api/atom_api_event.h"
|
#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;
|
using node::node_isolate;
|
||||||
|
|
||||||
namespace atom {
|
namespace atom {
|
||||||
|
@ -13,10 +17,14 @@ namespace api {
|
||||||
v8::Persistent<v8::FunctionTemplate> Event::constructor_template_;
|
v8::Persistent<v8::FunctionTemplate> Event::constructor_template_;
|
||||||
|
|
||||||
Event::Event()
|
Event::Event()
|
||||||
: prevent_default_(false) {
|
: sender_(NULL),
|
||||||
|
message_(NULL),
|
||||||
|
prevent_default_(false) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Event::~Event() {
|
Event::~Event() {
|
||||||
|
if (sender_)
|
||||||
|
sender_->RemoveObserver(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
|
@ -31,6 +39,7 @@ v8::Handle<v8::Object> Event::CreateV8Object() {
|
||||||
constructor_template_->SetClassName(v8::String::NewSymbol("Event"));
|
constructor_template_->SetClassName(v8::String::NewSymbol("Event"));
|
||||||
|
|
||||||
NODE_SET_PROTOTYPE_METHOD(t, "preventDefault", PreventDefault);
|
NODE_SET_PROTOTYPE_METHOD(t, "preventDefault", PreventDefault);
|
||||||
|
NODE_SET_PROTOTYPE_METHOD(t, "sendReply", SendReply);
|
||||||
}
|
}
|
||||||
|
|
||||||
v8::Handle<v8::Object> v8_event =
|
v8::Handle<v8::Object> v8_event =
|
||||||
|
@ -39,14 +48,30 @@ v8::Handle<v8::Object> Event::CreateV8Object() {
|
||||||
return scope.Close(v8_event);
|
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* event = new Event;
|
||||||
event->Wrap(args.This());
|
event->Wrap(args.This());
|
||||||
|
|
||||||
return 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());
|
Event* event = Unwrap<Event>(args.This());
|
||||||
if (event == NULL)
|
if (event == NULL)
|
||||||
return node::ThrowError("Event is already destroyed");
|
return node::ThrowError("Event is already destroyed");
|
||||||
|
@ -56,6 +81,24 @@ v8::Handle<v8::Value> Event::PreventDefault(const v8::Arguments &args) {
|
||||||
return v8::Undefined();
|
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 api
|
||||||
|
|
||||||
} // namespace atom
|
} // namespace atom
|
||||||
|
|
|
@ -6,19 +6,32 @@
|
||||||
#define ATOM_BROWSER_ATOM_API_EVENT_H_
|
#define ATOM_BROWSER_ATOM_API_EVENT_H_
|
||||||
|
|
||||||
#include "base/basictypes.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"
|
#include "vendor/node/src/node_object_wrap.h"
|
||||||
|
|
||||||
|
namespace IPC {
|
||||||
|
class Message;
|
||||||
|
}
|
||||||
|
|
||||||
namespace atom {
|
namespace atom {
|
||||||
|
|
||||||
|
class NativeWindow;
|
||||||
|
|
||||||
namespace api {
|
namespace api {
|
||||||
|
|
||||||
class Event : public node::ObjectWrap {
|
class Event : public node::ObjectWrap,
|
||||||
|
public NativeWindowObserver {
|
||||||
public:
|
public:
|
||||||
virtual ~Event();
|
virtual ~Event();
|
||||||
|
|
||||||
// Create a V8 Event object.
|
// Create a V8 Event object.
|
||||||
static v8::Handle<v8::Object> CreateV8Object();
|
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.
|
// Accessor to return handle_, this follows Google C++ Style.
|
||||||
v8::Persistent<v8::Object>& handle() { return handle_; }
|
v8::Persistent<v8::Object>& handle() { return handle_; }
|
||||||
|
|
||||||
|
@ -28,12 +41,21 @@ class Event : public node::ObjectWrap {
|
||||||
protected:
|
protected:
|
||||||
Event();
|
Event();
|
||||||
|
|
||||||
|
// NativeWindowObserver implementations:
|
||||||
|
virtual void OnWindowClosed() OVERRIDE;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static v8::Handle<v8::Value> New(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> PreventDefault(const v8::Arguments& args);
|
||||||
|
static v8::Handle<v8::Value> SendReply(const v8::Arguments& args);
|
||||||
|
|
||||||
static v8::Persistent<v8::FunctionTemplate> constructor_template_;
|
static v8::Persistent<v8::FunctionTemplate> constructor_template_;
|
||||||
|
|
||||||
|
// Replyer for the synchronous messages.
|
||||||
|
NativeWindow* sender_;
|
||||||
|
IPC::Message* message_;
|
||||||
|
|
||||||
bool prevent_default_;
|
bool prevent_default_;
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(Event);
|
DISALLOW_COPY_AND_ASSIGN(Event);
|
||||||
|
|
|
@ -4,8 +4,8 @@
|
||||||
|
|
||||||
#include "browser/api/atom_api_menu.h"
|
#include "browser/api/atom_api_menu.h"
|
||||||
|
|
||||||
#include "browser/api/atom_api_window.h"
|
|
||||||
#include "browser/ui/accelerator_util.h"
|
#include "browser/ui/accelerator_util.h"
|
||||||
|
#include "common/v8_conversions.h"
|
||||||
|
|
||||||
#define UNWRAP_MEMNU_AND_CHECK \
|
#define UNWRAP_MEMNU_AND_CHECK \
|
||||||
Menu* self = ObjectWrap::Unwrap<Menu>(args.This()); \
|
Menu* self = ObjectWrap::Unwrap<Menu>(args.This()); \
|
||||||
|
@ -18,17 +18,6 @@ namespace api {
|
||||||
|
|
||||||
namespace {
|
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.
|
// Call method of delegate object.
|
||||||
v8::Handle<v8::Value> CallDelegate(v8::Handle<v8::Value> default_value,
|
v8::Handle<v8::Value> CallDelegate(v8::Handle<v8::Value> default_value,
|
||||||
v8::Handle<v8::Object> menu,
|
v8::Handle<v8::Object> menu,
|
||||||
|
@ -93,7 +82,7 @@ bool Menu::GetAcceleratorForCommandId(int command_id,
|
||||||
"getAcceleratorForCommandId",
|
"getAcceleratorForCommandId",
|
||||||
command_id);
|
command_id);
|
||||||
if (shortcut->IsString()) {
|
if (shortcut->IsString()) {
|
||||||
std::string shortcut_str(*v8::String::Utf8Value(shortcut));
|
std::string shortcut_str = FromV8Value(shortcut);
|
||||||
return accelerator_util::StringToAccelerator(shortcut_str, accelerator);
|
return accelerator_util::StringToAccelerator(shortcut_str, accelerator);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,7 +99,7 @@ bool Menu::IsItemForCommandIdDynamic(int command_id) const {
|
||||||
|
|
||||||
string16 Menu::GetLabelForCommandId(int command_id) const {
|
string16 Menu::GetLabelForCommandId(int command_id) const {
|
||||||
v8::HandleScope scope;
|
v8::HandleScope scope;
|
||||||
return V8ValueToUTF16(CallDelegate(v8::False(),
|
return FromV8Value(CallDelegate(v8::False(),
|
||||||
handle(),
|
handle(),
|
||||||
"getLabelForCommandId",
|
"getLabelForCommandId",
|
||||||
command_id));
|
command_id));
|
||||||
|
@ -118,7 +107,7 @@ string16 Menu::GetLabelForCommandId(int command_id) const {
|
||||||
|
|
||||||
string16 Menu::GetSublabelForCommandId(int command_id) const {
|
string16 Menu::GetSublabelForCommandId(int command_id) const {
|
||||||
v8::HandleScope scope;
|
v8::HandleScope scope;
|
||||||
return V8ValueToUTF16(CallDelegate(v8::False(),
|
return FromV8Value(CallDelegate(v8::False(),
|
||||||
handle(),
|
handle(),
|
||||||
"getSubLabelForCommandId",
|
"getSubLabelForCommandId",
|
||||||
command_id));
|
command_id));
|
||||||
|
@ -145,16 +134,15 @@ v8::Handle<v8::Value> Menu::New(const v8::Arguments &args) {
|
||||||
v8::Handle<v8::Value> Menu::InsertItem(const v8::Arguments &args) {
|
v8::Handle<v8::Value> Menu::InsertItem(const v8::Arguments &args) {
|
||||||
UNWRAP_MEMNU_AND_CHECK;
|
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");
|
return node::ThrowTypeError("Bad argument");
|
||||||
|
|
||||||
int index = args[0]->IntegerValue();
|
|
||||||
|
|
||||||
if (index < 0)
|
if (index < 0)
|
||||||
self->model_->AddItem(args[1]->IntegerValue(), V8ValueToUTF16(args[2]));
|
self->model_->AddItem(command_id, label);
|
||||||
else
|
else
|
||||||
self->model_->InsertItemAt(
|
self->model_->InsertItemAt(index, command_id, label);
|
||||||
index, args[1]->IntegerValue(), V8ValueToUTF16(args[2]));
|
|
||||||
|
|
||||||
return v8::Undefined();
|
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) {
|
v8::Handle<v8::Value> Menu::InsertCheckItem(const v8::Arguments &args) {
|
||||||
UNWRAP_MEMNU_AND_CHECK;
|
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");
|
return node::ThrowTypeError("Bad argument");
|
||||||
|
|
||||||
int index = args[0]->IntegerValue();
|
|
||||||
int command_id = args[1]->IntegerValue();
|
|
||||||
|
|
||||||
if (index < 0)
|
if (index < 0)
|
||||||
self->model_->AddCheckItem(command_id, V8ValueToUTF16(args[2]));
|
self->model_->AddCheckItem(command_id, label);
|
||||||
else
|
else
|
||||||
self->model_->InsertCheckItemAt(index, command_id, V8ValueToUTF16(args[2]));
|
self->model_->InsertCheckItemAt(index, command_id, label);
|
||||||
|
|
||||||
return v8::Undefined();
|
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) {
|
v8::Handle<v8::Value> Menu::InsertRadioItem(const v8::Arguments &args) {
|
||||||
UNWRAP_MEMNU_AND_CHECK;
|
UNWRAP_MEMNU_AND_CHECK;
|
||||||
|
|
||||||
if (!args[0]->IsNumber() ||
|
int index, command_id, group_id;
|
||||||
!args[1]->IsNumber() ||
|
string16 label;
|
||||||
!args[2]->IsString() ||
|
if (!FromV8Arguments(args, &index, &command_id, &label, &group_id))
|
||||||
!args[3]->IsNumber())
|
|
||||||
return node::ThrowTypeError("Bad argument");
|
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)
|
if (index < 0)
|
||||||
self->model_->AddRadioItem(command_id, V8ValueToUTF16(args[2]), group_id);
|
self->model_->AddRadioItem(command_id, label, group_id);
|
||||||
else
|
else
|
||||||
self->model_->InsertRadioItemAt(
|
self->model_->InsertRadioItemAt(index, command_id, label, group_id);
|
||||||
index, command_id, V8ValueToUTF16(args[2]), group_id);
|
|
||||||
|
|
||||||
return v8::Undefined();
|
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) {
|
v8::Handle<v8::Value> Menu::InsertSeparator(const v8::Arguments &args) {
|
||||||
UNWRAP_MEMNU_AND_CHECK;
|
UNWRAP_MEMNU_AND_CHECK;
|
||||||
|
|
||||||
if (!args[0]->IsNumber())
|
int index;
|
||||||
|
if (!FromV8Arguments(args, &index))
|
||||||
return node::ThrowTypeError("Bad argument");
|
return node::ThrowTypeError("Bad argument");
|
||||||
|
|
||||||
int index = args[0]->IntegerValue();
|
|
||||||
|
|
||||||
if (index < 0)
|
if (index < 0)
|
||||||
self->model_->AddSeparator(ui::NORMAL_SEPARATOR);
|
self->model_->AddSeparator(ui::NORMAL_SEPARATOR);
|
||||||
else
|
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) {
|
v8::Handle<v8::Value> Menu::InsertSubMenu(const v8::Arguments &args) {
|
||||||
UNWRAP_MEMNU_AND_CHECK;
|
UNWRAP_MEMNU_AND_CHECK;
|
||||||
|
|
||||||
if (!args[0]->IsNumber() ||
|
int index, command_id;
|
||||||
!args[1]->IsNumber() ||
|
string16 label;
|
||||||
!args[2]->IsString() ||
|
if (!FromV8Arguments(args, &index, &command_id, &label))
|
||||||
!args[3]->IsObject())
|
|
||||||
return node::ThrowTypeError("Bad argument");
|
return node::ThrowTypeError("Bad argument");
|
||||||
|
|
||||||
Menu* submenu = ObjectWrap::Unwrap<Menu>(args[3]->ToObject());
|
Menu* submenu = ObjectWrap::Unwrap<Menu>(args[3]->ToObject());
|
||||||
if (!submenu)
|
if (!submenu)
|
||||||
return node::ThrowTypeError("The submenu is already destroyed");
|
return node::ThrowTypeError("The submenu is already destroyed");
|
||||||
|
|
||||||
int index = args[0]->IntegerValue();
|
|
||||||
int command_id = args[1]->IntegerValue();
|
|
||||||
|
|
||||||
if (index < 0)
|
if (index < 0)
|
||||||
self->model_->AddSubMenu(
|
self->model_->AddSubMenu(command_id, label, submenu->model_.get());
|
||||||
command_id, V8ValueToUTF16(args[2]), submenu->model_.get());
|
|
||||||
else
|
else
|
||||||
self->model_->InsertSubMenuAt(
|
self->model_->InsertSubMenuAt(
|
||||||
index, command_id, V8ValueToUTF16(args[2]), submenu->model_.get());
|
index, command_id, label, submenu->model_.get());
|
||||||
|
|
||||||
return v8::Undefined();
|
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) {
|
v8::Handle<v8::Value> Menu::SetIcon(const v8::Arguments &args) {
|
||||||
UNWRAP_MEMNU_AND_CHECK;
|
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");
|
return node::ThrowTypeError("Bad argument");
|
||||||
|
|
||||||
// FIXME use webkit_glue's image decoder here.
|
// 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) {
|
v8::Handle<v8::Value> Menu::SetSublabel(const v8::Arguments &args) {
|
||||||
UNWRAP_MEMNU_AND_CHECK;
|
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");
|
return node::ThrowTypeError("Bad argument");
|
||||||
|
|
||||||
self->model_->SetSublabel(args[0]->IntegerValue(), V8ValueToUTF16(args[1]));
|
self->model_->SetSublabel(index, label);
|
||||||
|
|
||||||
return v8::Undefined();
|
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) {
|
v8::Handle<v8::Value> Menu::GetLabelAt(const v8::Arguments &args) {
|
||||||
UNWRAP_MEMNU_AND_CHECK;
|
UNWRAP_MEMNU_AND_CHECK;
|
||||||
int index = args[0]->IntegerValue();
|
int index = args[0]->IntegerValue();
|
||||||
return UTF16ToV8Value(self->model_->GetLabelAt(index));
|
return ToV8Value(self->model_->GetLabelAt(index));
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
v8::Handle<v8::Value> Menu::GetSublabelAt(const v8::Arguments &args) {
|
v8::Handle<v8::Value> Menu::GetSublabelAt(const v8::Arguments &args) {
|
||||||
UNWRAP_MEMNU_AND_CHECK;
|
UNWRAP_MEMNU_AND_CHECK;
|
||||||
int index = args[0]->IntegerValue();
|
int index = args[0]->IntegerValue();
|
||||||
return UTF16ToV8Value(self->model_->GetSublabelAt(index));
|
return ToV8Value(self->model_->GetSublabelAt(index));
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// 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) {
|
v8::Handle<v8::Value> Menu::Popup(const v8::Arguments &args) {
|
||||||
UNWRAP_MEMNU_AND_CHECK;
|
UNWRAP_MEMNU_AND_CHECK;
|
||||||
|
|
||||||
Window* window = Window::Unwrap<Window>(args[0]->ToObject());
|
atom::NativeWindow* window;
|
||||||
if (!window)
|
if (!FromV8Arguments(args, &window))
|
||||||
return node::ThrowTypeError("Invalid window");
|
return node::ThrowTypeError("Bad argument");
|
||||||
|
|
||||||
self->Popup(window->window());
|
self->Popup(window);
|
||||||
return v8::Undefined();
|
return v8::Undefined();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include "base/mac/scoped_sending_event.h"
|
#include "base/mac/scoped_sending_event.h"
|
||||||
#include "base/strings/sys_string_conversions.h"
|
#include "base/strings/sys_string_conversions.h"
|
||||||
#include "browser/native_window.h"
|
#include "browser/native_window.h"
|
||||||
|
#include "common/v8_conversions.h"
|
||||||
#include "content/public/browser/web_contents.h"
|
#include "content/public/browser/web_contents.h"
|
||||||
#include "content/public/browser/web_contents_view.h"
|
#include "content/public/browser/web_contents_view.h"
|
||||||
|
|
||||||
|
@ -95,10 +96,10 @@ v8::Handle<v8::Value> Menu::SendActionToFirstResponder(
|
||||||
const v8::Arguments &args) {
|
const v8::Arguments &args) {
|
||||||
v8::HandleScope scope;
|
v8::HandleScope scope;
|
||||||
|
|
||||||
if (!args[0]->IsString())
|
std::string action;
|
||||||
|
if (!FromV8Arguments(args, &action))
|
||||||
return node::ThrowTypeError("Bad argument");
|
return node::ThrowTypeError("Bad argument");
|
||||||
|
|
||||||
std::string action(*v8::String::Utf8Value(args[0]));
|
|
||||||
MenuMac::SendActionToFirstResponder(action);
|
MenuMac::SendActionToFirstResponder(action);
|
||||||
|
|
||||||
return v8::Undefined();
|
return v8::Undefined();
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include "browser/net/adapter_request_job.h"
|
#include "browser/net/adapter_request_job.h"
|
||||||
#include "browser/net/atom_url_request_context_getter.h"
|
#include "browser/net/atom_url_request_context_getter.h"
|
||||||
#include "browser/net/atom_url_request_job_factory.h"
|
#include "browser/net/atom_url_request_job_factory.h"
|
||||||
|
#include "common/v8_conversions.h"
|
||||||
#include "content/public/browser/browser_thread.h"
|
#include "content/public/browser/browser_thread.h"
|
||||||
#include "net/url_request/url_request_context.h"
|
#include "net/url_request/url_request_context.h"
|
||||||
#include "vendor/node/src/node.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) {
|
void EmitEventInUI(const std::string& event, const std::string& parameter) {
|
||||||
v8::HandleScope scope;
|
v8::HandleScope scope;
|
||||||
|
|
||||||
v8::Local<v8::Value> argv[] = {
|
v8::Handle<v8::Value> argv[] = {
|
||||||
v8::String::New(event.data(), event.size()),
|
ToV8Value(event),
|
||||||
v8::String::New(parameter.data(), parameter.size()),
|
ToV8Value(parameter),
|
||||||
};
|
};
|
||||||
node::MakeCallback(g_protocol_object, "emit", arraysize(argv), argv);
|
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.
|
// Determine the type of the job we are going to create.
|
||||||
if (result->IsString()) {
|
if (result->IsString()) {
|
||||||
std::string data = *v8::String::Utf8Value(result);
|
std::string data = FromV8Value(result);
|
||||||
content::BrowserThread::PostTask(
|
content::BrowserThread::PostTask(
|
||||||
content::BrowserThread::IO,
|
content::BrowserThread::IO,
|
||||||
FROM_HERE,
|
FROM_HERE,
|
||||||
|
@ -95,14 +96,12 @@ class CustomProtocolRequestJob : public AdapterRequestJob {
|
||||||
return;
|
return;
|
||||||
} else if (result->IsObject()) {
|
} else if (result->IsObject()) {
|
||||||
v8::Handle<v8::Object> obj = result->ToObject();
|
v8::Handle<v8::Object> obj = result->ToObject();
|
||||||
std::string name = *v8::String::Utf8Value(obj->GetConstructorName());
|
std::string name = FromV8Value(obj->GetConstructorName());
|
||||||
if (name == "RequestStringJob") {
|
if (name == "RequestStringJob") {
|
||||||
std::string mime_type = *v8::String::Utf8Value(obj->Get(
|
std::string mime_type = FromV8Value(obj->Get(
|
||||||
v8::String::New("mimeType")));
|
v8::String::New("mimeType")));
|
||||||
std::string charset = *v8::String::Utf8Value(obj->Get(
|
std::string charset = FromV8Value(obj->Get(v8::String::New("charset")));
|
||||||
v8::String::New("charset")));
|
std::string data = FromV8Value(obj->Get(v8::String::New("data")));
|
||||||
std::string data = *v8::String::Utf8Value(obj->Get(
|
|
||||||
v8::String::New("data")));
|
|
||||||
|
|
||||||
content::BrowserThread::PostTask(
|
content::BrowserThread::PostTask(
|
||||||
content::BrowserThread::IO,
|
content::BrowserThread::IO,
|
||||||
|
@ -114,8 +113,7 @@ class CustomProtocolRequestJob : public AdapterRequestJob {
|
||||||
data));
|
data));
|
||||||
return;
|
return;
|
||||||
} else if (name == "RequestFileJob") {
|
} else if (name == "RequestFileJob") {
|
||||||
base::FilePath path = base::FilePath::FromUTF8Unsafe(
|
base::FilePath path = FromV8Value(obj->Get(v8::String::New("path")));
|
||||||
*v8::String::Utf8Value(obj->Get(v8::String::New("path"))));
|
|
||||||
|
|
||||||
content::BrowserThread::PostTask(
|
content::BrowserThread::PostTask(
|
||||||
content::BrowserThread::IO,
|
content::BrowserThread::IO,
|
||||||
|
@ -183,7 +181,11 @@ class CustomProtocolHandler : public ProtocolHandler {
|
||||||
|
|
||||||
// static
|
// static
|
||||||
v8::Handle<v8::Value> Protocol::RegisterProtocol(const v8::Arguments& args) {
|
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() ||
|
if (g_handlers.find(scheme) != g_handlers.end() ||
|
||||||
net::URLRequest::IsHandledProtocol(scheme))
|
net::URLRequest::IsHandledProtocol(scheme))
|
||||||
return node::ThrowError("The scheme is already registered");
|
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);
|
return node::ThrowError(kEarlyUseProtocolError);
|
||||||
|
|
||||||
// Store the handler in a map.
|
// Store the handler in a map.
|
||||||
if (!args[1]->IsFunction())
|
g_handlers[scheme] = callback;
|
||||||
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]));
|
|
||||||
|
|
||||||
content::BrowserThread::PostTask(content::BrowserThread::IO,
|
content::BrowserThread::PostTask(content::BrowserThread::IO,
|
||||||
FROM_HERE,
|
FROM_HERE,
|
||||||
|
@ -206,7 +205,9 @@ v8::Handle<v8::Value> Protocol::RegisterProtocol(const v8::Arguments& args) {
|
||||||
|
|
||||||
// static
|
// static
|
||||||
v8::Handle<v8::Value> Protocol::UnregisterProtocol(const v8::Arguments& args) {
|
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)
|
if (AtomBrowserContext::Get()->url_request_context_getter() == NULL)
|
||||||
return node::ThrowError(kEarlyUseProtocolError);
|
return node::ThrowError(kEarlyUseProtocolError);
|
||||||
|
@ -226,13 +227,16 @@ v8::Handle<v8::Value> Protocol::UnregisterProtocol(const v8::Arguments& args) {
|
||||||
|
|
||||||
// static
|
// static
|
||||||
v8::Handle<v8::Value> Protocol::IsHandledProtocol(const v8::Arguments& args) {
|
v8::Handle<v8::Value> Protocol::IsHandledProtocol(const v8::Arguments& args) {
|
||||||
return v8::Boolean::New(net::URLRequest::IsHandledProtocol(
|
return ToV8Value(net::URLRequest::IsHandledProtocol(FromV8Value(args[0])));
|
||||||
*v8::String::Utf8Value(args[0])));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
v8::Handle<v8::Value> Protocol::InterceptProtocol(const v8::Arguments& args) {
|
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))
|
if (!GetRequestJobFactory()->HasProtocolHandler(scheme))
|
||||||
return node::ThrowError("Cannot intercept procotol");
|
return node::ThrowError("Cannot intercept procotol");
|
||||||
|
|
||||||
|
@ -243,10 +247,7 @@ v8::Handle<v8::Value> Protocol::InterceptProtocol(const v8::Arguments& args) {
|
||||||
return node::ThrowError(kEarlyUseProtocolError);
|
return node::ThrowError(kEarlyUseProtocolError);
|
||||||
|
|
||||||
// Store the handler in a map.
|
// Store the handler in a map.
|
||||||
if (!args[1]->IsFunction())
|
g_handlers[scheme] = callback;
|
||||||
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]));
|
|
||||||
|
|
||||||
content::BrowserThread::PostTask(content::BrowserThread::IO,
|
content::BrowserThread::PostTask(content::BrowserThread::IO,
|
||||||
FROM_HERE,
|
FROM_HERE,
|
||||||
|
@ -256,7 +257,9 @@ v8::Handle<v8::Value> Protocol::InterceptProtocol(const v8::Arguments& args) {
|
||||||
|
|
||||||
// static
|
// static
|
||||||
v8::Handle<v8::Value> Protocol::UninterceptProtocol(const v8::Arguments& args) {
|
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)
|
if (AtomBrowserContext::Get()->url_request_context_getter() == NULL)
|
||||||
return node::ThrowError(kEarlyUseProtocolError);
|
return node::ThrowError(kEarlyUseProtocolError);
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
#include "base/values.h"
|
#include "base/values.h"
|
||||||
#include "browser/native_window.h"
|
#include "browser/native_window.h"
|
||||||
|
#include "common/v8_conversions.h"
|
||||||
#include "common/v8_value_converter_impl.h"
|
#include "common/v8_value_converter_impl.h"
|
||||||
#include "content/public/browser/navigation_entry.h"
|
#include "content/public/browser/navigation_entry.h"
|
||||||
#include "content/public/browser/web_contents.h"
|
#include "content/public/browser/web_contents.h"
|
||||||
|
@ -27,15 +28,6 @@ namespace atom {
|
||||||
|
|
||||||
namespace api {
|
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)
|
Window::Window(v8::Handle<v8::Object> wrapper, base::DictionaryValue* options)
|
||||||
: EventEmitter(wrapper),
|
: EventEmitter(wrapper),
|
||||||
window_(NativeWindow::Create(options)) {
|
window_(NativeWindow::Create(options)) {
|
||||||
|
@ -141,7 +133,7 @@ v8::Handle<v8::Value> Window::Focus(const v8::Arguments &args) {
|
||||||
// static
|
// static
|
||||||
v8::Handle<v8::Value> Window::IsFocused(const v8::Arguments &args) {
|
v8::Handle<v8::Value> Window::IsFocused(const v8::Arguments &args) {
|
||||||
UNWRAP_WINDOW_AND_CHECK;
|
UNWRAP_WINDOW_AND_CHECK;
|
||||||
return v8::Boolean::New(self->window_->IsFocused());
|
return ToV8Value(self->window_->IsFocused());
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// 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) {
|
v8::Handle<v8::Value> Window::SetFullscreen(const v8::Arguments &args) {
|
||||||
UNWRAP_WINDOW_AND_CHECK;
|
UNWRAP_WINDOW_AND_CHECK;
|
||||||
|
|
||||||
if (args.Length() < 1 || !args[0]->IsBoolean())
|
bool fs;
|
||||||
|
if (!FromV8Arguments(args, &fs))
|
||||||
return node::ThrowTypeError("Bad argument");
|
return node::ThrowTypeError("Bad argument");
|
||||||
self->window_->SetFullscreen(args[0]->BooleanValue());
|
|
||||||
|
|
||||||
|
self->window_->SetFullscreen(fs);
|
||||||
return v8::Undefined();
|
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) {
|
v8::Handle<v8::Value> Window::IsFullscreen(const v8::Arguments &args) {
|
||||||
UNWRAP_WINDOW_AND_CHECK;
|
UNWRAP_WINDOW_AND_CHECK;
|
||||||
|
|
||||||
return v8::Boolean::New(self->window_->IsFullscreen());
|
return ToV8Value(self->window_->IsFullscreen());
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
v8::Handle<v8::Value> Window::SetSize(const v8::Arguments &args) {
|
v8::Handle<v8::Value> Window::SetSize(const v8::Arguments &args) {
|
||||||
UNWRAP_WINDOW_AND_CHECK;
|
UNWRAP_WINDOW_AND_CHECK;
|
||||||
|
|
||||||
if (args.Length() < 2)
|
int width, height;
|
||||||
|
if (!FromV8Arguments(args, &width, &height))
|
||||||
return node::ThrowTypeError("Bad argument");
|
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();
|
return v8::Undefined();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -234,8 +227,8 @@ v8::Handle<v8::Value> Window::GetSize(const v8::Arguments &args) {
|
||||||
|
|
||||||
gfx::Size size = self->window_->GetSize();
|
gfx::Size size = self->window_->GetSize();
|
||||||
v8::Handle<v8::Array> ret = v8::Array::New(2);
|
v8::Handle<v8::Array> ret = v8::Array::New(2);
|
||||||
ret->Set(0, v8::Integer::New(size.width()));
|
ret->Set(0, ToV8Value(size.width()));
|
||||||
ret->Set(1, v8::Integer::New(size.height()));
|
ret->Set(1, ToV8Value(size.height()));
|
||||||
|
|
||||||
return ret;
|
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) {
|
v8::Handle<v8::Value> Window::SetMinimumSize(const v8::Arguments &args) {
|
||||||
UNWRAP_WINDOW_AND_CHECK;
|
UNWRAP_WINDOW_AND_CHECK;
|
||||||
|
|
||||||
if (args.Length() < 2)
|
int width, height;
|
||||||
|
if (!FromV8Arguments(args, &width, &height))
|
||||||
return node::ThrowTypeError("Bad argument");
|
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();
|
return v8::Undefined();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -258,8 +251,8 @@ v8::Handle<v8::Value> Window::GetMinimumSize(const v8::Arguments &args) {
|
||||||
|
|
||||||
gfx::Size size = self->window_->GetMinimumSize();
|
gfx::Size size = self->window_->GetMinimumSize();
|
||||||
v8::Handle<v8::Array> ret = v8::Array::New(2);
|
v8::Handle<v8::Array> ret = v8::Array::New(2);
|
||||||
ret->Set(0, v8::Integer::New(size.width()));
|
ret->Set(0, ToV8Value(size.width()));
|
||||||
ret->Set(1, v8::Integer::New(size.height()));
|
ret->Set(1, ToV8Value(size.height()));
|
||||||
|
|
||||||
return ret;
|
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) {
|
v8::Handle<v8::Value> Window::SetMaximumSize(const v8::Arguments &args) {
|
||||||
UNWRAP_WINDOW_AND_CHECK;
|
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();
|
return v8::Undefined();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -282,8 +276,8 @@ v8::Handle<v8::Value> Window::GetMaximumSize(const v8::Arguments &args) {
|
||||||
|
|
||||||
gfx::Size size = self->window_->GetMaximumSize();
|
gfx::Size size = self->window_->GetMaximumSize();
|
||||||
v8::Handle<v8::Array> ret = v8::Array::New(2);
|
v8::Handle<v8::Array> ret = v8::Array::New(2);
|
||||||
ret->Set(0, v8::Integer::New(size.width()));
|
ret->Set(0, ToV8Value(size.width()));
|
||||||
ret->Set(1, v8::Integer::New(size.height()));
|
ret->Set(1, ToV8Value(size.height()));
|
||||||
|
|
||||||
return ret;
|
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) {
|
v8::Handle<v8::Value> Window::SetResizable(const v8::Arguments &args) {
|
||||||
UNWRAP_WINDOW_AND_CHECK;
|
UNWRAP_WINDOW_AND_CHECK;
|
||||||
|
|
||||||
if (args.Length() < 1 || !args[0]->IsBoolean())
|
bool resizable;
|
||||||
|
if (!FromV8Arguments(args, &resizable))
|
||||||
return node::ThrowTypeError("Bad argument");
|
return node::ThrowTypeError("Bad argument");
|
||||||
self->window_->SetResizable(args[0]->BooleanValue());
|
|
||||||
|
|
||||||
|
self->window_->SetResizable(resizable);
|
||||||
return v8::Undefined();
|
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) {
|
v8::Handle<v8::Value> Window::IsResizable(const v8::Arguments &args) {
|
||||||
UNWRAP_WINDOW_AND_CHECK;
|
UNWRAP_WINDOW_AND_CHECK;
|
||||||
|
|
||||||
return v8::Boolean::New(self->window_->IsResizable());
|
return ToV8Value(self->window_->IsResizable());
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
v8::Handle<v8::Value> Window::SetAlwaysOnTop(const v8::Arguments &args) {
|
v8::Handle<v8::Value> Window::SetAlwaysOnTop(const v8::Arguments &args) {
|
||||||
UNWRAP_WINDOW_AND_CHECK;
|
UNWRAP_WINDOW_AND_CHECK;
|
||||||
|
|
||||||
if (args.Length() < 1 || !args[0]->IsBoolean())
|
bool top;
|
||||||
|
if (!FromV8Arguments(args, &top))
|
||||||
return node::ThrowTypeError("Bad argument");
|
return node::ThrowTypeError("Bad argument");
|
||||||
self->window_->SetAlwaysOnTop(args[0]->BooleanValue());
|
|
||||||
|
|
||||||
|
self->window_->SetAlwaysOnTop(top);
|
||||||
return v8::Undefined();
|
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) {
|
v8::Handle<v8::Value> Window::IsAlwaysOnTop(const v8::Arguments &args) {
|
||||||
UNWRAP_WINDOW_AND_CHECK;
|
UNWRAP_WINDOW_AND_CHECK;
|
||||||
|
|
||||||
return v8::Boolean::New(self->window_->IsAlwaysOnTop());
|
return ToV8Value(self->window_->IsAlwaysOnTop());
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// 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) {
|
v8::Handle<v8::Value> Window::SetPosition(const v8::Arguments &args) {
|
||||||
UNWRAP_WINDOW_AND_CHECK;
|
UNWRAP_WINDOW_AND_CHECK;
|
||||||
|
|
||||||
if (args.Length() < 2)
|
int x, y;
|
||||||
|
if (!FromV8Arguments(args, &x, &y))
|
||||||
return node::ThrowTypeError("Bad argument");
|
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();
|
return v8::Undefined();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -351,8 +347,8 @@ v8::Handle<v8::Value> Window::GetPosition(const v8::Arguments &args) {
|
||||||
|
|
||||||
gfx::Point pos = self->window_->GetPosition();
|
gfx::Point pos = self->window_->GetPosition();
|
||||||
v8::Handle<v8::Array> ret = v8::Array::New(2);
|
v8::Handle<v8::Array> ret = v8::Array::New(2);
|
||||||
ret->Set(0, v8::Integer::New(pos.x()));
|
ret->Set(0, ToV8Value(pos.x()));
|
||||||
ret->Set(1, v8::Integer::New(pos.y()));
|
ret->Set(1, ToV8Value(pos.y()));
|
||||||
|
|
||||||
return ret;
|
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) {
|
v8::Handle<v8::Value> Window::SetTitle(const v8::Arguments &args) {
|
||||||
UNWRAP_WINDOW_AND_CHECK;
|
UNWRAP_WINDOW_AND_CHECK;
|
||||||
|
|
||||||
if (args.Length() < 1 || !args[0]->IsString())
|
std::string title;
|
||||||
|
if (!FromV8Arguments(args, &title))
|
||||||
return node::ThrowTypeError("Bad argument");
|
return node::ThrowTypeError("Bad argument");
|
||||||
self->window_->SetTitle(*v8::String::Utf8Value(args[0]));
|
|
||||||
|
|
||||||
|
self->window_->SetTitle(title);
|
||||||
return v8::Undefined();
|
return v8::Undefined();
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
v8::Handle<v8::Value> Window::GetTitle(const v8::Arguments &args) {
|
v8::Handle<v8::Value> Window::GetTitle(const v8::Arguments &args) {
|
||||||
UNWRAP_WINDOW_AND_CHECK;
|
UNWRAP_WINDOW_AND_CHECK;
|
||||||
|
return ToV8Value(self->window_->GetTitle());
|
||||||
std::string title = self->window_->GetTitle();
|
|
||||||
|
|
||||||
return v8::String::New(title.c_str(), title.size());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// 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) {
|
v8::Handle<v8::Value> Window::SetKiosk(const v8::Arguments &args) {
|
||||||
UNWRAP_WINDOW_AND_CHECK;
|
UNWRAP_WINDOW_AND_CHECK;
|
||||||
|
|
||||||
if (args.Length() < 1 || !args[0]->IsBoolean())
|
bool kiosk;
|
||||||
|
if (!FromV8Arguments(args, &kiosk))
|
||||||
return node::ThrowTypeError("Bad argument");
|
return node::ThrowTypeError("Bad argument");
|
||||||
self->window_->SetKiosk(args[0]->BooleanValue());
|
|
||||||
|
|
||||||
|
self->window_->SetKiosk(kiosk);
|
||||||
return v8::Undefined();
|
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) {
|
v8::Handle<v8::Value> Window::IsKiosk(const v8::Arguments &args) {
|
||||||
UNWRAP_WINDOW_AND_CHECK;
|
UNWRAP_WINDOW_AND_CHECK;
|
||||||
|
|
||||||
return v8::Boolean::New(self->window_->IsKiosk());
|
return ToV8Value(self->window_->IsKiosk());
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// 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) {
|
v8::Handle<v8::Value> Window::InspectElement(const v8::Arguments& args) {
|
||||||
UNWRAP_WINDOW_AND_CHECK;
|
UNWRAP_WINDOW_AND_CHECK;
|
||||||
|
|
||||||
self->window_->InspectElement(args[0]->IntegerValue(),
|
int x, y;
|
||||||
args[1]->IntegerValue());
|
if (!FromV8Arguments(args, &x, &y))
|
||||||
|
return node::ThrowTypeError("Bad argument");
|
||||||
|
|
||||||
|
self->window_->InspectElement(x, y);
|
||||||
return v8::Undefined();
|
return v8::Undefined();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -454,7 +451,7 @@ v8::Handle<v8::Value> Window::BlurWebView(const v8::Arguments &args) {
|
||||||
// static
|
// static
|
||||||
v8::Handle<v8::Value> Window::IsWebViewFocused(const v8::Arguments& args) {
|
v8::Handle<v8::Value> Window::IsWebViewFocused(const v8::Arguments& args) {
|
||||||
UNWRAP_WINDOW_AND_CHECK;
|
UNWRAP_WINDOW_AND_CHECK;
|
||||||
return v8::Boolean::New(self->window_->IsWebViewFocused());
|
return ToV8Value(self->window_->IsWebViewFocused());
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
|
@ -471,24 +468,21 @@ v8::Handle<v8::Value> Window::RestartHangMonitorTimeout(
|
||||||
v8::Handle<v8::Value> Window::GetPageTitle(const v8::Arguments &args) {
|
v8::Handle<v8::Value> Window::GetPageTitle(const v8::Arguments &args) {
|
||||||
UNWRAP_WINDOW_AND_CHECK;
|
UNWRAP_WINDOW_AND_CHECK;
|
||||||
|
|
||||||
string16 title = self->window_->GetWebContents()->GetTitle();
|
return ToV8Value(self->window_->GetWebContents()->GetTitle());
|
||||||
|
|
||||||
return UTF16ToV8String(title);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
v8::Handle<v8::Value> Window::IsLoading(const v8::Arguments &args) {
|
v8::Handle<v8::Value> Window::IsLoading(const v8::Arguments &args) {
|
||||||
UNWRAP_WINDOW_AND_CHECK;
|
UNWRAP_WINDOW_AND_CHECK;
|
||||||
|
|
||||||
return v8::Boolean::New(self->window_->GetWebContents()->IsLoading());
|
return ToV8Value(self->window_->GetWebContents()->IsLoading());
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
v8::Handle<v8::Value> Window::IsWaitingForResponse(const v8::Arguments &args) {
|
v8::Handle<v8::Value> Window::IsWaitingForResponse(const v8::Arguments &args) {
|
||||||
UNWRAP_WINDOW_AND_CHECK;
|
UNWRAP_WINDOW_AND_CHECK;
|
||||||
|
|
||||||
return v8::Boolean::New(
|
return ToV8Value(self->window_->GetWebContents()->IsWaitingForResponse());
|
||||||
self->window_->GetWebContents()->IsWaitingForResponse());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// 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) {
|
v8::Handle<v8::Value> Window::GetRoutingID(const v8::Arguments &args) {
|
||||||
UNWRAP_WINDOW_AND_CHECK;
|
UNWRAP_WINDOW_AND_CHECK;
|
||||||
|
|
||||||
return v8::Integer::New(self->window_->GetWebContents()->GetRoutingID());
|
return ToV8Value(self->window_->GetWebContents()->GetRoutingID());
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
v8::Handle<v8::Value> Window::GetProcessID(const v8::Arguments &args) {
|
v8::Handle<v8::Value> Window::GetProcessID(const v8::Arguments &args) {
|
||||||
UNWRAP_WINDOW_AND_CHECK;
|
UNWRAP_WINDOW_AND_CHECK;
|
||||||
|
|
||||||
return v8::Integer::New(
|
return ToV8Value(
|
||||||
self->window_->GetWebContents()->GetRenderProcessHost()->GetID());
|
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) {
|
v8::Handle<v8::Value> Window::IsCrashed(const v8::Arguments &args) {
|
||||||
UNWRAP_WINDOW_AND_CHECK;
|
UNWRAP_WINDOW_AND_CHECK;
|
||||||
|
|
||||||
return v8::Boolean::New(self->window_->GetWebContents()->IsCrashed());
|
return ToV8Value(self->window_->GetWebContents()->IsCrashed());
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
v8::Handle<v8::Value> Window::LoadURL(const v8::Arguments &args) {
|
v8::Handle<v8::Value> Window::LoadURL(const v8::Arguments &args) {
|
||||||
UNWRAP_WINDOW_AND_CHECK;
|
UNWRAP_WINDOW_AND_CHECK;
|
||||||
|
|
||||||
if (args.Length() < 1 || !args[0]->IsString())
|
std::string url;
|
||||||
|
if (!FromV8Arguments(args, &url))
|
||||||
return node::ThrowTypeError("Bad argument");
|
return node::ThrowTypeError("Bad argument");
|
||||||
|
|
||||||
NavigationController& controller =
|
NavigationController& controller =
|
||||||
self->window_->GetWebContents()->GetController();
|
self->window_->GetWebContents()->GetController();
|
||||||
controller.LoadURL(GURL(*v8::String::Utf8Value(args[0])),
|
controller.LoadURL(GURL(url),
|
||||||
content::Referrer(),
|
content::Referrer(),
|
||||||
content::PAGE_TRANSITION_AUTO_TOPLEVEL,
|
content::PAGE_TRANSITION_AUTO_TOPLEVEL,
|
||||||
std::string());
|
std::string());
|
||||||
|
@ -549,7 +544,7 @@ v8::Handle<v8::Value> Window::GetURL(const v8::Arguments &args) {
|
||||||
if (controller.GetActiveEntry())
|
if (controller.GetActiveEntry())
|
||||||
url = controller.GetActiveEntry()->GetVirtualURL().spec();
|
url = controller.GetActiveEntry()->GetVirtualURL().spec();
|
||||||
|
|
||||||
return v8::String::New(url.c_str(), url.size());
|
return ToV8Value(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
|
@ -559,7 +554,7 @@ v8::Handle<v8::Value> Window::CanGoBack(const v8::Arguments &args) {
|
||||||
NavigationController& controller =
|
NavigationController& controller =
|
||||||
self->window_->GetWebContents()->GetController();
|
self->window_->GetWebContents()->GetController();
|
||||||
|
|
||||||
return v8::Boolean::New(controller.CanGoBack());
|
return ToV8Value(controller.CanGoBack());
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
|
@ -569,21 +564,21 @@ v8::Handle<v8::Value> Window::CanGoForward(const v8::Arguments &args) {
|
||||||
NavigationController& controller =
|
NavigationController& controller =
|
||||||
self->window_->GetWebContents()->GetController();
|
self->window_->GetWebContents()->GetController();
|
||||||
|
|
||||||
return v8::Boolean::New(controller.CanGoForward());
|
return ToV8Value(controller.CanGoForward());
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
v8::Handle<v8::Value> Window::CanGoToOffset(const v8::Arguments &args) {
|
v8::Handle<v8::Value> Window::CanGoToOffset(const v8::Arguments &args) {
|
||||||
UNWRAP_WINDOW_AND_CHECK;
|
UNWRAP_WINDOW_AND_CHECK;
|
||||||
|
|
||||||
if (args.Length() < 1)
|
int offset;
|
||||||
|
if (!FromV8Arguments(args, &offset))
|
||||||
return node::ThrowTypeError("Bad argument");
|
return node::ThrowTypeError("Bad argument");
|
||||||
|
|
||||||
NavigationController& controller =
|
NavigationController& controller =
|
||||||
self->window_->GetWebContents()->GetController();
|
self->window_->GetWebContents()->GetController();
|
||||||
int offset = args[0]->IntegerValue();
|
|
||||||
|
|
||||||
return v8::Boolean::New(controller.CanGoToOffset(offset));
|
return ToV8Value(controller.CanGoToOffset(offset));
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// 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) {
|
v8::Handle<v8::Value> Window::GoToIndex(const v8::Arguments &args) {
|
||||||
UNWRAP_WINDOW_AND_CHECK;
|
UNWRAP_WINDOW_AND_CHECK;
|
||||||
|
|
||||||
if (args.Length() < 1)
|
int index;
|
||||||
|
if (!FromV8Arguments(args, &index))
|
||||||
return node::ThrowTypeError("Bad argument");
|
return node::ThrowTypeError("Bad argument");
|
||||||
|
|
||||||
NavigationController& controller =
|
NavigationController& controller =
|
||||||
self->window_->GetWebContents()->GetController();
|
self->window_->GetWebContents()->GetController();
|
||||||
controller.GoToIndex(args[0]->IntegerValue());
|
controller.GoToIndex(index);
|
||||||
|
|
||||||
return v8::Undefined();
|
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) {
|
v8::Handle<v8::Value> Window::GoToOffset(const v8::Arguments &args) {
|
||||||
UNWRAP_WINDOW_AND_CHECK;
|
UNWRAP_WINDOW_AND_CHECK;
|
||||||
|
|
||||||
if (args.Length() < 1)
|
int offset;
|
||||||
|
if (!FromV8Arguments(args, &offset))
|
||||||
return node::ThrowTypeError("Bad argument");
|
return node::ThrowTypeError("Bad argument");
|
||||||
|
|
||||||
NavigationController& controller =
|
NavigationController& controller =
|
||||||
self->window_->GetWebContents()->GetController();
|
self->window_->GetWebContents()->GetController();
|
||||||
controller.GoToOffset(args[0]->IntegerValue());
|
controller.GoToOffset(offset);
|
||||||
|
|
||||||
return v8::Undefined();
|
return v8::Undefined();
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,8 @@
|
||||||
|
|
||||||
#include "base/logging.h"
|
#include "base/logging.h"
|
||||||
#include "base/values.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 "common/v8_value_converter_impl.h"
|
||||||
#include "content/public/browser/browser_thread.h"
|
#include "content/public/browser/browser_thread.h"
|
||||||
#include "vendor/node/src/node.h"
|
#include "vendor/node/src/node.h"
|
||||||
|
@ -42,7 +44,7 @@ void AtomBrowserBindings::AfterLoad() {
|
||||||
|
|
||||||
void AtomBrowserBindings::OnRendererMessage(int process_id,
|
void AtomBrowserBindings::OnRendererMessage(int process_id,
|
||||||
int routing_id,
|
int routing_id,
|
||||||
const std::string& channel,
|
const string16& channel,
|
||||||
const base::ListValue& args) {
|
const base::ListValue& args) {
|
||||||
v8::HandleScope scope;
|
v8::HandleScope scope;
|
||||||
|
|
||||||
|
@ -53,7 +55,7 @@ void AtomBrowserBindings::OnRendererMessage(int process_id,
|
||||||
// process.emit(channel, 'message', process_id, routing_id);
|
// process.emit(channel, 'message', process_id, routing_id);
|
||||||
std::vector<v8::Handle<v8::Value>> arguments;
|
std::vector<v8::Handle<v8::Value>> arguments;
|
||||||
arguments.reserve(3 + args.GetSize());
|
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;
|
const base::Value* value;
|
||||||
if (args.Get(0, &value))
|
if (args.Get(0, &value))
|
||||||
arguments.push_back(converter->ToV8Value(value, context));
|
arguments.push_back(converter->ToV8Value(value, context));
|
||||||
|
@ -72,21 +74,24 @@ void AtomBrowserBindings::OnRendererMessage(int process_id,
|
||||||
void AtomBrowserBindings::OnRendererMessageSync(
|
void AtomBrowserBindings::OnRendererMessageSync(
|
||||||
int process_id,
|
int process_id,
|
||||||
int routing_id,
|
int routing_id,
|
||||||
const std::string& channel,
|
const string16& channel,
|
||||||
const base::ListValue& args,
|
const base::ListValue& args,
|
||||||
base::DictionaryValue* result) {
|
NativeWindow* sender,
|
||||||
|
IPC::Message* message) {
|
||||||
v8::HandleScope scope;
|
v8::HandleScope scope;
|
||||||
|
|
||||||
v8::Handle<v8::Context> context = v8::Context::GetCurrent();
|
v8::Handle<v8::Context> context = v8::Context::GetCurrent();
|
||||||
|
|
||||||
scoped_ptr<V8ValueConverter> converter(new V8ValueConverterImpl());
|
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);
|
// process.emit(channel, 'sync-message', event, process_id, routing_id);
|
||||||
std::vector<v8::Handle<v8::Value>> arguments;
|
std::vector<v8::Handle<v8::Value>> arguments;
|
||||||
arguments.reserve(3 + args.GetSize());
|
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;
|
const base::Value* value;
|
||||||
if (args.Get(0, &value))
|
if (args.Get(0, &value))
|
||||||
arguments.push_back(converter->ToV8Value(value, context));
|
arguments.push_back(converter->ToV8Value(value, context));
|
||||||
|
@ -101,11 +106,6 @@ void AtomBrowserBindings::OnRendererMessageSync(
|
||||||
}
|
}
|
||||||
|
|
||||||
node::MakeCallback(node::process, "emit", arguments.size(), &arguments[0]);
|
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
|
} // namespace atom
|
||||||
|
|
|
@ -5,17 +5,21 @@
|
||||||
#ifndef ATOM_BROWSER_API_ATOM_BROWSER_BINDINGS_
|
#ifndef ATOM_BROWSER_API_ATOM_BROWSER_BINDINGS_
|
||||||
#define 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"
|
#include "common/api/atom_bindings.h"
|
||||||
|
|
||||||
namespace base {
|
namespace base {
|
||||||
class DictionaryValue;
|
|
||||||
class ListValue;
|
class ListValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace IPC {
|
||||||
|
class Message;
|
||||||
|
}
|
||||||
|
|
||||||
namespace atom {
|
namespace atom {
|
||||||
|
|
||||||
|
class NativeWindow;
|
||||||
|
|
||||||
class AtomBrowserBindings : public AtomBindings {
|
class AtomBrowserBindings : public AtomBindings {
|
||||||
public:
|
public:
|
||||||
AtomBrowserBindings();
|
AtomBrowserBindings();
|
||||||
|
@ -27,15 +31,16 @@ class AtomBrowserBindings : public AtomBindings {
|
||||||
// Called when received a message from renderer.
|
// Called when received a message from renderer.
|
||||||
void OnRendererMessage(int process_id,
|
void OnRendererMessage(int process_id,
|
||||||
int routing_id,
|
int routing_id,
|
||||||
const std::string& channel,
|
const string16& channel,
|
||||||
const base::ListValue& args);
|
const base::ListValue& args);
|
||||||
|
|
||||||
// Called when received a synchronous message from renderer.
|
// Called when received a synchronous message from renderer.
|
||||||
void OnRendererMessageSync(int process_id,
|
void OnRendererMessageSync(int process_id,
|
||||||
int routing_id,
|
int routing_id,
|
||||||
const std::string& channel,
|
const string16& channel,
|
||||||
const base::ListValue& args,
|
const base::ListValue& args,
|
||||||
base::DictionaryValue* result);
|
NativeWindow* sender,
|
||||||
|
IPC::Message* message);
|
||||||
|
|
||||||
// The require('atom').browserMainParts object.
|
// The require('atom').browserMainParts object.
|
||||||
v8::Handle<v8::Object> browser_main_parts() {
|
v8::Handle<v8::Object> browser_main_parts() {
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
binding = process.atomBinding 'dialog'
|
binding = process.atomBinding 'dialog'
|
||||||
|
v8Util = process.atomBinding 'v8_util'
|
||||||
BrowserWindow = require 'browser-window'
|
BrowserWindow = require 'browser-window'
|
||||||
|
|
||||||
fileDialogProperties =
|
fileDialogProperties =
|
||||||
|
@ -7,48 +8,71 @@ fileDialogProperties =
|
||||||
messageBoxTypes = ['none', 'info', 'warning']
|
messageBoxTypes = ['none', 'info', 'warning']
|
||||||
|
|
||||||
module.exports =
|
module.exports =
|
||||||
showOpenDialog: (options) ->
|
showOpenDialog: (window, options, callback) ->
|
||||||
options = title: 'Open', properties: ['openFile'] unless options?
|
unless window?.constructor is BrowserWindow
|
||||||
options.properties = options.properties ? ['openFile']
|
# 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
|
throw new TypeError('Properties need to be array') unless Array.isArray options.properties
|
||||||
|
|
||||||
properties = 0
|
properties = 0
|
||||||
for prop, value of fileDialogProperties
|
for prop, value of fileDialogProperties
|
||||||
properties |= value if prop in options.properties
|
properties |= value if prop in options.properties
|
||||||
|
|
||||||
options.title = options.title ? ''
|
options.title ?= ''
|
||||||
options.defaultPath = options.defaultPath ? ''
|
options.defaultPath ?= ''
|
||||||
|
|
||||||
binding.showOpenDialog options.title, options.defaultPath, properties
|
binding.showOpenDialog String(options.title),
|
||||||
|
String(options.defaultPath),
|
||||||
|
properties,
|
||||||
|
window,
|
||||||
|
callback
|
||||||
|
|
||||||
showSaveDialog: (window, options) ->
|
showSaveDialog: (window, options, callback) ->
|
||||||
throw new TypeError('Invalid window') unless window?.constructor is BrowserWindow
|
unless window?.constructor is BrowserWindow
|
||||||
options = title: 'Save' unless options?
|
# Shift.
|
||||||
|
callback = 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
|
|
||||||
options = window
|
options = window
|
||||||
window = null
|
window = null
|
||||||
|
|
||||||
options = type: 'none' unless options?
|
options ?= title: 'Save'
|
||||||
options.type = options.type ? 'none'
|
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
|
options.type = messageBoxTypes.indexOf options.type
|
||||||
throw new TypeError('Invalid message box type') unless options.type > -1
|
throw new TypeError('Invalid message box type') unless options.type > -1
|
||||||
|
|
||||||
throw new TypeError('Buttons need to be array') unless Array.isArray options.buttons
|
throw new TypeError('Buttons need to be array') unless Array.isArray options.buttons
|
||||||
|
|
||||||
options.title = options.title ? ''
|
options.title ?= ''
|
||||||
options.message = options.message ? ''
|
options.message ?= ''
|
||||||
options.detail = options.detail ? ''
|
options.detail ?= ''
|
||||||
|
|
||||||
binding.showMessageBox options.type,
|
binding.showMessageBox options.type,
|
||||||
options.buttons,
|
options.buttons,
|
||||||
String(options.title),
|
String(options.title),
|
||||||
String(options.message),
|
String(options.message),
|
||||||
String(options.detail),
|
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: ->
|
constructor: ->
|
||||||
process.on 'ATOM_INTERNAL_MESSAGE', (args...) =>
|
process.on 'ATOM_INTERNAL_MESSAGE', (args...) =>
|
||||||
@emit(args...)
|
@emit(args...)
|
||||||
process.on 'ATOM_INTERNAL_MESSAGE_SYNC', (args...) =>
|
process.on 'ATOM_INTERNAL_MESSAGE_SYNC', (channel, event, args...) =>
|
||||||
@emit(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...) ->
|
send: (processId, routingId, args...) ->
|
||||||
@sendChannel(processId, routingId, 'message', args...)
|
@sendChannel(processId, routingId, 'message', args...)
|
||||||
|
|
|
@ -61,28 +61,40 @@ unwrapArgs = (processId, routingId, args) ->
|
||||||
|
|
||||||
args.map metaToValue
|
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) ->
|
ipc.on 'ATOM_BROWSER_REQUIRE', (event, processId, routingId, module) ->
|
||||||
try
|
try
|
||||||
event.result = valueToMeta processId, routingId, require(module)
|
event.returnValue = valueToMeta processId, routingId, require(module)
|
||||||
catch e
|
catch e
|
||||||
event.result = errorToMeta e
|
event.returnValue = errorToMeta e
|
||||||
|
|
||||||
ipc.on 'ATOM_BROWSER_GLOBAL', (event, processId, routingId, name) ->
|
ipc.on 'ATOM_BROWSER_GLOBAL', (event, processId, routingId, name) ->
|
||||||
try
|
try
|
||||||
event.result = valueToMeta processId, routingId, global[name]
|
event.returnValue = valueToMeta processId, routingId, global[name]
|
||||||
catch e
|
catch e
|
||||||
event.result = errorToMeta e
|
event.returnValue = errorToMeta e
|
||||||
|
|
||||||
ipc.on 'ATOM_BROWSER_RELEASE_RENDER_VIEW', (event, processId, routingId) ->
|
ipc.on 'ATOM_BROWSER_RELEASE_RENDER_VIEW', (event, processId, routingId) ->
|
||||||
objectsRegistry.clear processId, routingId
|
objectsRegistry.clear processId, routingId
|
||||||
|
event.returnValue = null
|
||||||
|
|
||||||
ipc.on 'ATOM_BROWSER_CURRENT_WINDOW', (event, processId, routingId) ->
|
ipc.on 'ATOM_BROWSER_CURRENT_WINDOW', (event, processId, routingId) ->
|
||||||
try
|
try
|
||||||
BrowserWindow = require 'browser-window'
|
BrowserWindow = require 'browser-window'
|
||||||
window = BrowserWindow.fromProcessIdAndRoutingId processId, routingId
|
window = BrowserWindow.fromProcessIdAndRoutingId processId, routingId
|
||||||
event.result = valueToMeta processId, routingId, window
|
event.returnValue = valueToMeta processId, routingId, window
|
||||||
catch e
|
catch e
|
||||||
event.result = errorToMeta e
|
event.returnValue = errorToMeta e
|
||||||
|
|
||||||
ipc.on 'ATOM_BROWSER_CONSTRUCTOR', (event, processId, routingId, id, args) ->
|
ipc.on 'ATOM_BROWSER_CONSTRUCTOR', (event, processId, routingId, id, args) ->
|
||||||
try
|
try
|
||||||
|
@ -91,18 +103,17 @@ ipc.on 'ATOM_BROWSER_CONSTRUCTOR', (event, processId, routingId, id, args) ->
|
||||||
# Call new with array of arguments.
|
# Call new with array of arguments.
|
||||||
# http://stackoverflow.com/questions/1606797/use-of-apply-with-new-operator-is-this-possible
|
# http://stackoverflow.com/questions/1606797/use-of-apply-with-new-operator-is-this-possible
|
||||||
obj = new (Function::bind.apply(constructor, [null].concat(args)))
|
obj = new (Function::bind.apply(constructor, [null].concat(args)))
|
||||||
event.result = valueToMeta processId, routingId, obj
|
event.returnValue = valueToMeta processId, routingId, obj
|
||||||
catch e
|
catch e
|
||||||
event.result = errorToMeta e
|
event.returnValue = errorToMeta e
|
||||||
|
|
||||||
ipc.on 'ATOM_BROWSER_FUNCTION_CALL', (event, processId, routingId, id, args) ->
|
ipc.on 'ATOM_BROWSER_FUNCTION_CALL', (event, processId, routingId, id, args) ->
|
||||||
try
|
try
|
||||||
args = unwrapArgs processId, routingId, args
|
args = unwrapArgs processId, routingId, args
|
||||||
func = objectsRegistry.get id
|
func = objectsRegistry.get id
|
||||||
ret = func.apply global, args
|
callFunction event, processId, routingId, func, global, args
|
||||||
event.result = valueToMeta processId, routingId, ret
|
|
||||||
catch e
|
catch e
|
||||||
event.result = errorToMeta e
|
event.returnValue = errorToMeta e
|
||||||
|
|
||||||
ipc.on 'ATOM_BROWSER_MEMBER_CONSTRUCTOR', (event, processId, routingId, id, method, args) ->
|
ipc.on 'ATOM_BROWSER_MEMBER_CONSTRUCTOR', (event, processId, routingId, id, method, args) ->
|
||||||
try
|
try
|
||||||
|
@ -110,32 +121,32 @@ ipc.on 'ATOM_BROWSER_MEMBER_CONSTRUCTOR', (event, processId, routingId, id, meth
|
||||||
constructor = objectsRegistry.get(id)[method]
|
constructor = objectsRegistry.get(id)[method]
|
||||||
# Call new with array of arguments.
|
# Call new with array of arguments.
|
||||||
obj = new (Function::bind.apply(constructor, [null].concat(args)))
|
obj = new (Function::bind.apply(constructor, [null].concat(args)))
|
||||||
event.result = valueToMeta processId, routingId, obj
|
event.returnValue = valueToMeta processId, routingId, obj
|
||||||
catch e
|
catch e
|
||||||
event.result = errorToMeta e
|
event.returnValue = errorToMeta e
|
||||||
|
|
||||||
ipc.on 'ATOM_BROWSER_MEMBER_CALL', (event, processId, routingId, id, method, args) ->
|
ipc.on 'ATOM_BROWSER_MEMBER_CALL', (event, processId, routingId, id, method, args) ->
|
||||||
try
|
try
|
||||||
args = unwrapArgs processId, routingId, args
|
args = unwrapArgs processId, routingId, args
|
||||||
obj = objectsRegistry.get id
|
obj = objectsRegistry.get id
|
||||||
ret = obj[method].apply(obj, args)
|
callFunction event, processId, routingId, obj[method], obj, args
|
||||||
event.result = valueToMeta processId, routingId, ret
|
|
||||||
catch e
|
catch e
|
||||||
event.result = errorToMeta e
|
event.returnValue = errorToMeta e
|
||||||
|
|
||||||
ipc.on 'ATOM_BROWSER_MEMBER_SET', (event, processId, routingId, id, name, value) ->
|
ipc.on 'ATOM_BROWSER_MEMBER_SET', (event, processId, routingId, id, name, value) ->
|
||||||
try
|
try
|
||||||
obj = objectsRegistry.get id
|
obj = objectsRegistry.get id
|
||||||
obj[name] = value
|
obj[name] = value
|
||||||
|
event.returnValue = null
|
||||||
catch e
|
catch e
|
||||||
event.result = errorToMeta e
|
event.returnValue = errorToMeta e
|
||||||
|
|
||||||
ipc.on 'ATOM_BROWSER_MEMBER_GET', (event, processId, routingId, id, name) ->
|
ipc.on 'ATOM_BROWSER_MEMBER_GET', (event, processId, routingId, id, name) ->
|
||||||
try
|
try
|
||||||
obj = objectsRegistry.get id
|
obj = objectsRegistry.get id
|
||||||
event.result = valueToMeta processId, routingId, obj[name]
|
event.returnValue = valueToMeta processId, routingId, obj[name]
|
||||||
catch e
|
catch e
|
||||||
event.result = errorToMeta e
|
event.returnValue = errorToMeta e
|
||||||
|
|
||||||
ipc.on 'ATOM_BROWSER_DEREFERENCE', (processId, routingId, storeId) ->
|
ipc.on 'ATOM_BROWSER_DEREFERENCE', (processId, routingId, storeId) ->
|
||||||
objectsRegistry.remove processId, routingId, storeId
|
objectsRegistry.remove processId, routingId, storeId
|
||||||
|
|
|
@ -300,7 +300,8 @@ bool NativeWindow::OnMessageReceived(const IPC::Message& message) {
|
||||||
bool handled = true;
|
bool handled = true;
|
||||||
IPC_BEGIN_MESSAGE_MAP(NativeWindow, message)
|
IPC_BEGIN_MESSAGE_MAP(NativeWindow, message)
|
||||||
IPC_MESSAGE_HANDLER(AtomViewHostMsg_Message, OnRendererMessage)
|
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,
|
IPC_MESSAGE_HANDLER(AtomViewHostMsg_UpdateDraggableRegions,
|
||||||
UpdateDraggableRegions)
|
UpdateDraggableRegions)
|
||||||
IPC_MESSAGE_UNHANDLED(handled = false)
|
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) {
|
const base::ListValue& args) {
|
||||||
AtomBrowserMainParts::Get()->atom_bindings()->OnRendererMessage(
|
AtomBrowserMainParts::Get()->atom_bindings()->OnRendererMessage(
|
||||||
GetWebContents()->GetRenderProcessHost()->GetID(),
|
GetWebContents()->GetRenderProcessHost()->GetID(),
|
||||||
|
@ -349,15 +350,16 @@ void NativeWindow::OnRendererMessage(const std::string& channel,
|
||||||
args);
|
args);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NativeWindow::OnRendererMessageSync(const std::string& channel,
|
void NativeWindow::OnRendererMessageSync(const string16& channel,
|
||||||
const base::ListValue& args,
|
const base::ListValue& args,
|
||||||
base::DictionaryValue* result) {
|
IPC::Message* reply_msg) {
|
||||||
AtomBrowserMainParts::Get()->atom_bindings()->OnRendererMessageSync(
|
AtomBrowserMainParts::Get()->atom_bindings()->OnRendererMessageSync(
|
||||||
GetWebContents()->GetRenderProcessHost()->GetID(),
|
GetWebContents()->GetRenderProcessHost()->GetID(),
|
||||||
GetWebContents()->GetRoutingID(),
|
GetWebContents()->GetRoutingID(),
|
||||||
channel,
|
channel,
|
||||||
args,
|
args,
|
||||||
result);
|
this,
|
||||||
|
reply_msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace atom
|
} // namespace atom
|
||||||
|
|
|
@ -35,6 +35,10 @@ class Rect;
|
||||||
class Size;
|
class Size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace IPC {
|
||||||
|
class Message;
|
||||||
|
}
|
||||||
|
|
||||||
namespace atom {
|
namespace atom {
|
||||||
|
|
||||||
class AtomJavaScriptDialogManager;
|
class AtomJavaScriptDialogManager;
|
||||||
|
@ -173,12 +177,12 @@ class NativeWindow : public brightray::DefaultWebContentsDelegate,
|
||||||
private:
|
private:
|
||||||
void RendererUnresponsiveDelayed();
|
void RendererUnresponsiveDelayed();
|
||||||
|
|
||||||
void OnRendererMessage(const std::string& channel,
|
void OnRendererMessage(const string16& channel,
|
||||||
const base::ListValue& args);
|
const base::ListValue& args);
|
||||||
|
|
||||||
void OnRendererMessageSync(const std::string& channel,
|
void OnRendererMessageSync(const string16& channel,
|
||||||
const base::ListValue& args,
|
const base::ListValue& args,
|
||||||
base::DictionaryValue* result);
|
IPC::Message* reply_msg);
|
||||||
|
|
||||||
// Notification manager.
|
// Notification manager.
|
||||||
content::NotificationRegistrar registrar_;
|
content::NotificationRegistrar registrar_;
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "base/callback_forward.h"
|
||||||
#include "base/files/file_path.h"
|
#include "base/files/file_path.h"
|
||||||
|
|
||||||
namespace atom {
|
namespace atom {
|
||||||
|
@ -23,16 +24,34 @@ enum FileDialogProperty {
|
||||||
FILE_DIALOG_CREATE_DIRECTORY = 8,
|
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,
|
const base::FilePath& default_path,
|
||||||
int properties,
|
int properties,
|
||||||
std::vector<base::FilePath>* paths);
|
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 std::string& title,
|
||||||
const base::FilePath& default_path,
|
const base::FilePath& default_path,
|
||||||
base::FilePath* 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
|
} // namespace file_dialog
|
||||||
|
|
||||||
#endif // BROWSER_UI_FILE_DIALOG_H_
|
#endif // BROWSER_UI_FILE_DIALOG_H_
|
||||||
|
|
|
@ -38,20 +38,11 @@ void SetupDialog(NSSavePanel* dialog,
|
||||||
if (default_filename)
|
if (default_filename)
|
||||||
[dialog setNameFieldStringValue:default_filename];
|
[dialog setNameFieldStringValue:default_filename];
|
||||||
|
|
||||||
|
[dialog setCanSelectHiddenExtension:YES];
|
||||||
[dialog setAllowsOtherFileTypes:YES];
|
[dialog setAllowsOtherFileTypes:YES];
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
void SetupDialogForProperties(NSOpenPanel* dialog, int properties) {
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
[dialog setCanChooseFiles:(properties & FILE_DIALOG_OPEN_FILE)];
|
[dialog setCanChooseFiles:(properties & FILE_DIALOG_OPEN_FILE)];
|
||||||
if (properties & FILE_DIALOG_OPEN_DIRECTORY)
|
if (properties & FILE_DIALOG_OPEN_DIRECTORY)
|
||||||
[dialog setCanChooseDirectories:YES];
|
[dialog setCanChooseDirectories:YES];
|
||||||
|
@ -59,49 +50,119 @@ bool ShowOpenDialog(const std::string& title,
|
||||||
[dialog setCanCreateDirectories:YES];
|
[dialog setCanCreateDirectories:YES];
|
||||||
if (properties & FILE_DIALOG_MULTI_SELECTIONS)
|
if (properties & FILE_DIALOG_MULTI_SELECTIONS)
|
||||||
[dialog setAllowsMultipleSelection:YES];
|
[dialog setAllowsMultipleSelection:YES];
|
||||||
|
}
|
||||||
|
|
||||||
if ([dialog runModal] == NSFileHandlingPanelCancelButton)
|
// Run modal dialog with parent window and return user's choice.
|
||||||
return false;
|
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];
|
NSArray* urls = [dialog URLs];
|
||||||
for (NSURL* url in urls)
|
for (NSURL* url in urls)
|
||||||
if ([url isFileURL])
|
if ([url isFileURL])
|
||||||
paths->push_back(base::FilePath(base::SysNSStringToUTF8([url path])));
|
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;
|
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 std::string& title,
|
||||||
const base::FilePath& default_path,
|
const base::FilePath& default_path,
|
||||||
base::FilePath* path) {
|
base::FilePath* path) {
|
||||||
DCHECK(window);
|
|
||||||
DCHECK(path);
|
DCHECK(path);
|
||||||
NSSavePanel* dialog = [NSSavePanel savePanel];
|
NSSavePanel* dialog = [NSSavePanel savePanel];
|
||||||
|
|
||||||
SetupDialog(dialog, title, default_path);
|
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;
|
*path = base::FilePath(base::SysNSStringToUTF8([[dialog URL] path]));
|
||||||
__block base::FilePath ret_path;
|
return true;
|
||||||
[dialog beginSheetModalForWindow:window->GetNativeWindow()
|
}
|
||||||
|
|
||||||
|
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) {
|
completionHandler:^(NSInteger chosen) {
|
||||||
if (chosen == NSFileHandlingPanelCancelButton ||
|
if (chosen == NSFileHandlingPanelCancelButton) {
|
||||||
![[dialog URL] isFileURL]) {
|
callback.Run(false, base::FilePath());
|
||||||
result = false;
|
|
||||||
} else {
|
} else {
|
||||||
result = true;
|
std::string path = base::SysNSStringToUTF8([[dialog URL] path]);
|
||||||
ret_path = base::FilePath(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
|
} // namespace file_dialog
|
||||||
|
|
|
@ -162,7 +162,8 @@ class FileDialog {
|
||||||
SetDefaultFolder(default_path);
|
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;
|
return dialog_->DoModal(window) == IDOK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -198,7 +199,8 @@ class FileDialog {
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
bool ShowOpenDialog(const std::string& title,
|
bool ShowOpenDialog(atom::NativeWindow* parent_window,
|
||||||
|
const std::string& title,
|
||||||
const base::FilePath& default_path,
|
const base::FilePath& default_path,
|
||||||
int properties,
|
int properties,
|
||||||
std::vector<base::FilePath>* paths) {
|
std::vector<base::FilePath>* paths) {
|
||||||
|
@ -214,7 +216,7 @@ bool ShowOpenDialog(const std::string& title,
|
||||||
options,
|
options,
|
||||||
std::vector<std::wstring>(),
|
std::vector<std::wstring>(),
|
||||||
std::vector<std::wstring>());
|
std::vector<std::wstring>());
|
||||||
if (!open_dialog.Show(::GetActiveWindow()))
|
if (!open_dialog.Show(parent_window))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
ATL::CComPtr<IShellItemArray> items;
|
ATL::CComPtr<IShellItemArray> items;
|
||||||
|
@ -247,7 +249,21 @@ bool ShowOpenDialog(const std::string& title,
|
||||||
return true;
|
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 std::string& title,
|
||||||
const base::FilePath& default_path,
|
const base::FilePath& default_path,
|
||||||
base::FilePath* path) {
|
base::FilePath* path) {
|
||||||
|
@ -263,7 +279,7 @@ bool ShowSaveDialog(atom::NativeWindow* window,
|
||||||
FOS_FORCEFILESYSTEM | FOS_PATHMUSTEXIST | FOS_OVERWRITEPROMPT,
|
FOS_FORCEFILESYSTEM | FOS_PATHMUSTEXIST | FOS_OVERWRITEPROMPT,
|
||||||
file_ext,
|
file_ext,
|
||||||
std::vector<std::wstring>());
|
std::vector<std::wstring>());
|
||||||
if (!save_dialog.Show(window->GetNativeWindow()))
|
if (!save_dialog.Show(parent_window))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
wchar_t file_name[MAX_PATH];
|
wchar_t file_name[MAX_PATH];
|
||||||
|
@ -290,4 +306,13 @@ bool ShowSaveDialog(atom::NativeWindow* window,
|
||||||
return true;
|
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
|
} // namespace file_dialog
|
||||||
|
|
|
@ -8,6 +8,8 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "base/callback_forward.h"
|
||||||
|
|
||||||
namespace atom {
|
namespace atom {
|
||||||
|
|
||||||
class NativeWindow;
|
class NativeWindow;
|
||||||
|
@ -18,6 +20,8 @@ enum MessageBoxType {
|
||||||
MESSAGE_BOX_TYPE_WARNING
|
MESSAGE_BOX_TYPE_WARNING
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef base::Callback<void(int code)> MessageBoxCallback;
|
||||||
|
|
||||||
int ShowMessageBox(NativeWindow* parent_window,
|
int ShowMessageBox(NativeWindow* parent_window,
|
||||||
MessageBoxType type,
|
MessageBoxType type,
|
||||||
const std::vector<std::string>& buttons,
|
const std::vector<std::string>& buttons,
|
||||||
|
@ -25,6 +29,14 @@ int ShowMessageBox(NativeWindow* parent_window,
|
||||||
const std::string& message,
|
const std::string& message,
|
||||||
const std::string& detail);
|
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
|
} // namespace atom
|
||||||
|
|
||||||
#endif // BROWSER_UI_MESSAGE_BOX_H_
|
#endif // BROWSER_UI_MESSAGE_BOX_H_
|
||||||
|
|
|
@ -6,20 +6,53 @@
|
||||||
|
|
||||||
#import <Cocoa/Cocoa.h>
|
#import <Cocoa/Cocoa.h>
|
||||||
|
|
||||||
|
#include "base/callback.h"
|
||||||
#include "base/strings/sys_string_conversions.h"
|
#include "base/strings/sys_string_conversions.h"
|
||||||
#include "browser/native_window.h"
|
#include "browser/native_window.h"
|
||||||
#include "browser/ui/nsalert_synchronous_sheet_mac.h"
|
#include "browser/ui/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 {
|
namespace atom {
|
||||||
|
|
||||||
int ShowMessageBox(NativeWindow* parent_window,
|
namespace {
|
||||||
|
|
||||||
|
NSAlert* CreateNSAlert(NativeWindow* parent_window,
|
||||||
MessageBoxType type,
|
MessageBoxType type,
|
||||||
const std::vector<std::string>& buttons,
|
const std::vector<std::string>& buttons,
|
||||||
const std::string& title,
|
const std::string& title,
|
||||||
const std::string& message,
|
const std::string& message,
|
||||||
const std::string& detail) {
|
const std::string& detail) {
|
||||||
// Ignore the title; it's the window title on other platforms and ignorable.
|
// 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 setMessageText:base::SysUTF8ToNSString(message)];
|
||||||
[alert setInformativeText:base::SysUTF8ToNSString(detail)];
|
[alert setInformativeText:base::SysUTF8ToNSString(detail)];
|
||||||
|
|
||||||
|
@ -40,10 +73,44 @@ int ShowMessageBox(NativeWindow* parent_window,
|
||||||
[button setTag:i];
|
[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)
|
if (parent_window)
|
||||||
return [alert runModalSheetForWindow:parent_window->GetNativeWindow()];
|
return [alert runModalSheetForWindow:parent_window->GetNativeWindow()];
|
||||||
else
|
else
|
||||||
return [alert runModal];
|
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
|
} // namespace atom
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
#include "browser/ui/message_box.h"
|
#include "browser/ui/message_box.h"
|
||||||
|
|
||||||
|
#include "base/callback.h"
|
||||||
#include "base/message_loop.h"
|
#include "base/message_loop.h"
|
||||||
#include "base/run_loop.h"
|
#include "base/run_loop.h"
|
||||||
#include "base/string_util.h"
|
#include "base/string_util.h"
|
||||||
|
@ -38,7 +39,14 @@ class MessageDialog : public base::MessageLoop::Dispatcher,
|
||||||
const std::string& detail);
|
const std::string& detail);
|
||||||
virtual ~MessageDialog();
|
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:
|
private:
|
||||||
// Overridden from MessageLoop::Dispatcher:
|
// Overridden from MessageLoop::Dispatcher:
|
||||||
|
@ -63,11 +71,13 @@ class MessageDialog : public base::MessageLoop::Dispatcher,
|
||||||
const ui::Event& event) OVERRIDE;
|
const ui::Event& event) OVERRIDE;
|
||||||
|
|
||||||
bool should_close_;
|
bool should_close_;
|
||||||
|
bool delete_on_close_;
|
||||||
int result_;
|
int result_;
|
||||||
string16 title_;
|
string16 title_;
|
||||||
views::Widget* widget_;
|
views::Widget* widget_;
|
||||||
views::MessageBoxView* message_box_view_;
|
views::MessageBoxView* message_box_view_;
|
||||||
std::vector<views::LabelButton*> buttons_;
|
std::vector<views::LabelButton*> buttons_;
|
||||||
|
MessageBoxCallback callback_;
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(MessageDialog);
|
DISALLOW_COPY_AND_ASSIGN(MessageDialog);
|
||||||
};
|
};
|
||||||
|
@ -82,6 +92,7 @@ MessageDialog::MessageDialog(NativeWindow* parent_window,
|
||||||
const std::string& message,
|
const std::string& message,
|
||||||
const std::string& detail)
|
const std::string& detail)
|
||||||
: should_close_(false),
|
: should_close_(false),
|
||||||
|
delete_on_close_(false),
|
||||||
result_(-1),
|
result_(-1),
|
||||||
title_(UTF8ToUTF16(title)),
|
title_(UTF8ToUTF16(title)),
|
||||||
widget_(NULL),
|
widget_(NULL),
|
||||||
|
@ -124,12 +135,30 @@ MessageDialog::MessageDialog(NativeWindow* parent_window,
|
||||||
|
|
||||||
set_background(views::Background::CreateSolidBackground(
|
set_background(views::Background::CreateSolidBackground(
|
||||||
skia::COLORREFToSkColor(GetSysColor(COLOR_WINDOW))));
|
skia::COLORREFToSkColor(GetSysColor(COLOR_WINDOW))));
|
||||||
widget_->Show();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MessageDialog::~MessageDialog() {
|
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:
|
// MessageDialog, private:
|
||||||
|
|
||||||
|
@ -145,6 +174,11 @@ string16 MessageDialog::GetWindowTitle() const {
|
||||||
|
|
||||||
void MessageDialog::WindowClosing() {
|
void MessageDialog::WindowClosing() {
|
||||||
should_close_ = true;
|
should_close_ = true;
|
||||||
|
|
||||||
|
if (delete_on_close_) {
|
||||||
|
callback_.Run(GetResult());
|
||||||
|
base::MessageLoop::current()->DeleteSoon(FROM_HERE, this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
views::Widget* MessageDialog::GetWidget() {
|
views::Widget* MessageDialog::GetWidget() {
|
||||||
|
@ -232,6 +266,7 @@ int ShowMessageBox(NativeWindow* parent_window,
|
||||||
const std::string& message,
|
const std::string& message,
|
||||||
const std::string& detail) {
|
const std::string& detail) {
|
||||||
MessageDialog dialog(parent_window, type, buttons, title, message, detail);
|
MessageDialog dialog(parent_window, type, buttons, title, message, detail);
|
||||||
|
dialog.Show();
|
||||||
{
|
{
|
||||||
base::MessageLoop::ScopedNestableTaskAllower allow(
|
base::MessageLoop::ScopedNestableTaskAllower allow(
|
||||||
base::MessageLoopForUI::current());
|
base::MessageLoopForUI::current());
|
||||||
|
@ -239,18 +274,21 @@ int ShowMessageBox(NativeWindow* parent_window,
|
||||||
run_loop.Run();
|
run_loop.Run();
|
||||||
}
|
}
|
||||||
|
|
||||||
// When the dialog is closed without choosing anything, we think the user
|
return dialog.GetResult();
|
||||||
// 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 0;
|
void ShowMessageBox(NativeWindow* parent_window,
|
||||||
} else {
|
MessageBoxType type,
|
||||||
return dialog.result();
|
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
|
} // namespace atom
|
||||||
|
|
|
@ -4,8 +4,7 @@
|
||||||
|
|
||||||
// Multiply-included file, no traditional include guard.
|
// Multiply-included file, no traditional include guard.
|
||||||
|
|
||||||
#include <string>
|
#include "base/string16.h"
|
||||||
|
|
||||||
#include "base/values.h"
|
#include "base/values.h"
|
||||||
#include "common/draggable_region.h"
|
#include "common/draggable_region.h"
|
||||||
#include "content/public/common/common_param_traits.h"
|
#include "content/public/common/common_param_traits.h"
|
||||||
|
@ -22,16 +21,16 @@ IPC_STRUCT_TRAITS_BEGIN(atom::DraggableRegion)
|
||||||
IPC_STRUCT_TRAITS_END()
|
IPC_STRUCT_TRAITS_END()
|
||||||
|
|
||||||
IPC_MESSAGE_ROUTED2(AtomViewHostMsg_Message,
|
IPC_MESSAGE_ROUTED2(AtomViewHostMsg_Message,
|
||||||
std::string /* channel */,
|
string16 /* channel */,
|
||||||
ListValue /* arguments */)
|
ListValue /* arguments */)
|
||||||
|
|
||||||
IPC_SYNC_MESSAGE_ROUTED2_1(AtomViewHostMsg_Message_Sync,
|
IPC_SYNC_MESSAGE_ROUTED2_1(AtomViewHostMsg_Message_Sync,
|
||||||
std::string /* channel */,
|
string16 /* channel */,
|
||||||
ListValue /* arguments */,
|
ListValue /* arguments */,
|
||||||
DictionaryValue /* result */)
|
string16 /* result (in JSON) */)
|
||||||
|
|
||||||
IPC_MESSAGE_ROUTED2(AtomViewMsg_Message,
|
IPC_MESSAGE_ROUTED2(AtomViewMsg_Message,
|
||||||
std::string /* channel */,
|
string16 /* channel */,
|
||||||
ListValue /* arguments */)
|
ListValue /* arguments */)
|
||||||
|
|
||||||
// Sent by the renderer when the draggable regions are updated.
|
// 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
|
* `routingId` Integer
|
||||||
|
|
||||||
Emitted when renderer sent a synchronous message to the browser. The receiver
|
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
|
**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
|
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:
|
// In browser:
|
||||||
var ipc = require('ipc');
|
var ipc = require('ipc');
|
||||||
ipc.on('browser-data-request', function(event, processId, routingId, message) {
|
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 "base/values.h"
|
||||||
#include "common/api/api_messages.h"
|
#include "common/api/api_messages.h"
|
||||||
|
#include "common/v8_conversions.h"
|
||||||
#include "content/public/renderer/render_view.h"
|
#include "content/public/renderer/render_view.h"
|
||||||
#include "content/public/renderer/v8_value_converter.h"
|
#include "content/public/renderer/v8_value_converter.h"
|
||||||
#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.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())
|
if (!args[0]->IsString())
|
||||||
return node::ThrowTypeError("Bad argument");
|
return node::ThrowTypeError("Bad argument");
|
||||||
|
|
||||||
std::string channel(*v8::String::Utf8Value(args[0]));
|
string16 channel = FromV8Value(args[0]);
|
||||||
|
|
||||||
RenderView* render_view = GetCurrentRenderView();
|
RenderView* render_view = GetCurrentRenderView();
|
||||||
|
|
||||||
// Convert Arguments to Array, so we can use V8ValueConverter to convert it
|
// 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");
|
return node::ThrowTypeError("Bad argument");
|
||||||
|
|
||||||
v8::Handle<v8::Context> context = v8::Context::GetCurrent();
|
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
|
// Convert Arguments to Array, so we can use V8ValueConverter to convert it
|
||||||
// to ListValue.
|
// to ListValue.
|
||||||
|
@ -97,12 +97,12 @@ v8::Handle<v8::Value> RendererIPC::SendSync(const v8::Arguments &args) {
|
||||||
|
|
||||||
RenderView* render_view = GetCurrentRenderView();
|
RenderView* render_view = GetCurrentRenderView();
|
||||||
|
|
||||||
base::DictionaryValue result;
|
string16 json;
|
||||||
IPC::SyncMessage* message = new AtomViewHostMsg_Message_Sync(
|
IPC::SyncMessage* message = new AtomViewHostMsg_Message_Sync(
|
||||||
render_view->GetRoutingID(),
|
render_view->GetRoutingID(),
|
||||||
channel,
|
channel,
|
||||||
*static_cast<base::ListValue*>(arguments.get()),
|
*static_cast<base::ListValue*>(arguments.get()),
|
||||||
&result);
|
&json);
|
||||||
// Enable the UI thread in browser to receive messages.
|
// Enable the UI thread in browser to receive messages.
|
||||||
message->EnableMessagePumping();
|
message->EnableMessagePumping();
|
||||||
bool success = render_view->Send(message);
|
bool success = render_view->Send(message);
|
||||||
|
@ -110,7 +110,7 @@ v8::Handle<v8::Value> RendererIPC::SendSync(const v8::Arguments &args) {
|
||||||
if (!success)
|
if (!success)
|
||||||
return node::ThrowError("Unable to send AtomViewHostMsg_Message_Sync");
|
return node::ThrowError("Unable to send AtomViewHostMsg_Message_Sync");
|
||||||
|
|
||||||
return scope.Close(converter->ToV8Value(&result, context));
|
return scope.Close(ToV8Value(json));
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
#include "base/logging.h"
|
#include "base/logging.h"
|
||||||
#include "base/values.h"
|
#include "base/values.h"
|
||||||
|
#include "common/v8_conversions.h"
|
||||||
#include "content/public/renderer/render_view.h"
|
#include "content/public/renderer/render_view.h"
|
||||||
#include "content/public/renderer/v8_value_converter.h"
|
#include "content/public/renderer/v8_value_converter.h"
|
||||||
#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
|
#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
|
||||||
|
@ -51,7 +52,7 @@ void AtomRendererBindings::BindToFrame(WebFrame* frame) {
|
||||||
AtomBindings::BindTo(GetProcessObject(context));
|
AtomBindings::BindTo(GetProcessObject(context));
|
||||||
}
|
}
|
||||||
|
|
||||||
void AtomRendererBindings::OnBrowserMessage(const std::string& channel,
|
void AtomRendererBindings::OnBrowserMessage(const string16& channel,
|
||||||
const base::ListValue& args) {
|
const base::ListValue& args) {
|
||||||
if (!render_view_->GetWebView())
|
if (!render_view_->GetWebView())
|
||||||
return;
|
return;
|
||||||
|
@ -70,7 +71,7 @@ void AtomRendererBindings::OnBrowserMessage(const std::string& channel,
|
||||||
|
|
||||||
std::vector<v8::Handle<v8::Value>> arguments;
|
std::vector<v8::Handle<v8::Value>> arguments;
|
||||||
arguments.reserve(1 + args.GetSize());
|
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++) {
|
for (size_t i = 0; i < args.GetSize(); i++) {
|
||||||
const base::Value* value;
|
const base::Value* value;
|
||||||
|
|
|
@ -5,10 +5,10 @@
|
||||||
#ifndef ATOM_RENDERER_API_ATOM_RENDERER_BINDINGS_H_
|
#ifndef ATOM_RENDERER_API_ATOM_RENDERER_BINDINGS_H_
|
||||||
#define ATOM_RENDERER_API_ATOM_RENDERER_BINDINGS_H_
|
#define ATOM_RENDERER_API_ATOM_RENDERER_BINDINGS_H_
|
||||||
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include "common/api/atom_bindings.h"
|
#include "common/api/atom_bindings.h"
|
||||||
|
|
||||||
|
#include "base/string16.h"
|
||||||
|
|
||||||
namespace base {
|
namespace base {
|
||||||
class ListValue;
|
class ListValue;
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,7 @@ class AtomRendererBindings : public AtomBindings {
|
||||||
void BindToFrame(WebKit::WebFrame* frame);
|
void BindToFrame(WebKit::WebFrame* frame);
|
||||||
|
|
||||||
// Dispatch messages from browser.
|
// Dispatch messages from browser.
|
||||||
void OnBrowserMessage(const std::string& channel,
|
void OnBrowserMessage(const string16& channel,
|
||||||
const base::ListValue& args);
|
const base::ListValue& args);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -16,9 +16,11 @@ class Ipc extends EventEmitter
|
||||||
ipc.send('ATOM_INTERNAL_MESSAGE', args...)
|
ipc.send('ATOM_INTERNAL_MESSAGE', args...)
|
||||||
|
|
||||||
sendSync: (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...) ->
|
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
|
module.exports = new Ipc
|
||||||
|
|
|
@ -72,6 +72,7 @@ metaToValue = (meta) ->
|
||||||
ret.__defineSetter__ member.name, (value) ->
|
ret.__defineSetter__ member.name, (value) ->
|
||||||
# Set member data.
|
# Set member data.
|
||||||
ipc.sendChannelSync 'ATOM_BROWSER_MEMBER_SET', meta.id, member.name, value
|
ipc.sendChannelSync 'ATOM_BROWSER_MEMBER_SET', meta.id, member.name, value
|
||||||
|
value
|
||||||
|
|
||||||
ret.__defineGetter__ member.name, ->
|
ret.__defineGetter__ member.name, ->
|
||||||
# Get member data.
|
# Get member data.
|
||||||
|
|
|
@ -101,7 +101,7 @@ bool AtomRenderViewObserver::OnMessageReceived(const IPC::Message& message) {
|
||||||
return handled;
|
return handled;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AtomRenderViewObserver::OnBrowserMessage(const std::string& channel,
|
void AtomRenderViewObserver::OnBrowserMessage(const string16& channel,
|
||||||
const base::ListValue& args) {
|
const base::ListValue& args) {
|
||||||
atom_bindings()->OnBrowserMessage(channel, args);
|
atom_bindings()->OnBrowserMessage(channel, args);
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,7 @@ class AtomRenderViewObserver : content::RenderViewObserver {
|
||||||
virtual void DraggableRegionsChanged(WebKit::WebFrame* frame) OVERRIDE;
|
virtual void DraggableRegionsChanged(WebKit::WebFrame* frame) OVERRIDE;
|
||||||
virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
|
virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
|
||||||
|
|
||||||
void OnBrowserMessage(const std::string& channel,
|
void OnBrowserMessage(const string16& channel,
|
||||||
const base::ListValue& args);
|
const base::ListValue& args);
|
||||||
|
|
||||||
scoped_ptr<AtomRendererBindings> atom_bindings_;
|
scoped_ptr<AtomRendererBindings> atom_bindings_;
|
||||||
|
|
|
@ -49,7 +49,12 @@ describe 'ipc', ->
|
||||||
describe 'ipc.send', ->
|
describe 'ipc.send', ->
|
||||||
it 'should work when sending an object containing id property', (done) ->
|
it 'should work when sending an object containing id property', (done) ->
|
||||||
obj = id: 1, name: 'ly'
|
obj = id: 1, name: 'ly'
|
||||||
ipc.on 'message', (message) ->
|
ipc.once 'message', (message) ->
|
||||||
assert.deepEqual message, obj
|
assert.deepEqual message, obj
|
||||||
done()
|
done()
|
||||||
ipc.send obj
|
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) {
|
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() {
|
process.on('uncaughtException', function() {
|
||||||
|
|
Loading…
Reference in a new issue