summaryrefslogtreecommitdiffstats
path: root/WebCore/bindings/v8/custom/V8NodeCustom.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/bindings/v8/custom/V8NodeCustom.cpp')
-rw-r--r--WebCore/bindings/v8/custom/V8NodeCustom.cpp115
1 files changed, 84 insertions, 31 deletions
diff --git a/WebCore/bindings/v8/custom/V8NodeCustom.cpp b/WebCore/bindings/v8/custom/V8NodeCustom.cpp
index e81e8b5..6b0d740 100644
--- a/WebCore/bindings/v8/custom/V8NodeCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8NodeCustom.cpp
@@ -34,30 +34,86 @@
#include "Document.h"
#include "EventListener.h"
+#include "V8AbstractEventListener.h"
#include "V8Binding.h"
#include "V8CustomBinding.h"
#include "V8CustomEventListener.h"
#include "V8Node.h"
+#include "V8ObjectEventListener.h"
#include "V8Proxy.h"
#include <wtf/RefPtr.h>
namespace WebCore {
-CALLBACK_FUNC_DECL(NodeAddEventListener)
+static inline String toEventType(v8::Local<v8::String> value)
{
- INC_STATS("DOM.Node.addEventListener()");
- Node* node = V8Proxy::DOMWrapperToNode<Node>(args.Holder());
+ String key = toWebCoreString(value);
+ ASSERT(key.startsWith("on"));
+ return key.substring(2);
+}
- V8Proxy* proxy = V8Proxy::retrieve(node->document()->frame());
+static PassRefPtr<EventListener> getEventListener(Node* node, v8::Local<v8::Value> value, bool isAttribute, bool findOnly)
+{
+ V8Proxy* proxy = V8Proxy::retrieve(node->scriptExecutionContext());
+ // The document might be created using createDocument, which does
+ // not have a frame, use the active frame.
if (!proxy)
- return v8::Undefined();
+ proxy = V8Proxy::retrieve(V8Proxy::retrieveFrameForEnteredContext());
+
+ if (proxy) {
+ V8EventListenerList* list = proxy->objectListeners();
+ return findOnly ? list->findWrapper(value, isAttribute) : list->findOrCreateWrapper<V8ObjectEventListener>(proxy->frame(), value, isAttribute);
+ }
+
+ return 0;
+}
+
+ACCESSOR_SETTER(NodeEventHandler)
+{
+ Node* node = V8DOMWrapper::convertDOMWrapperToNode<Node>(info.Holder());
+ String eventType = toEventType(name);
+
+ // Remove hidden dependency on the old event handler.
+ if (EventListener* listener = node->getAttributeEventListener(eventType)) {
+ if (static_cast<V8AbstractEventListener*>(listener)->isObjectListener()) {
+ v8::Local<v8::Object> v8Listener = static_cast<V8ObjectEventListener*>(listener)->getListenerObject();
+ removeHiddenDependency(info.Holder(), v8Listener, V8Custom::kNodeEventListenerCacheIndex);
+ }
+ }
+
+ // Set handler if the value is a function.
+ if (value->IsFunction()) {
+ RefPtr<EventListener> listener = getEventListener(node, value, true, false);
+ if (listener) {
+ node->setAttributeEventListener(eventType, listener);
+ createHiddenDependency(info.Holder(), value, V8Custom::kNodeEventListenerCacheIndex);
+ }
+ } else {
+ // Otherwise, clear the handler.
+ node->clearAttributeEventListener(eventType);
+ }
+}
+
+ACCESSOR_GETTER(NodeEventHandler)
+{
+ Node* node = V8DOMWrapper::convertDOMWrapperToNode<Node>(info.Holder());
+
+ EventListener* listener = node->getAttributeEventListener(toEventType(name));
+ return V8DOMWrapper::convertEventListenerToV8Object(listener);
+}
- RefPtr<EventListener> listener = proxy->FindOrCreateV8EventListener(args[1], false);
+CALLBACK_FUNC_DECL(NodeAddEventListener)
+{
+ INC_STATS("DOM.Node.addEventListener()");
+ Node* node = V8DOMWrapper::convertDOMWrapperToNode<Node>(args.Holder());
+
+ RefPtr<EventListener> listener = getEventListener(node, args[1], false, false);
if (listener) {
String type = toWebCoreString(args[0]);
bool useCapture = args[2]->BooleanValue();
node->addEventListener(type, listener, useCapture);
+ createHiddenDependency(args.Holder(), args[1], V8Custom::kNodeEventListenerCacheIndex);
}
return v8::Undefined();
}
@@ -65,20 +121,17 @@ CALLBACK_FUNC_DECL(NodeAddEventListener)
CALLBACK_FUNC_DECL(NodeRemoveEventListener)
{
INC_STATS("DOM.Node.removeEventListener()");
- Node* node = V8Proxy::DOMWrapperToNode<Node>(args.Holder());
+ Node* node = V8DOMWrapper::convertDOMWrapperToNode<Node>(args.Holder());
- V8Proxy* proxy = V8Proxy::retrieve(node->document()->frame());
// It is possbile that the owner document of the node is detached
- // from the frame, return immediately in this case.
+ // from the frame.
// See issue http://b/878909
- if (!proxy)
- return v8::Undefined();
-
- RefPtr<EventListener> listener = proxy->FindV8EventListener(args[1], false);
+ RefPtr<EventListener> listener = getEventListener(node, args[1], false, true);
if (listener) {
String type = toWebCoreString(args[0]);
bool useCapture = args[2]->BooleanValue();
node->removeEventListener(type, listener.get(), useCapture);
+ removeHiddenDependency(args.Holder(), args[1], V8Custom::kNodeEventListenerCacheIndex);
}
return v8::Undefined();
@@ -88,14 +141,14 @@ CALLBACK_FUNC_DECL(NodeRemoveEventListener)
CALLBACK_FUNC_DECL(NodeInsertBefore)
{
INC_STATS("DOM.Node.insertBefore");
- v8::Handle<v8::Value> holder = args.Holder();
- Node* imp = V8Proxy::DOMWrapperToNode<Node>(holder);
+ v8::Handle<v8::Object> holder = args.Holder();
+ Node* imp = V8DOMWrapper::convertDOMWrapperToNode<Node>(holder);
ExceptionCode ec = 0;
- Node* newChild = V8Node::HasInstance(args[0]) ? V8Proxy::DOMWrapperToNode<Node>(args[0]) : 0;
- Node* refChild = V8Node::HasInstance(args[1]) ? V8Proxy::DOMWrapperToNode<Node>(args[1]) : 0;
+ Node* newChild = V8Node::HasInstance(args[0]) ? V8DOMWrapper::convertDOMWrapperToNode<Node>(v8::Handle<v8::Object>::Cast(args[0])) : 0;
+ Node* refChild = V8Node::HasInstance(args[1]) ? V8DOMWrapper::convertDOMWrapperToNode<Node>(v8::Handle<v8::Object>::Cast(args[1])) : 0;
bool success = imp->insertBefore(newChild, refChild, ec, true);
if (ec) {
- V8Proxy::SetDOMException(ec);
+ V8Proxy::setDOMException(ec);
return v8::Handle<v8::Value>();
}
if (success)
@@ -107,14 +160,14 @@ CALLBACK_FUNC_DECL(NodeInsertBefore)
CALLBACK_FUNC_DECL(NodeReplaceChild)
{
INC_STATS("DOM.Node.replaceChild");
- v8::Handle<v8::Value> holder = args.Holder();
- Node* imp = V8Proxy::DOMWrapperToNode<Node>(holder);
+ v8::Handle<v8::Object> holder = args.Holder();
+ Node* imp = V8DOMWrapper::convertDOMWrapperToNode<Node>(holder);
ExceptionCode ec = 0;
- Node* newChild = V8Node::HasInstance(args[0]) ? V8Proxy::DOMWrapperToNode<Node>(args[0]) : 0;
- Node* oldChild = V8Node::HasInstance(args[1]) ? V8Proxy::DOMWrapperToNode<Node>(args[1]) : 0;
+ Node* newChild = V8Node::HasInstance(args[0]) ? V8DOMWrapper::convertDOMWrapperToNode<Node>(v8::Handle<v8::Object>::Cast(args[0])) : 0;
+ Node* oldChild = V8Node::HasInstance(args[1]) ? V8DOMWrapper::convertDOMWrapperToNode<Node>(v8::Handle<v8::Object>::Cast(args[1])) : 0;
bool success = imp->replaceChild(newChild, oldChild, ec, true);
if (ec) {
- V8Proxy::SetDOMException(ec);
+ V8Proxy::setDOMException(ec);
return v8::Handle<v8::Value>();
}
if (success)
@@ -125,13 +178,13 @@ CALLBACK_FUNC_DECL(NodeReplaceChild)
CALLBACK_FUNC_DECL(NodeRemoveChild)
{
INC_STATS("DOM.Node.removeChild");
- v8::Handle<v8::Value> holder = args.Holder();
- Node* imp = V8Proxy::DOMWrapperToNode<Node>(holder);
+ v8::Handle<v8::Object> holder = args.Holder();
+ Node* imp = V8DOMWrapper::convertDOMWrapperToNode<Node>(holder);
ExceptionCode ec = 0;
- Node* oldChild = V8Node::HasInstance(args[0]) ? V8Proxy::DOMWrapperToNode<Node>(args[0]) : 0;
+ Node* oldChild = V8Node::HasInstance(args[0]) ? V8DOMWrapper::convertDOMWrapperToNode<Node>(v8::Handle<v8::Object>::Cast(args[0])) : 0;
bool success = imp->removeChild(oldChild, ec);
if (ec) {
- V8Proxy::SetDOMException(ec);
+ V8Proxy::setDOMException(ec);
return v8::Handle<v8::Value>();
}
if (success)
@@ -143,13 +196,13 @@ CALLBACK_FUNC_DECL(NodeRemoveChild)
CALLBACK_FUNC_DECL(NodeAppendChild)
{
INC_STATS("DOM.Node.appendChild");
- v8::Handle<v8::Value> holder = args.Holder();
- Node* imp = V8Proxy::DOMWrapperToNode<Node>(holder);
+ v8::Handle<v8::Object> holder = args.Holder();
+ Node* imp = V8DOMWrapper::convertDOMWrapperToNode<Node>(holder);
ExceptionCode ec = 0;
- Node* newChild = V8Node::HasInstance(args[0]) ? V8Proxy::DOMWrapperToNode<Node>(args[0]) : 0;
+ Node* newChild = V8Node::HasInstance(args[0]) ? V8DOMWrapper::convertDOMWrapperToNode<Node>(v8::Handle<v8::Object>::Cast(args[0])) : 0;
bool success = imp->appendChild(newChild, ec, true );
if (ec) {
- V8Proxy::SetDOMException(ec);
+ V8Proxy::setDOMException(ec);
return v8::Handle<v8::Value>();
}
if (success)