Emit 'page-title-updated' as javascript event for window.

This commit is contained in:
Cheng Zhao 2013-04-18 23:50:47 +08:00
parent 1309d04ca7
commit d3e4db7ba3
9 changed files with 82 additions and 4 deletions

View file

@ -4,6 +4,14 @@
#include "browser/api/atom_api_event_emitter.h"
#include <vector>
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/values.h"
#include "browser/api/atom_api_event.h"
#include "common/v8_value_converter_impl.h"
namespace atom {
namespace api {
@ -15,6 +23,40 @@ EventEmitter::EventEmitter(v8::Handle<v8::Object> wrapper) {
EventEmitter::~EventEmitter() {
}
bool EventEmitter::Emit(const std::string& name, base::ListValue* args) {
v8::HandleScope scope;
v8::Handle<v8::Context> context = v8::Context::GetCurrent();
scoped_ptr<content::V8ValueConverter> converter(new V8ValueConverterImpl);
v8::Handle<v8::Object> v8_event = Event::CreateV8Object();
Event* event = Event::Unwrap<Event>(v8_event);
// Generate arguments for calling handle.emit.
std::vector<v8::Handle<v8::Value>> v8_args;
v8_args.reserve(args->GetSize() + 2);
v8_args.push_back(v8::String::New(name.c_str(), name.size()));
v8_args.push_back(v8_event);
for (size_t i = 0; i < args->GetSize(); i++) {
base::Value* value = NULL;
if (args->Get(i, &value)) {
DCHECK(value);
v8_args.push_back(converter->ToV8Value(value, context));
} else {
NOTREACHED() << "Wrong offset " << i << " for " << *args;
}
}
node::MakeCallback(handle(), "emit", v8_args.size(), &v8_args[0]);
bool prevent_default = event->prevent_default();
// Don't wait for V8 GC, delete it immediately.
delete event;
return prevent_default;
}
} // namespace api
} // namespace atom

View file

@ -5,9 +5,15 @@
#ifndef ATOM_BROWSER_API_ATOM_API_EVENT_EMITTER_H_
#define ATOM_BROWSER_API_ATOM_API_EVENT_EMITTER_H_
#include <iosfwd>
#include "base/basictypes.h"
#include "vendor/node/src/node_object_wrap.h"
namespace base {
class ListValue;
}
namespace atom {
namespace api {
@ -19,6 +25,9 @@ class EventEmitter : public node::ObjectWrap {
public:
virtual ~EventEmitter();
// Emit an event and returns whether the handler has called preventDefault().
bool Emit(const std::string& name, base::ListValue* args);
// Small accessor to return handle_, this follows Google C++ Style.
v8::Persistent<v8::Object>& handle() { return handle_; }

View file

@ -34,11 +34,19 @@ Window::Window(v8::Handle<v8::Object> wrapper, base::DictionaryValue* options)
: EventEmitter(wrapper),
window_(NativeWindow::Create(AtomBrowserContext::Get(), options)) {
window_->InitFromOptions(options);
window_->AddObserver(this);
}
Window::~Window() {
}
void Window::OnPageTitleUpdated(bool* prevent_default,
const std::string& title) {
scoped_ptr<base::ListValue> args(new base::ListValue);
args->AppendString(title);
*prevent_default = Emit("page-title-updated", args.get());
}
// static
v8::Handle<v8::Value> Window::New(const v8::Arguments &args) {
v8::HandleScope scope;

View file

@ -5,7 +5,9 @@
#ifndef ATOM_BROWSER_API_ATOM_API_WINDOW_H_
#define ATOM_BROWSER_API_ATOM_API_WINDOW_H_
#include "base/memory/scoped_ptr.h"
#include "browser/api/atom_api_event_emitter.h"
#include "browser/native_window_observer.h"
namespace base {
class DictionaryValue;
@ -17,7 +19,8 @@ class NativeWindow;
namespace api {
class Window : public EventEmitter {
class Window : public EventEmitter,
public NativeWindowObserver {
public:
virtual ~Window();
@ -29,6 +32,10 @@ class Window : public EventEmitter {
explicit Window(v8::Handle<v8::Object> wrapper,
base::DictionaryValue* options);
// Implementations of NativeWindowObserver.
virtual void OnPageTitleUpdated(bool* prevent_default,
const std::string& title) OVERRIDE;
private:
static v8::Handle<v8::Value> New(const v8::Arguments &args);
static v8::Handle<v8::Value> Destroy(const v8::Arguments &args);

View file

@ -27,14 +27,12 @@ AtomBindings::~AtomBindings() {
void AtomBindings::BindTo(v8::Handle<v8::Object> process) {
v8::HandleScope scope;
v8::Context::Scope context_scope(node::g_context);
node::SetMethod(process, "atom_binding", Binding);
}
void AtomBindings::AfterLoad() {
v8::HandleScope scope;
v8::Context::Scope context_scope(node::g_context);
v8::Handle<v8::Object> global = node::g_context->Global();
v8::Handle<v8::Object> atom =

View file

@ -1,5 +1,11 @@
EventEmitter = require('events').EventEmitter
Window = process.atom_binding('window').Window
# Inherits EventEmitter.
for prop, func of EventEmitter.prototype
Window.prototype[prop] = func
# Convient accessors.
setupGetterAndSetter = (constructor, name, getter, setter) ->
constructor.prototype.__defineGetter__ name, ->

View file

@ -30,6 +30,9 @@ void AtomBrowserMainParts::PostEarlyInitialization() {
node_bindings_->Initialize();
// Wrap whole process in one global context.
node::g_context->Enter();
atom_bindings_->BindTo(node::process);
node_bindings_->Load();

View file

@ -6,4 +6,9 @@ var mainWindow = null;
atom.browserMainParts.preMainMessageLoopRun = function() {
mainWindow = new Window({ width: 800, height: 600 });
mainWindow.loadURL('file://' + __dirname + '/index.html');
mainWindow.on('page-title-updated', function(event, title) {
event.preventDefault();
this.title = 'Atom Shell - ' + title;
});
}

View file

@ -11,7 +11,7 @@ namespace atom {
class NativeWindowObserver {
public:
virtual ~NativeWindowObserver() {};
virtual ~NativeWindowObserver() {}
// Called when the web page of the window has updated it's document title.
virtual void OnPageTitleUpdated(bool* prevent_default,