diff options
author | ager@google.com <ager@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-01-13 11:46:47 +0000 |
---|---|---|
committer | ager@google.com <ager@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-01-13 11:46:47 +0000 |
commit | 2ce3d9dae916dda6c1ec91d013b71ba42179ce32 (patch) | |
tree | 438155d77a3b4b3cd4a5881189b38aeed6fc0753 | |
parent | c6b7e26081de7ea040aa9b56cbe0def4fe82145b (diff) | |
download | chromium_src-2ce3d9dae916dda6c1ec91d013b71ba42179ce32.zip chromium_src-2ce3d9dae916dda6c1ec91d013b71ba42179ce32.tar.gz chromium_src-2ce3d9dae916dda6c1ec91d013b71ba42179ce32.tar.bz2 |
Refactor the code that computes the receiver for an event listener.
The code can be shared for both types of event listeners and it should
use EventTargetToV8Object for converting the target to a V8 wrapper
object.
Additionally add an empty-handle check of the receiver object to fix a
crash bug.
Review URL: http://codereview.chromium.org/17643
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@7920 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | webkit/port/bindings/v8/v8_events.cpp | 106 | ||||
-rw-r--r-- | webkit/port/bindings/v8/v8_events.h | 13 | ||||
-rw-r--r-- | webkit/port/bindings/v8/v8_proxy.cpp | 1 |
3 files changed, 41 insertions, 79 deletions
diff --git a/webkit/port/bindings/v8/v8_events.cpp b/webkit/port/bindings/v8/v8_events.cpp index ff0ef27..d0ff3ba 100644 --- a/webkit/port/bindings/v8/v8_events.cpp +++ b/webkit/port/bindings/v8/v8_events.cpp @@ -146,6 +146,24 @@ void V8AbstractEventListener::DisposeListenerObject() { } +v8::Local<v8::Object> V8AbstractEventListener::GetReceiverObject( + Event* event, + bool isWindowEvent) { + if (!m_listener.IsEmpty() && !m_listener->IsFunction()) { + return v8::Local<v8::Object>::New(m_listener); + } + + if (isWindowEvent) { + return v8::Context::GetCurrent()->Global(); + } + + EventTarget* target = event->currentTarget(); + v8::Handle<v8::Value> value = V8Proxy::EventTargetToV8Object(target); + if (value.IsEmpty()) return v8::Local<v8::Object>(); + return v8::Local<v8::Object>::New(v8::Handle<v8::Object>::Cast(value)); +} + + V8EventListener::V8EventListener(Frame* frame, v8::Local<v8::Object> listener, bool isInline) : V8AbstractEventListener(frame, isInline) { @@ -191,68 +209,22 @@ v8::Local<v8::Value> V8EventListener::CallListenerFunction(v8::Handle<v8::Value> jsevent, Event* event, bool isWindowEvent) { v8::Local<v8::Function> handler_func = GetListenerFunction(); - if (handler_func.IsEmpty()) return v8::Local<v8::Value>(); - - v8::Local<v8::Object> this_obj = GetThisObject(event, isWindowEvent); - v8::Handle<v8::Value> parameters[1] = {jsevent}; - - V8Proxy* proxy = V8Proxy::retrieve(m_frame); - ASSERT(proxy); - - return proxy->CallFunction(handler_func, this_obj, 1, parameters); -} - - -v8::Local<v8::Object> V8EventListener::GetThisObject(Event* event, - bool isWindowEvent) { - if (!m_listener.IsEmpty() && !m_listener->IsFunction()) { - return v8::Local<v8::Object>::New(m_listener); - } - - if (isWindowEvent) { - return v8::Context::GetCurrent()->Global(); + v8::Local<v8::Object> receiver = GetReceiverObject(event, isWindowEvent); + if (handler_func.IsEmpty() || receiver.IsEmpty()) { + return v8::Local<v8::Value>(); } - // make sure to sync type conversions with V8Proxy::EventTargetToV8Object - EventTarget* target = event->currentTarget(); - if (target->toNode()) { - v8::Handle<v8::Value> value = - V8Proxy::NodeToV8Object(target->toNode()); - return v8::Local<v8::Object>::New(v8::Handle<v8::Object>::Cast(value)); - - } else if (target->toXMLHttpRequest()) { - v8::Handle<v8::Value> value = V8Proxy::ToV8Object( - V8ClassIndex::XMLHTTPREQUEST, target->toXMLHttpRequest()); - return v8::Local<v8::Object>::New(v8::Handle<v8::Object>::Cast(value)); - - } else if (target->toXMLHttpRequestUpload()) { - v8::Handle<v8::Value> value = V8Proxy::ToV8Object( - V8ClassIndex::XMLHTTPREQUESTUPLOAD, target->toXMLHttpRequestUpload()); - return v8::Local<v8::Object>::New(v8::Handle<v8::Object>::Cast(value)); - - } else if (target->toMessagePort()) { - v8::Handle<v8::Value> value = V8Proxy::ToV8Object( - V8ClassIndex::MESSAGEPORT, target->toMessagePort()); - return v8::Local<v8::Object>::New(v8::Handle<v8::Object>::Cast(value)); - -#if ENABLE(SVG) - } else if (target->toSVGElementInstance()) { - v8::Handle<v8::Value> value = V8Proxy::ToV8Object( - V8ClassIndex::SVGELEMENTINSTANCE, target->toSVGElementInstance()); - return v8::Local<v8::Object>::New(v8::Handle<v8::Object>::Cast(value)); -#endif + v8::Handle<v8::Value> parameters[1] = { jsevent }; - } else { - ASSERT(false); - return v8::Local<v8::Object>(); - } + V8Proxy* proxy = V8Proxy::retrieve(m_frame); + return proxy->CallFunction(handler_func, receiver, 1, parameters); } // ------- V 8 X H R E v e n t L i s t e n e r ----------------- static void WeakObjectEventListenerCallback(v8::Persistent<v8::Value> obj, - void* para) { + void* para) { V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(para); // Remove the wrapper @@ -274,8 +246,8 @@ static void WeakObjectEventListenerCallback(v8::Persistent<v8::Value> obj, V8ObjectEventListener::V8ObjectEventListener(Frame* frame, - v8::Local<v8::Object> listener, - bool isInline) + v8::Local<v8::Object> listener, + bool isInline) : V8EventListener(frame, listener, isInline) { // make m_listener weak. m_listener.MakeWeak(this, WeakObjectEventListenerCallback); @@ -318,20 +290,6 @@ V8LazyEventListener::~V8LazyEventListener() { } -v8::Local<v8::Object> V8LazyEventListener::GetThisObject(Event* event, - bool isWindowEvent) { - if (isWindowEvent) { - return v8::Context::GetCurrent()->Global(); - } - - v8::Handle<v8::Value> value = - V8Proxy::NodeToV8Object(event->currentTarget()->toNode()); - ASSERT(!value.IsEmpty()); - - return v8::Local<v8::Object>::New(v8::Handle<v8::Object>::Cast(value)); -} - - v8::Local<v8::Function> V8LazyEventListener::GetListenerFunction() { if (m_compiled) { ASSERT(m_listener.IsEmpty() || m_listener->IsFunction()); @@ -409,14 +367,16 @@ v8::Local<v8::Function> V8LazyEventListener::GetListenerFunction() { v8::Local<v8::Value> V8LazyEventListener::CallListenerFunction(v8::Handle<v8::Value> jsevent, Event* event, bool isWindowEvent) { - v8::Local<v8::Object> this_obj = GetThisObject(event, isWindowEvent); v8::Local<v8::Function> handler_func = GetWrappedListenerFunction(); - if (handler_func.IsEmpty()) return v8::Local<v8::Value>(); + v8::Local<v8::Object> receiver = GetReceiverObject(event, isWindowEvent); + if (handler_func.IsEmpty() || receiver.IsEmpty()) { + return v8::Local<v8::Value>(); + } - v8::Handle<v8::Value> parameters[1] = {jsevent}; + v8::Handle<v8::Value> parameters[1] = { jsevent }; V8Proxy* proxy = V8Proxy::retrieve(m_frame); - return proxy->CallFunction(handler_func, this_obj, 1, parameters); + return proxy->CallFunction(handler_func, receiver, 1, parameters); } diff --git a/webkit/port/bindings/v8/v8_events.h b/webkit/port/bindings/v8/v8_events.h index 93acdc1..7306ab4 100644 --- a/webkit/port/bindings/v8/v8_events.h +++ b/webkit/port/bindings/v8/v8_events.h @@ -49,9 +49,14 @@ class V8AbstractEventListener : public EventListener { // Call listener function. - virtual v8::Local<v8::Value> - CallListenerFunction(v8::Handle<v8::Value> jsevent, - Event* event, bool isWindowEvent) = 0; + virtual v8::Local<v8::Value> CallListenerFunction( + v8::Handle<v8::Value> jsevent, + Event* event, + bool isWindowEvent) = 0; + + // Get the receiver object to use for event listener call. + v8::Local<v8::Object> GetReceiverObject(Event* event, + bool isWindowEvent); // Frame to which the event listener is attached to. // An event listener must be destroyed before its owner @@ -97,7 +102,6 @@ class V8EventListener : public V8AbstractEventListener { // Call listener function. virtual v8::Local<v8::Value> CallListenerFunction( v8::Handle<v8::Value> jsevent, Event* event, bool isWindowEvent); - v8::Local<v8::Object> GetThisObject(Event* event, bool isWindowEvent); v8::Local<v8::Function> GetListenerFunction(); }; @@ -151,7 +155,6 @@ class V8LazyEventListener : public V8AbstractEventListener { virtual v8::Local<v8::Value> CallListenerFunction( v8::Handle<v8::Value> jsevent, Event* event, bool isWindowEvent); - v8::Local<v8::Object> GetThisObject(Event* event, bool isWindowEvent); v8::Local<v8::Function> GetListenerFunction(); }; diff --git a/webkit/port/bindings/v8/v8_proxy.cpp b/webkit/port/bindings/v8/v8_proxy.cpp index 19ce50a..4e1be35 100644 --- a/webkit/port/bindings/v8/v8_proxy.cpp +++ b/webkit/port/bindings/v8/v8_proxy.cpp @@ -3161,7 +3161,6 @@ v8::Handle<v8::Value> V8Proxy::NodeToV8Object(Node* node) // 1) EventTargetNode; 2) XMLHttpRequest; 3) MessagePort; 4) SVGElementInstance; // 5) XMLHttpRequestUpload // check EventTarget.h for new type conversion methods -// also make sure to sync with V8EventListener::GetThisObject (v8_events.cpp) v8::Handle<v8::Value> V8Proxy::EventTargetToV8Object(EventTarget* target) { if (!target) |