Revert "Make BrowserWindow inheritable. Fixed #23."
This reverts commit 5a0aab2e4f
.
This commit is contained in:
parent
3d267e2a9f
commit
dbaf8860a6
6 changed files with 47 additions and 95 deletions
|
@ -20,6 +20,13 @@ namespace api {
|
||||||
|
|
||||||
EventEmitter::EventEmitter(v8::Handle<v8::Object> wrapper) {
|
EventEmitter::EventEmitter(v8::Handle<v8::Object> wrapper) {
|
||||||
Wrap(wrapper);
|
Wrap(wrapper);
|
||||||
|
|
||||||
|
// process.emit('ATOM_BROWSER_INTERNAL_NEW', this).
|
||||||
|
v8::Handle<v8::Value> args[] = {
|
||||||
|
v8::String::New("ATOM_BROWSER_INTERNAL_NEW"),
|
||||||
|
wrapper,
|
||||||
|
};
|
||||||
|
node::MakeCallback(node::process, "emit", 2, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
EventEmitter::~EventEmitter() {
|
EventEmitter::~EventEmitter() {
|
||||||
|
@ -64,26 +71,6 @@ bool EventEmitter::Emit(const std::string& name, base::ListValue* args) {
|
||||||
return prevent_default;
|
return prevent_default;
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
|
||||||
v8::Handle<v8::Value> EventEmitter::FromConstructorTemplate(
|
|
||||||
v8::Persistent<v8::FunctionTemplate> t,
|
|
||||||
const v8::Arguments& args) {
|
|
||||||
v8::Handle<v8::Value> new_object = node::FromConstructorTemplate(t, args);
|
|
||||||
args.This()->SetHiddenValue(v8::String::New("native_object"), new_object);
|
|
||||||
return new_object;
|
|
||||||
}
|
|
||||||
|
|
||||||
// static
|
|
||||||
v8::Handle<v8::Object> EventEmitter::SearchNativeObject(
|
|
||||||
v8::Handle<v8::Object> handle) {
|
|
||||||
if (handle->InternalFieldCount() > 0)
|
|
||||||
return handle;
|
|
||||||
|
|
||||||
// If the object is not a native object, we assume the native object is
|
|
||||||
// stored in it.
|
|
||||||
return handle->GetHiddenValue(v8::String::New("native_object"))->ToObject();
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace api
|
} // namespace api
|
||||||
|
|
||||||
} // namespace atom
|
} // namespace atom
|
||||||
|
|
|
@ -29,37 +29,12 @@ class EventEmitter : public node::ObjectWrap {
|
||||||
bool Emit(const std::string& name);
|
bool Emit(const std::string& name);
|
||||||
bool Emit(const std::string& name, base::ListValue* args);
|
bool Emit(const std::string& name, base::ListValue* args);
|
||||||
|
|
||||||
// Same with Unwrap but if the handle is not a native object, which happened
|
|
||||||
// when user inherits a native class, we would search for the native object,
|
|
||||||
// otherwise we won't get the correct C++ object.
|
|
||||||
template <typename T>
|
|
||||||
static inline bool SafeUnwrap(v8::Handle<v8::Object> handle, T** pointer) {
|
|
||||||
v8::Handle<v8::Object> real_handle = SearchNativeObject(handle);
|
|
||||||
if (real_handle->InternalFieldCount() == 0)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
*pointer = Unwrap<T>(real_handle);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Helper function to call "new" when constructor is called as normal
|
|
||||||
// function, this usually happens when inheriting native class.
|
|
||||||
//
|
|
||||||
// This function also does some special hacks to make sure the inheritance
|
|
||||||
// would work, because normal inheritance would not inherit internal fields.
|
|
||||||
static v8::Handle<v8::Value> FromConstructorTemplate(
|
|
||||||
v8::Persistent<v8::FunctionTemplate> t,
|
|
||||||
const v8::Arguments& args);
|
|
||||||
|
|
||||||
// Small accessor to return handle_, this follows Google C++ Style.
|
// Small accessor to return handle_, this follows Google C++ Style.
|
||||||
v8::Persistent<v8::Object> handle() const { return handle_; }
|
v8::Persistent<v8::Object> handle() const { return handle_; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
explicit EventEmitter(v8::Handle<v8::Object> wrapper);
|
explicit EventEmitter(v8::Handle<v8::Object> wrapper);
|
||||||
|
|
||||||
static v8::Handle<v8::Object> SearchNativeObject(
|
|
||||||
v8::Handle<v8::Object> handle);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DISALLOW_COPY_AND_ASSIGN(EventEmitter);
|
DISALLOW_COPY_AND_ASSIGN(EventEmitter);
|
||||||
};
|
};
|
||||||
|
|
|
@ -19,13 +19,9 @@ using content::NavigationController;
|
||||||
using node::ObjectWrap;
|
using node::ObjectWrap;
|
||||||
|
|
||||||
#define UNWRAP_WINDOW_AND_CHECK \
|
#define UNWRAP_WINDOW_AND_CHECK \
|
||||||
Window* self; \
|
Window* self = ObjectWrap::Unwrap<Window>(args.This()); \
|
||||||
if (SafeUnwrap<Window>(args.This(), &self)) { \
|
|
||||||
if (self == NULL) \
|
if (self == NULL) \
|
||||||
return node::ThrowError("Window is already destroyed"); \
|
return node::ThrowError("Window is already destroyed")
|
||||||
} else { \
|
|
||||||
return node::ThrowTypeError("Window methods are not generic");\
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace atom {
|
namespace atom {
|
||||||
|
|
||||||
|
@ -40,9 +36,6 @@ v8::Handle<v8::String> UTF16ToV8String(const string16& s) {
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
// static
|
|
||||||
v8::Persistent<v8::FunctionTemplate> Window::constructor_template_;
|
|
||||||
|
|
||||||
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)) {
|
||||||
|
@ -92,11 +85,11 @@ void Window::OnRendererCrashed() {
|
||||||
|
|
||||||
// static
|
// static
|
||||||
v8::Handle<v8::Value> Window::New(const v8::Arguments &args) {
|
v8::Handle<v8::Value> Window::New(const v8::Arguments &args) {
|
||||||
if (!args.IsConstructCall())
|
|
||||||
return FromConstructorTemplate(constructor_template_, args);
|
|
||||||
|
|
||||||
v8::HandleScope scope;
|
v8::HandleScope scope;
|
||||||
|
|
||||||
|
if (!args.IsConstructCall())
|
||||||
|
return node::ThrowError("Require constructor call");
|
||||||
|
|
||||||
if (!args[0]->IsObject())
|
if (!args[0]->IsObject())
|
||||||
return node::ThrowTypeError("Need options creating Window");
|
return node::ThrowTypeError("Need options creating Window");
|
||||||
|
|
||||||
|
@ -650,10 +643,7 @@ void Window::Initialize(v8::Handle<v8::Object> target) {
|
||||||
|
|
||||||
v8::Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(Window::New);
|
v8::Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(Window::New);
|
||||||
t->InstanceTemplate()->SetInternalFieldCount(1);
|
t->InstanceTemplate()->SetInternalFieldCount(1);
|
||||||
t->SetClassName(v8::String::NewSymbol("Window"));
|
t->SetClassName(v8::String::NewSymbol("BrowserWindow"));
|
||||||
|
|
||||||
constructor_template_ = v8::Persistent<v8::FunctionTemplate>::New(
|
|
||||||
node::node_isolate, t);
|
|
||||||
|
|
||||||
NODE_SET_PROTOTYPE_METHOD(t, "destroy", Destroy);
|
NODE_SET_PROTOTYPE_METHOD(t, "destroy", Destroy);
|
||||||
NODE_SET_PROTOTYPE_METHOD(t, "close", Close);
|
NODE_SET_PROTOTYPE_METHOD(t, "close", Close);
|
||||||
|
@ -713,7 +703,7 @@ void Window::Initialize(v8::Handle<v8::Object> target) {
|
||||||
NODE_SET_PROTOTYPE_METHOD(t, "reload", Reload);
|
NODE_SET_PROTOTYPE_METHOD(t, "reload", Reload);
|
||||||
NODE_SET_PROTOTYPE_METHOD(t, "reloadIgnoringCache", ReloadIgnoringCache);
|
NODE_SET_PROTOTYPE_METHOD(t, "reloadIgnoringCache", ReloadIgnoringCache);
|
||||||
|
|
||||||
target->Set(v8::String::NewSymbol("Window"), t->GetFunction());
|
target->Set(v8::String::NewSymbol("BrowserWindow"), t->GetFunction());
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace api
|
} // namespace api
|
||||||
|
|
|
@ -105,8 +105,6 @@ class Window : public EventEmitter,
|
||||||
static v8::Handle<v8::Value> Reload(const v8::Arguments &args);
|
static v8::Handle<v8::Value> Reload(const v8::Arguments &args);
|
||||||
static v8::Handle<v8::Value> ReloadIgnoringCache(const v8::Arguments &args);
|
static v8::Handle<v8::Value> ReloadIgnoringCache(const v8::Arguments &args);
|
||||||
|
|
||||||
static v8::Persistent<v8::FunctionTemplate> constructor_template_;
|
|
||||||
|
|
||||||
scoped_ptr<NativeWindow> window_;
|
scoped_ptr<NativeWindow> window_;
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(Window);
|
DISALLOW_COPY_AND_ASSIGN(Window);
|
||||||
|
|
|
@ -2,17 +2,10 @@ EventEmitter = require('events').EventEmitter
|
||||||
v8Util = process.atomBinding 'v8_util'
|
v8Util = process.atomBinding 'v8_util'
|
||||||
objectsRegistry = require '../../atom/objects-registry.js'
|
objectsRegistry = require '../../atom/objects-registry.js'
|
||||||
|
|
||||||
Window = process.atomBinding('window').Window
|
BrowserWindow = process.atomBinding('window').BrowserWindow
|
||||||
Window::__proto__ = EventEmitter.prototype
|
BrowserWindow::__proto__ = EventEmitter.prototype
|
||||||
|
|
||||||
module.exports = class BrowserWindow extends Window
|
BrowserWindow::toggleDevTools = ->
|
||||||
constructor: ->
|
|
||||||
super
|
|
||||||
|
|
||||||
# Remember all BrowserWindows.
|
|
||||||
process.emit 'ATOM_BROWSER_INTERNAL_NEW_BROWSER_WINDOW', this
|
|
||||||
|
|
||||||
toggleDevTools: ->
|
|
||||||
opened = v8Util.getHiddenValue this, 'devtoolsOpened'
|
opened = v8Util.getHiddenValue this, 'devtoolsOpened'
|
||||||
if opened
|
if opened
|
||||||
@closeDevTools()
|
@closeDevTools()
|
||||||
|
@ -21,14 +14,16 @@ module.exports = class BrowserWindow extends Window
|
||||||
@openDevTools()
|
@openDevTools()
|
||||||
v8Util.setHiddenValue this, 'devtoolsOpened', true
|
v8Util.setHiddenValue this, 'devtoolsOpened', true
|
||||||
|
|
||||||
restart: ->
|
BrowserWindow::restart = ->
|
||||||
@loadUrl @getUrl()
|
@loadUrl(@getUrl())
|
||||||
|
|
||||||
@getFocusedWindow: ->
|
BrowserWindow.getFocusedWindow = ->
|
||||||
windows = objectsRegistry.getAllWindows()
|
windows = objectsRegistry.getAllWindows()
|
||||||
return window for window in windows when window.isFocused()
|
return window for window in windows when window.isFocused()
|
||||||
|
|
||||||
@fromProcessIdAndRoutingId = (processId, routingId) ->
|
BrowserWindow.fromProcessIdAndRoutingId = (processId, routingId) ->
|
||||||
windows = objectsRegistry.getAllWindows()
|
windows = objectsRegistry.getAllWindows()
|
||||||
return window for window in windows when window.getProcessId() == processId and
|
return window for window in windows when window.getProcessId() == processId and
|
||||||
window.getRoutingId() == routingId
|
window.getRoutingId() == routingId
|
||||||
|
|
||||||
|
module.exports = BrowserWindow
|
||||||
|
|
|
@ -47,8 +47,15 @@ objectsWeakMap.add = (obj) ->
|
||||||
|
|
||||||
windowsWeakMap = new IDWeakMap
|
windowsWeakMap = new IDWeakMap
|
||||||
|
|
||||||
process.on 'ATOM_BROWSER_INTERNAL_NEW_BROWSER_WINDOW', (obj) ->
|
process.on 'ATOM_BROWSER_INTERNAL_NEW', (obj) ->
|
||||||
# Remember all windows.
|
# It's possible that user created a object in browser side and then want to
|
||||||
|
# get it in renderer via remote.getObject. So we must add every native object
|
||||||
|
# created in browser to the weak map even it may not be referenced by the
|
||||||
|
# renderer.
|
||||||
|
objectsWeakMap.add obj
|
||||||
|
|
||||||
|
# Also remember all windows.
|
||||||
|
if obj.constructor is BrowserWindow
|
||||||
id = windowsWeakMap.add obj
|
id = windowsWeakMap.add obj
|
||||||
obj.on 'destroyed', ->
|
obj.on 'destroyed', ->
|
||||||
windowsWeakMap.remove id
|
windowsWeakMap.remove id
|
||||||
|
|
Loading…
Reference in a new issue