#include "browser/api/atom_api_event.h"
+#include "common/api/api_messages.h"
#include "common/string16_conversions.h"
+#include "ipc/ipc_sender.h"
using node::node_isolate;
v8::Persistent<v8::FunctionTemplate> Event::constructor_template_;
Event::Event()
- : prevent_default_(false) {
+ : sender_(NULL),
+ message_(NULL),
+ prevent_default_(false) {
}
Event::~Event() {
constructor_template_->SetClassName(v8::String::NewSymbol("Event"));
NODE_SET_PROTOTYPE_METHOD(t, "preventDefault", PreventDefault);
+ NODE_SET_PROTOTYPE_METHOD(t, "sendReply", SendReply);
}
v8::Handle<v8::Object> v8_event =
return V8ValueToUTF16(json);
}
-v8::Handle<v8::Value> Event::New(const v8::Arguments &args) {
+
+void Event::SetSenderAndMessage(IPC::Sender* sender, IPC::Message* message) {
+ DCHECK(!sender_);
+ DCHECK(!message_);
+ sender_ = sender;
+ message_ = message;
+}
+
+// static
+v8::Handle<v8::Value> Event::New(const v8::Arguments& args) {
Event* event = new Event;
event->Wrap(args.This());
return args.This();
}
-v8::Handle<v8::Value> Event::PreventDefault(const v8::Arguments &args) {
+// static
+v8::Handle<v8::Value> Event::PreventDefault(const v8::Arguments& args) {
Event* event = Unwrap<Event>(args.This());
if (event == NULL)
return node::ThrowError("Event is already destroyed");
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->sender_ == NULL)
+ return node::ThrowError("Can only send reply to synchronous events");
+
+ string16 json = GetReturnValue(args.This());
+
+ AtomViewHostMsg_Message_Sync::WriteReplyParams(event->message_, json);
+ event->sender_->Send(event->message_);
+
+ return v8::Undefined();
+}
+
} // namespace api
} // namespace atom
#include "base/string16.h"
#include "vendor/node/src/node_object_wrap.h"
+namespace IPC {
+class Message;
+class Sender;
+}
+
namespace atom {
namespace api {
// Get JSON string of the event.returnValue from a Event object.
static string16 GetReturnValue(v8::Handle<v8::Object> event);
+ // Pass the sender and message to be replied.
+ void SetSenderAndMessage(IPC::Sender* sender, IPC::Message* message);
+
// Accessor to return handle_, this follows Google C++ Style.
v8::Persistent<v8::Object>& handle() { return handle_; }
Event();
private:
- static v8::Handle<v8::Value> New(const v8::Arguments &args);
- static v8::Handle<v8::Value> PreventDefault(const v8::Arguments &args);
+ static v8::Handle<v8::Value> New(const v8::Arguments& args);
+
+ static v8::Handle<v8::Value> PreventDefault(const v8::Arguments& args);
+ static v8::Handle<v8::Value> SendReply(const v8::Arguments& args);
static v8::Persistent<v8::FunctionTemplate> constructor_template_;
+ // Replyer for the synchronous messages.
+ IPC::Sender* sender_;
+ IPC::Message* message_;
+
bool prevent_default_;
DISALLOW_COPY_AND_ASSIGN(Event);
int routing_id,
const string16& channel,
const base::ListValue& args,
- string16* result) {
+ IPC::Sender* sender,
+ IPC::Message* message) {
v8::HandleScope scope;
v8::Handle<v8::Context> context = v8::Context::GetCurrent();
scoped_ptr<V8ValueConverter> converter(new V8ValueConverterImpl());
- v8::Handle<v8::Object> event = v8::Object::New();
+ // Create the event object.
+ v8::Handle<v8::Object> event = api::Event::CreateV8Object();
+ api::Event::Unwrap<api::Event>(event)->SetSenderAndMessage(sender, message);
// process.emit(channel, 'sync-message', event, process_id, routing_id);
std::vector<v8::Handle<v8::Value>> arguments;
}
node::MakeCallback(node::process, "emit", arguments.size(), &arguments[0]);
- *result = api::Event::GetReturnValue(event);
}
} // namespace atom
class ListValue;
}
+namespace IPC {
+class Message;
+class Sender;
+}
+
namespace atom {
class AtomBrowserBindings : public AtomBindings {
int routing_id,
const string16& channel,
const base::ListValue& args,
- string16* result);
+ IPC::Sender* sender,
+ IPC::Message* message);
// The require('atom').browserMainParts object.
v8::Handle<v8::Object> browser_main_parts() {
process.on 'ATOM_INTERNAL_MESSAGE', (args...) =>
@emit(args...)
process.on 'ATOM_INTERNAL_MESSAGE_SYNC', (channel, event, args...) =>
- returnValue = 'null'
+ returnValue = null
get = -> returnValue
- set = (value) -> returnValue = JSON.stringify(value)
+ set = (value) ->
+ throw new Error('returnValue can be only set once') if returnValue?
+ returnValue = JSON.stringify(value)
+ event.sendReply()
Object.defineProperty event, 'returnValue', {get, set}
Object.defineProperty event, 'result', {get, set}
void NativeWindow::OnRendererMessageSync(const string16& channel,
const base::ListValue& args,
IPC::Message* reply_msg) {
- string16 json;
AtomBrowserMainParts::Get()->atom_bindings()->OnRendererMessageSync(
GetWebContents()->GetRenderProcessHost()->GetID(),
GetWebContents()->GetRoutingID(),
channel,
args,
- &json);
-
- AtomViewHostMsg_Message_Sync::WriteReplyParams(reply_msg, json);
- Send(reply_msg);
+ this,
+ reply_msg);
}
} // namespace atom