diff --git a/atom.gyp b/atom.gyp index a86e09eea37..a69667f2af6 100644 --- a/atom.gyp +++ b/atom.gyp @@ -68,6 +68,10 @@ 'atom/browser/api/atom_api_window.h', 'atom/browser/api/atom_browser_bindings.cc', 'atom/browser/api/atom_browser_bindings.h', + 'atom/browser/api/event.cc', + 'atom/browser/api/event.h', + 'atom/browser/api/event_emitter.cc', + 'atom/browser/api/event_emitter.h', 'atom/browser/auto_updater.cc', 'atom/browser/auto_updater.h', 'atom/browser/auto_updater_delegate.h', diff --git a/atom/browser/api/event.cc b/atom/browser/api/event.cc new file mode 100644 index 00000000000..16f464551b8 --- /dev/null +++ b/atom/browser/api/event.cc @@ -0,0 +1,61 @@ +// Copyright (c) 2014 GitHub, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "atom/browser/api/event.h" + +#include "atom/common/api/api_messages.h" +#include "atom/common/native_mate_converters/string16_converter.h" +#include "content/public/browser/web_contents.h" +#include "native_mate/object_template_builder.h" + +namespace mate { + +Event::Event() + : sender_(NULL), + message_(NULL), + prevent_default_(false) { +} + +Event::~Event() { +} + +ObjectTemplateBuilder Event::GetObjectTemplateBuilder(v8::Isolate* isolate) { + return ObjectTemplateBuilder(isolate) + .SetMethod("preventDefault", &Event::PreventDefault) + .SetMethod("sendReply", &Event::SendReply); +} + +void Event::SetSenderAndMessage(content::WebContents* sender, + IPC::Message* message) { + DCHECK(!sender_); + DCHECK(!message_); + sender_ = sender; + message_ = message; + + Observe(sender); +} + +void Event::WebContentsDestroyed(content::WebContents* web_contents) { + sender_ = NULL; + message_ = NULL; +} + +void Event::PreventDefault() { + prevent_default_ = true; +} + +bool Event::SendReply(const string16& json) { + if (message_ == NULL || sender_ == NULL) + return false; + + AtomViewHostMsg_Message_Sync::WriteReplyParams(message_, json); + return sender_->Send(message_); +} + +// static +Handle Event::Create(v8::Isolate* isolate) { + return CreateHandle(isolate, new Event); +} + +} // namespace mate diff --git a/atom/browser/api/event.h b/atom/browser/api/event.h new file mode 100644 index 00000000000..bf22079291f --- /dev/null +++ b/atom/browser/api/event.h @@ -0,0 +1,57 @@ +// Copyright (c) 2014 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 ATOM_BROWSER_API_EVENT_H_ +#define ATOM_BROWSER_API_EVENT_H_ + +#include "content/public/browser/web_contents_observer.h" +#include "native_mate/wrappable.h" +#include "native_mate/handle.h" + +namespace IPC { +class Message; +} + +namespace mate { + +class Event : public Wrappable, + public content::WebContentsObserver { + public: + static Handle Create(v8::Isolate* isolate); + + // Pass the sender and message to be replied. + void SetSenderAndMessage(content::WebContents* sender, IPC::Message* message); + + // event.PreventDefault(). + void PreventDefault(); + + // event.sendReply(json), used for replying synchronous message. + bool SendReply(const string16& json); + + // Whether event.preventDefault() is called. + bool prevent_default() const { return prevent_default_; } + + protected: + Event(); + virtual ~Event(); + + // Wrappable implementations: + virtual ObjectTemplateBuilder GetObjectTemplateBuilder(v8::Isolate* isolate); + + // content::WebContentsObserver implementations: + virtual void WebContentsDestroyed(content::WebContents*) OVERRIDE; + + private: + // Replyer for the synchronous messages. + content::WebContents* sender_; + IPC::Message* message_; + + bool prevent_default_; + + DISALLOW_COPY_AND_ASSIGN(Event); +}; + +} // namespace mate + +#endif // ATOM_BROWSER_API_EVENT_H_ diff --git a/atom/browser/api/event_emitter.cc b/atom/browser/api/event_emitter.cc new file mode 100644 index 00000000000..5192c63488e --- /dev/null +++ b/atom/browser/api/event_emitter.cc @@ -0,0 +1,53 @@ +// Copyright (c) 2014 GitHub, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "atom/browser/api/event_emitter.h" + +#include + +#include "atom/browser/api/event.h" +#include "atom/common/native_mate_converters/v8_value_converter.h" +#include "base/memory/scoped_ptr.h" +#include "base/values.h" + +#include "atom/common/node_includes.h" + +namespace mate { + +EventEmitter::EventEmitter() { +} + +bool EventEmitter::Emit(const base::StringPiece& name) { + return Emit(name, base::ListValue()); +} + +bool EventEmitter::Emit(const base::StringPiece& name, + const base::ListValue& args) { + v8::Locker locker(node_isolate); + v8::HandleScope handle_scope(node_isolate); + + v8::Handle context = v8::Context::GetCurrent(); + scoped_ptr converter(new atom::V8ValueConverter); + + mate::Handle event = mate::Event::Create(node_isolate); + + // v8_args = [name, event, args...]; + std::vector> v8_args; + v8_args.reserve(args.GetSize() + 2); + v8_args.push_back(mate::StringToV8(node_isolate, name)); + v8_args.push_back(event.ToV8()); + for (size_t i = 0; i < args.GetSize(); i++) { + const base::Value* value(NULL); + if (args.Get(i, &value)) + v8_args.push_back(converter->ToV8Value(value, context)); + } + + // this.emit.apply(this, v8_args); + node::MakeCallback( + GetWrapper(node_isolate), "emit", v8_args.size(), &v8_args[0]); + + return event->prevent_default(); +} + +} // namespace mate diff --git a/atom/browser/api/event_emitter.h b/atom/browser/api/event_emitter.h new file mode 100644 index 00000000000..44e586c020d --- /dev/null +++ b/atom/browser/api/event_emitter.h @@ -0,0 +1,33 @@ +// Copyright (c) 2014 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 ATOM_BROWSER_API_EVENT_EMITTER_H_ +#define ATOM_BROWSER_API_EVENT_EMITTER_H_ + +#include "native_mate/wrappable.h" + +namespace base { +class ListValue; +} + +namespace mate { + +// Provide helperers to emit event in JavaScript. +class EventEmitter : public Wrappable { + protected: + EventEmitter(); + + // this.emit(name); + bool Emit(const base::StringPiece& name); + + // this.emit(name, args...); + bool Emit(const base::StringPiece& name, const base::ListValue& args); + + private: + DISALLOW_COPY_AND_ASSIGN(EventEmitter); +}; + +} // namespace mate + +#endif // ATOM_BROWSER_API_EVENT_EMITTER_H_