Do not rely on Constructor to call Init

This makes it deterministic when the JavaScript is initialized, which
can make our logic more clear.
This commit is contained in:
Cheng Zhao 2016-08-02 15:15:40 +09:00
parent 84bb82866d
commit 1505a46ed0
11 changed files with 44 additions and 44 deletions

View file

@ -19,9 +19,10 @@ namespace atom {
namespace api { namespace api {
Menu::Menu(v8::Isolate* isolate) Menu::Menu(v8::Isolate* isolate, v8::Local<v8::Object> wrapper)
: model_(new AtomMenuModel(this)), : model_(new AtomMenuModel(this)),
parent_(nullptr) { parent_(nullptr) {
InitWith(isolate, wrapper);
} }
Menu::~Menu() { Menu::~Menu() {
@ -189,7 +190,7 @@ void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
using atom::api::Menu; using atom::api::Menu;
v8::Isolate* isolate = context->GetIsolate(); v8::Isolate* isolate = context->GetIsolate();
v8::Local<v8::Function> constructor = mate::CreateConstructor<Menu>( v8::Local<v8::Function> constructor = mate::CreateConstructor<Menu>(
isolate, "Menu", base::Bind(&Menu::Create)); isolate, "Menu", base::Bind(&Menu::New));
mate::Dictionary dict(isolate, exports); mate::Dictionary dict(isolate, exports);
dict.Set("Menu", static_cast<v8::Local<v8::Value>>(constructor)); dict.Set("Menu", static_cast<v8::Local<v8::Value>>(constructor));
#if defined(OS_MACOSX) #if defined(OS_MACOSX)

View file

@ -20,7 +20,7 @@ namespace api {
class Menu : public mate::TrackableObject<Menu>, class Menu : public mate::TrackableObject<Menu>,
public AtomMenuModel::Delegate { public AtomMenuModel::Delegate {
public: public:
static mate::WrappableBase* Create(v8::Isolate* isolate); static mate::WrappableBase* New(mate::Arguments* args);
static void BuildPrototype(v8::Isolate* isolate, static void BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::ObjectTemplate> prototype); v8::Local<v8::ObjectTemplate> prototype);
@ -36,7 +36,7 @@ class Menu : public mate::TrackableObject<Menu>,
AtomMenuModel* model() const { return model_.get(); } AtomMenuModel* model() const { return model_.get(); }
protected: protected:
explicit Menu(v8::Isolate* isolate); Menu(v8::Isolate* isolate, v8::Local<v8::Object> wrapper);
~Menu() override; ~Menu() override;
// mate::Wrappable: // mate::Wrappable:

View file

@ -17,7 +17,7 @@ namespace api {
class MenuMac : public Menu { class MenuMac : public Menu {
protected: protected:
explicit MenuMac(v8::Isolate* isolate); MenuMac(v8::Isolate* isolate, v8::Local<v8::Object> wrapper);
void PopupAt(Window* window, int x, int y, int positioning_item) override; void PopupAt(Window* window, int x, int y, int positioning_item) override;

View file

@ -18,7 +18,8 @@ namespace atom {
namespace api { namespace api {
MenuMac::MenuMac(v8::Isolate* isolate) : Menu(isolate) { MenuMac::MenuMac(v8::Isolate* isolate, v8::Local<v8::Object> wrapper)
: Menu(isolate, wrapper) {
} }
void MenuMac::PopupAt(Window* window, int x, int y, int positioning_item) { void MenuMac::PopupAt(Window* window, int x, int y, int positioning_item) {
@ -94,8 +95,8 @@ void Menu::SendActionToFirstResponder(const std::string& action) {
} }
// static // static
mate::WrappableBase* Menu::Create(v8::Isolate* isolate) { mate::WrappableBase* Menu::New(mate::Arguments* args) {
return new MenuMac(isolate); return new MenuMac(args->isolate(), args->GetThis());
} }
} // namespace api } // namespace api

View file

@ -14,7 +14,8 @@ namespace atom {
namespace api { namespace api {
MenuViews::MenuViews(v8::Isolate* isolate) : Menu(isolate) { MenuViews::MenuViews(v8::Isolate* isolate, v8::Local<v8::Object> wrapper)
: Menu(isolate, wrapper) {
} }
void MenuViews::PopupAt(Window* window, int x, int y, int positioning_item) { void MenuViews::PopupAt(Window* window, int x, int y, int positioning_item) {
@ -53,8 +54,8 @@ void MenuViews::PopupAt(Window* window, int x, int y, int positioning_item) {
} }
// static // static
mate::WrappableBase* Menu::Create(v8::Isolate* isolate) { mate::WrappableBase* Menu::New(mate::Arguments* args) {
return new MenuViews(isolate); return new MenuViews(args->isolate(), args->GetThis());
} }
} // namespace api } // namespace api

View file

@ -14,7 +14,7 @@ namespace api {
class MenuViews : public Menu { class MenuViews : public Menu {
public: public:
explicit MenuViews(v8::Isolate* isolate); MenuViews(v8::Isolate* isolate, v8::Local<v8::Object> wrapper);
protected: protected:
void PopupAt(Window* window, int x, int y, int positioning_item) override; void PopupAt(Window* window, int x, int y, int positioning_item) override;

View file

@ -60,10 +60,13 @@ namespace atom {
namespace api { namespace api {
Tray::Tray(v8::Isolate* isolate, mate::Handle<NativeImage> image) Tray::Tray(v8::Isolate* isolate, v8::Local<v8::Object> wrapper,
mate::Handle<NativeImage> image)
: tray_icon_(TrayIcon::Create()) { : tray_icon_(TrayIcon::Create()) {
SetImage(isolate, image); SetImage(isolate, image);
tray_icon_->AddObserver(this); tray_icon_->AddObserver(this);
InitWith(isolate, wrapper);
} }
Tray::~Tray() { Tray::~Tray() {
@ -72,14 +75,13 @@ Tray::~Tray() {
} }
// static // static
mate::WrappableBase* Tray::New(v8::Isolate* isolate, mate::WrappableBase* Tray::New(mate::Handle<NativeImage> image,
mate::Handle<NativeImage> image) { mate::Arguments* args) {
if (!Browser::Get()->is_ready()) { if (!Browser::Get()->is_ready()) {
isolate->ThrowException(v8::Exception::Error(mate::StringToV8( args->ThrowError("Cannot create Tray before app is ready");
isolate, "Cannot create Tray before app is ready")));
return nullptr; return nullptr;
} }
return new Tray(isolate, image); return new Tray(args->isolate(), args->GetThis(), image);
} }
void Tray::OnClicked(const gfx::Rect& bounds, int modifiers) { void Tray::OnClicked(const gfx::Rect& bounds, int modifiers) {

View file

@ -35,14 +35,15 @@ class NativeImage;
class Tray : public mate::TrackableObject<Tray>, class Tray : public mate::TrackableObject<Tray>,
public TrayIconObserver { public TrayIconObserver {
public: public:
static mate::WrappableBase* New( static mate::WrappableBase* New(mate::Handle<NativeImage> image,
v8::Isolate* isolate, mate::Handle<NativeImage> image); mate::Arguments* args);
static void BuildPrototype(v8::Isolate* isolate, static void BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::ObjectTemplate> prototype); v8::Local<v8::ObjectTemplate> prototype);
protected: protected:
Tray(v8::Isolate* isolate, mate::Handle<NativeImage> image); Tray(v8::Isolate* isolate, v8::Local<v8::Object> wrapper,
mate::Handle<NativeImage> image);
~Tray() override; ~Tray() override;
// TrayIconObserver: // TrayIconObserver:

View file

@ -67,7 +67,8 @@ v8::Local<v8::Value> ToBuffer(v8::Isolate* isolate, void* val, int size) {
} // namespace } // namespace
Window::Window(v8::Isolate* isolate, const mate::Dictionary& options) { Window::Window(v8::Isolate* isolate, v8::Local<v8::Object> wrapper,
const mate::Dictionary& options) {
// Use options.webPreferences to create WebContents. // Use options.webPreferences to create WebContents.
mate::Dictionary web_preferences = mate::Dictionary::CreateEmpty(isolate); mate::Dictionary web_preferences = mate::Dictionary::CreateEmpty(isolate);
options.Get(options::kWebPreferences, &web_preferences); options.Get(options::kWebPreferences, &web_preferences);
@ -107,7 +108,14 @@ Window::Window(v8::Isolate* isolate, const mate::Dictionary& options) {
window_->InitFromOptions(options); window_->InitFromOptions(options);
window_->AddObserver(this); window_->AddObserver(this);
InitWith(isolate, wrapper);
AttachAsUserData(window_.get()); AttachAsUserData(window_.get());
// We can only append this window to parent window's child windows after this
// window's JS wrapper gets initialized.
if (!parent.IsEmpty())
parent->child_windows_.Set(isolate, ID(), wrapper);
} }
Window::~Window() { Window::~Window() {
@ -119,17 +127,6 @@ Window::~Window() {
base::MessageLoop::current()->DeleteSoon(FROM_HERE, window_.release()); base::MessageLoop::current()->DeleteSoon(FROM_HERE, window_.release());
} }
void Window::AfterInit(v8::Isolate* isolate) {
mate::TrackableObject<Window>::AfterInit(isolate);
// We can only append this window to parent window's child windows after this
// window's JS wrapper gets initialized.
mate::Handle<Window> parent;
if (!parent_window_.IsEmpty() &&
mate::ConvertFromV8(isolate, GetParentWindow(), &parent))
parent->child_windows_.Set(isolate, ID(), GetWrapper());
}
void Window::WillCloseWindow(bool* prevent_default) { void Window::WillCloseWindow(bool* prevent_default) {
*prevent_default = Emit("close"); *prevent_default = Emit("close");
} }
@ -262,10 +259,9 @@ void Window::OnWindowMessage(UINT message, WPARAM w_param, LPARAM l_param) {
#endif #endif
// static // static
mate::WrappableBase* Window::New(v8::Isolate* isolate, mate::Arguments* args) { mate::WrappableBase* Window::New(mate::Arguments* args) {
if (!Browser::Get()->is_ready()) { if (!Browser::Get()->is_ready()) {
isolate->ThrowException(v8::Exception::Error(mate::StringToV8( args->ThrowError("Cannot create BrowserWindow before app is ready");
isolate, "Cannot create BrowserWindow before app is ready")));
return nullptr; return nullptr;
} }
@ -276,10 +272,10 @@ mate::WrappableBase* Window::New(v8::Isolate* isolate, mate::Arguments* args) {
mate::Dictionary options; mate::Dictionary options;
if (!(args->Length() == 1 && args->GetNext(&options))) { if (!(args->Length() == 1 && args->GetNext(&options))) {
options = mate::Dictionary::CreateEmpty(isolate); options = mate::Dictionary::CreateEmpty(args->isolate());
} }
return new Window(isolate, options); return new Window(args->isolate(), args->GetThis(), options);
} }
void Window::Close() { void Window::Close() {

View file

@ -40,7 +40,7 @@ class WebContents;
class Window : public mate::TrackableObject<Window>, class Window : public mate::TrackableObject<Window>,
public NativeWindowObserver { public NativeWindowObserver {
public: public:
static mate::WrappableBase* New(v8::Isolate* isolate, mate::Arguments* args); static mate::WrappableBase* New(mate::Arguments* args);
static void BuildPrototype(v8::Isolate* isolate, static void BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::ObjectTemplate> prototype); v8::Local<v8::ObjectTemplate> prototype);
@ -52,12 +52,10 @@ class Window : public mate::TrackableObject<Window>,
NativeWindow* window() const { return window_.get(); } NativeWindow* window() const { return window_.get(); }
protected: protected:
Window(v8::Isolate* isolate, const mate::Dictionary& options); Window(v8::Isolate* isolate, v8::Local<v8::Object> wrapper,
const mate::Dictionary& options);
~Window() override; ~Window() override;
// TrackableObject:
void AfterInit(v8::Isolate* isolate) override;
// NativeWindowObserver: // NativeWindowObserver:
void WillCloseWindow(bool* prevent_default) override; void WillCloseWindow(bool* prevent_default) override;
void WillDestoryNativeObject() override; void WillDestoryNativeObject() override;

2
vendor/native_mate vendored

@ -1 +1 @@
Subproject commit d9bfe6a49d8585916bd8dc77165154afeee4e5b6 Subproject commit bd20bde1a257b1b740dfeafc220c331ead3b66ab