| Index: WebCore/bindings/v8/custom/V8NodeCustom.cpp
|
| ===================================================================
|
| --- WebCore/bindings/v8/custom/V8NodeCustom.cpp (revision 24197)
|
| +++ WebCore/bindings/v8/custom/V8NodeCustom.cpp (working copy)
|
| @@ -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 {
|
|
|
| +static inline String toEventType(v8::Local<v8::String> value)
|
| +{
|
| + String key = toWebCoreString(value);
|
| + ASSERT(key.startsWith("on"));
|
| + return key.substring(2);
|
| +}
|
| +
|
| +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)
|
| + 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);
|
| +}
|
| +
|
| CALLBACK_FUNC_DECL(NodeAddEventListener)
|
| {
|
| INC_STATS("DOM.Node.addEventListener()");
|
| Node* node = V8DOMWrapper::convertDOMWrapperToNode<Node>(args.Holder());
|
|
|
| - V8Proxy* proxy = V8Proxy::retrieve(node->document()->frame());
|
| - if (!proxy)
|
| - return v8::Undefined();
|
| -
|
| - RefPtr<EventListener> listener = proxy->eventListeners()->findOrCreateWrapper<V8EventListener>(proxy->frame(), args[1], false);
|
| + 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();
|
| }
|
| @@ -67,18 +123,15 @@
|
| INC_STATS("DOM.Node.removeEventListener()");
|
| 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->eventListeners()->findWrapper(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();
|
|
|