[SCM] WebKit Debian packaging branch, webkit-1.1, updated. upstream/1.1.15.1-1414-gc69ee75

eric at webkit.org eric at webkit.org
Thu Oct 29 20:37:30 UTC 2009


The following commit has been merged in the webkit-1.1 branch:
commit 76d2a71ca8d2d08abc732628637523f8852d5786
Author: eric at webkit.org <eric at webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Thu Oct 1 17:01:50 2009 +0000

    2009-10-01  Vitaly Repeshko  <vitalyr at chromium.org>
    
            Reviewed by Dimitri Glazkov.
    
            [V8] Refactored V8 event listeners:
            (This change should fix http://crbug.com/21079 and
            https://bugs.webkit.org/show_bug.cgi?id=29093.)
             o All listeners use weak handles to JS objects to avoid creating
               cycles and leaking memory.
             o "Object" variants of listeners removed.
             o All event accessor callbacks are generated.
             o Custom event accessors removed.
             o All wrappers have hidden dependencies on their listeners to
               prevent listeners from being collected.
             o All variats of getEventListener function grouped in V8DOMWrapper.
             o Pointers to C++ EventListener wrappers are stored in JS objects
               instead of event listener lists.
            https://bugs.webkit.org/show_bug.cgi?id=29825
    
            * WebCore.gypi: Removed "Object" listeners.
            * bindings/scripts/CodeGeneratorV8.pm: Now handles event accessors.
            * bindings/v8/DOMObjectsInclude.h:
    
            V8AbstractEventListener manages weak JS handle:
            * bindings/v8/V8AbstractEventListener.cpp:
            (WebCore::weakEventListenerCallback):
            (WebCore::V8AbstractEventListener::V8AbstractEventListener):
            (WebCore::V8AbstractEventListener::~V8AbstractEventListener):
            (WebCore::V8AbstractEventListener::handleEvent):
            (WebCore::V8AbstractEventListener::disposeListenerObject):
            (WebCore::V8AbstractEventListener::setListenerObject):
            * bindings/v8/V8AbstractEventListener.h:
            (WebCore::V8AbstractEventListener::cast):
            (WebCore::V8AbstractEventListener::isLazy):
            (WebCore::V8AbstractEventListener::getListenerObject):
            (WebCore::V8AbstractEventListener::getExistingListenerObject):
            (WebCore::V8AbstractEventListener::hasExistingListenerObject):
            (WebCore::V8AbstractEventListener::disconnectFrame):
            (WebCore::V8AbstractEventListener::disconnected):
            (WebCore::V8AbstractEventListener::prepareListenerObject):
            (WebCore::V8AbstractEventListener::lineNumber):
            (WebCore::V8AbstractEventListener::virtualisAttribute):
    
            Grouped getEventListener functions:
            * bindings/v8/V8DOMWrapper.cpp:
            (WebCore::V8DOMWrapper::getTemplate):
            (WebCore::V8DOMWrapper::getEventListener):
            * bindings/v8/V8DOMWrapper.h:
    
            Removed most event listener objects bookkeeping:
            * bindings/v8/V8EventListenerList.cpp:
            * bindings/v8/V8EventListenerList.h:
            (WebCore::V8EventListenerList::findWrapper):
            (WebCore::V8EventListenerList::clearWrapper):
            (WebCore::V8EventListenerList::doFindWrapper):
            (WebCore::V8EventListenerList::getHiddenProperty):
            (WebCore::V8EventListenerList::findOrCreateWrapper):
    
            Added hidden properties for storing EventListener wrappers:
            * bindings/v8/V8HiddenPropertyName.cpp:
            (WebCore::V8HiddenPropertyName::listener):
            (WebCore::V8HiddenPropertyName::attributeListener):
            * bindings/v8/V8HiddenPropertyName.h:
    
            * bindings/v8/V8LazyEventListener.cpp:
            (WebCore::V8LazyEventListener::V8LazyEventListener):
            (WebCore::V8LazyEventListener::callListenerFunction):
            (WebCore::V8LazyEventListener::prepareListenerObject):
            * bindings/v8/V8LazyEventListener.h:
            (WebCore::V8LazyEventListener::isLazy):
            * bindings/v8/V8ObjectEventListener.cpp: Removed.
            * bindings/v8/V8ObjectEventListener.h: Removed.
            * bindings/v8/V8Proxy.cpp:
            (WebCore::V8Proxy::disconnectFrame):
            (WebCore::V8Proxy::disconnectEventListeners):
            * bindings/v8/V8Proxy.h:
            * bindings/v8/V8WorkerContextEventListener.cpp:
            (WebCore::V8WorkerContextEventListener::reportError):
            (WebCore::V8WorkerContextEventListener::getReceiverObject):
            * bindings/v8/V8WorkerContextEventListener.h:
            * bindings/v8/V8WorkerContextObjectEventListener.cpp: Removed.
            * bindings/v8/V8WorkerContextObjectEventListener.h: Removed.
            * bindings/v8/WorkerContextExecutionProxy.cpp:
            (WebCore::WorkerContextExecutionProxy::dispose):
            (WebCore::WorkerContextExecutionProxy::initContextIfNeeded):
            (WebCore::WorkerContextExecutionProxy::findOrCreateEventListener):
            * bindings/v8/WorkerContextExecutionProxy.h:
            * bindings/v8/custom/V8AbstractWorkerCustom.cpp:
            (WebCore::CALLBACK_FUNC_DECL):
            * bindings/v8/custom/V8CustomBinding.h:
            * bindings/v8/custom/V8CustomEventListener.cpp:
            (WebCore::V8EventListener::V8EventListener):
            (WebCore::V8EventListener::getListenerFunction):
            (WebCore::V8EventListener::callListenerFunction):
            * bindings/v8/custom/V8CustomEventListener.h:
            * bindings/v8/custom/V8DOMApplicationCacheCustom.cpp:
            (WebCore::CALLBACK_FUNC_DECL):
            * bindings/v8/custom/V8DOMWindowCustom.cpp:
            (WebCore::CALLBACK_FUNC_DECL):
            * bindings/v8/custom/V8DedicatedWorkerContextCustom.cpp:
            * bindings/v8/custom/V8MessagePortCustom.cpp:
            (WebCore::getEventListener):
            (WebCore::CALLBACK_FUNC_DECL):
            * bindings/v8/custom/V8NodeCustom.cpp:
            (WebCore::CALLBACK_FUNC_DECL):
            * bindings/v8/custom/V8NotificationCenterCustom.cpp:
            (WebCore::CALLBACK_FUNC_DECL):
            * bindings/v8/custom/V8SVGElementInstanceCustom.cpp:
            (WebCore::CALLBACK_FUNC_DECL):
            * bindings/v8/custom/V8WebSocketCustom.cpp:
            * bindings/v8/custom/V8WorkerContextCustom.cpp:
            (WebCore::CALLBACK_FUNC_DECL):
            * bindings/v8/custom/V8WorkerCustom.cpp:
            * bindings/v8/custom/V8XMLHttpRequestConstructor.cpp:
            * bindings/v8/custom/V8XMLHttpRequestCustom.cpp:
            (WebCore::CALLBACK_FUNC_DECL):
            * bindings/v8/custom/V8XMLHttpRequestUploadCustom.cpp:
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@48978 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 7ad805e..9c767f2 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,121 @@
+2009-10-01  Vitaly Repeshko  <vitalyr at chromium.org>
+
+        Reviewed by Dimitri Glazkov.
+
+        [V8] Refactored V8 event listeners:
+        (This change should fix http://crbug.com/21079 and
+        https://bugs.webkit.org/show_bug.cgi?id=29093.)
+         o All listeners use weak handles to JS objects to avoid creating
+           cycles and leaking memory.
+         o "Object" variants of listeners removed.
+         o All event accessor callbacks are generated.
+         o Custom event accessors removed.
+         o All wrappers have hidden dependencies on their listeners to
+           prevent listeners from being collected.
+         o All variats of getEventListener function grouped in V8DOMWrapper.
+         o Pointers to C++ EventListener wrappers are stored in JS objects
+           instead of event listener lists.
+        https://bugs.webkit.org/show_bug.cgi?id=29825
+
+        * WebCore.gypi: Removed "Object" listeners.
+        * bindings/scripts/CodeGeneratorV8.pm: Now handles event accessors.
+        * bindings/v8/DOMObjectsInclude.h:
+
+        V8AbstractEventListener manages weak JS handle:
+        * bindings/v8/V8AbstractEventListener.cpp:
+        (WebCore::weakEventListenerCallback):
+        (WebCore::V8AbstractEventListener::V8AbstractEventListener):
+        (WebCore::V8AbstractEventListener::~V8AbstractEventListener):
+        (WebCore::V8AbstractEventListener::handleEvent):
+        (WebCore::V8AbstractEventListener::disposeListenerObject):
+        (WebCore::V8AbstractEventListener::setListenerObject):
+        * bindings/v8/V8AbstractEventListener.h:
+        (WebCore::V8AbstractEventListener::cast):
+        (WebCore::V8AbstractEventListener::isLazy):
+        (WebCore::V8AbstractEventListener::getListenerObject):
+        (WebCore::V8AbstractEventListener::getExistingListenerObject):
+        (WebCore::V8AbstractEventListener::hasExistingListenerObject):
+        (WebCore::V8AbstractEventListener::disconnectFrame):
+        (WebCore::V8AbstractEventListener::disconnected):
+        (WebCore::V8AbstractEventListener::prepareListenerObject):
+        (WebCore::V8AbstractEventListener::lineNumber):
+        (WebCore::V8AbstractEventListener::virtualisAttribute):
+
+        Grouped getEventListener functions:
+        * bindings/v8/V8DOMWrapper.cpp:
+        (WebCore::V8DOMWrapper::getTemplate):
+        (WebCore::V8DOMWrapper::getEventListener):
+        * bindings/v8/V8DOMWrapper.h:
+
+        Removed most event listener objects bookkeeping:
+        * bindings/v8/V8EventListenerList.cpp:
+        * bindings/v8/V8EventListenerList.h:
+        (WebCore::V8EventListenerList::findWrapper):
+        (WebCore::V8EventListenerList::clearWrapper):
+        (WebCore::V8EventListenerList::doFindWrapper):
+        (WebCore::V8EventListenerList::getHiddenProperty):
+        (WebCore::V8EventListenerList::findOrCreateWrapper):
+
+        Added hidden properties for storing EventListener wrappers:
+        * bindings/v8/V8HiddenPropertyName.cpp:
+        (WebCore::V8HiddenPropertyName::listener):
+        (WebCore::V8HiddenPropertyName::attributeListener):
+        * bindings/v8/V8HiddenPropertyName.h:
+
+        * bindings/v8/V8LazyEventListener.cpp:
+        (WebCore::V8LazyEventListener::V8LazyEventListener):
+        (WebCore::V8LazyEventListener::callListenerFunction):
+        (WebCore::V8LazyEventListener::prepareListenerObject):
+        * bindings/v8/V8LazyEventListener.h:
+        (WebCore::V8LazyEventListener::isLazy):
+        * bindings/v8/V8ObjectEventListener.cpp: Removed.
+        * bindings/v8/V8ObjectEventListener.h: Removed.
+        * bindings/v8/V8Proxy.cpp:
+        (WebCore::V8Proxy::disconnectFrame):
+        (WebCore::V8Proxy::disconnectEventListeners):
+        * bindings/v8/V8Proxy.h:
+        * bindings/v8/V8WorkerContextEventListener.cpp:
+        (WebCore::V8WorkerContextEventListener::reportError):
+        (WebCore::V8WorkerContextEventListener::getReceiverObject):
+        * bindings/v8/V8WorkerContextEventListener.h:
+        * bindings/v8/V8WorkerContextObjectEventListener.cpp: Removed.
+        * bindings/v8/V8WorkerContextObjectEventListener.h: Removed.
+        * bindings/v8/WorkerContextExecutionProxy.cpp:
+        (WebCore::WorkerContextExecutionProxy::dispose):
+        (WebCore::WorkerContextExecutionProxy::initContextIfNeeded):
+        (WebCore::WorkerContextExecutionProxy::findOrCreateEventListener):
+        * bindings/v8/WorkerContextExecutionProxy.h:
+        * bindings/v8/custom/V8AbstractWorkerCustom.cpp:
+        (WebCore::CALLBACK_FUNC_DECL):
+        * bindings/v8/custom/V8CustomBinding.h:
+        * bindings/v8/custom/V8CustomEventListener.cpp:
+        (WebCore::V8EventListener::V8EventListener):
+        (WebCore::V8EventListener::getListenerFunction):
+        (WebCore::V8EventListener::callListenerFunction):
+        * bindings/v8/custom/V8CustomEventListener.h:
+        * bindings/v8/custom/V8DOMApplicationCacheCustom.cpp:
+        (WebCore::CALLBACK_FUNC_DECL):
+        * bindings/v8/custom/V8DOMWindowCustom.cpp:
+        (WebCore::CALLBACK_FUNC_DECL):
+        * bindings/v8/custom/V8DedicatedWorkerContextCustom.cpp:
+        * bindings/v8/custom/V8MessagePortCustom.cpp:
+        (WebCore::getEventListener):
+        (WebCore::CALLBACK_FUNC_DECL):
+        * bindings/v8/custom/V8NodeCustom.cpp:
+        (WebCore::CALLBACK_FUNC_DECL):
+        * bindings/v8/custom/V8NotificationCenterCustom.cpp:
+        (WebCore::CALLBACK_FUNC_DECL):
+        * bindings/v8/custom/V8SVGElementInstanceCustom.cpp:
+        (WebCore::CALLBACK_FUNC_DECL):
+        * bindings/v8/custom/V8WebSocketCustom.cpp:
+        * bindings/v8/custom/V8WorkerContextCustom.cpp:
+        (WebCore::CALLBACK_FUNC_DECL):
+        * bindings/v8/custom/V8WorkerCustom.cpp:
+        * bindings/v8/custom/V8XMLHttpRequestConstructor.cpp:
+        * bindings/v8/custom/V8XMLHttpRequestCustom.cpp:
+        (WebCore::CALLBACK_FUNC_DECL):
+        * bindings/v8/custom/V8XMLHttpRequestUploadCustom.cpp:
+
 2009-10-01  Alexis Menard  <alexis.menard at nokia.com>
 
         Reviewed by Tor Arne Vestbø.
diff --git a/WebCore/WebCore.gypi b/WebCore/WebCore.gypi
index 5921e64..7766af1 100644
--- a/WebCore/WebCore.gypi
+++ b/WebCore/WebCore.gypi
@@ -802,8 +802,6 @@
             'bindings/v8/V8NPUtils.h',
             'bindings/v8/V8NodeFilterCondition.cpp',
             'bindings/v8/V8NodeFilterCondition.h',
-            'bindings/v8/V8ObjectEventListener.cpp',
-            'bindings/v8/V8ObjectEventListener.h',
             'bindings/v8/V8Proxy.cpp',
             'bindings/v8/V8Proxy.h',
             'bindings/v8/V8SVGPODTypeWrapper.h',
@@ -811,8 +809,6 @@
             'bindings/v8/V8Utilities.h',
             'bindings/v8/V8WorkerContextEventListener.cpp',
             'bindings/v8/V8WorkerContextEventListener.h',
-            'bindings/v8/V8WorkerContextObjectEventListener.cpp',
-            'bindings/v8/V8WorkerContextObjectEventListener.h',
             'bindings/v8/WorkerContextExecutionProxy.h',
             'bindings/v8/WorkerContextExecutionProxy.cpp',
             'bindings/v8/WorkerScriptController.h',
diff --git a/WebCore/bindings/scripts/CodeGeneratorV8.pm b/WebCore/bindings/scripts/CodeGeneratorV8.pm
index 177c3f4..231355a 100644
--- a/WebCore/bindings/scripts/CodeGeneratorV8.pm
+++ b/WebCore/bindings/scripts/CodeGeneratorV8.pm
@@ -326,10 +326,26 @@ sub IsNodeSubType
     return 0;
 }
 
-sub RequiresCustomEventListenerAccessors
+sub GetHiddenDependencyIndex
 {
     my $dataNode = shift;
-    return !IsNodeSubType($dataNode) && $dataNode->name ne "SVGElementInstance";
+    my $attribute = shift;
+    my $name = $dataNode->name;
+    return "V8Custom::kNodeEventListenerCacheIndex" if IsNodeSubType($dataNode);
+    return "V8Custom::kSVGElementInstanceEventListenerCacheIndex" if $name eq "SVGElementInstance";
+    return "V8Custom::kAbstractWorkerRequestCacheIndex" if $name eq "AbstractWorker";
+    return "V8Custom::kWorkerRequestCacheIndex" if $name eq "Worker";
+    return "V8Custom::kDedicatedWorkerContextRequestCacheIndex" if $name eq "DedicatedWorkerContext";
+    return "V8Custom::kWorkerContextRequestCacheIndex" if $name eq "WorkerContext";
+    return "V8Custom::kWorkerContextRequestCacheIndex" if $name eq "SharedWorkerContext";
+    return "V8Custom::kMessagePortRequestCacheIndex" if $name eq "MessagePort";
+    return "V8Custom::kWebSocketCacheIndex" if $name eq "WebSocket";
+    return "V8Custom::kXMLHttpRequestCacheIndex" if $name eq "XMLHttpRequest";
+    return "V8Custom::kXMLHttpRequestCacheIndex" if $name eq "XMLHttpRequestUpload";
+    return "V8Custom::kDOMApplicationCacheCacheIndex" if $name eq "DOMApplicationCache";
+    return "V8Custom::kNotificationRequestCacheIndex" if $name eq "Notification";
+    return "V8Custom::kDOMWindowEventListenerCacheIndex" if $name eq "DOMWindow";
+    die "Unexpected name " . $name . " when generating " . $attribute;
 }
 
 sub HolderToNative
@@ -594,6 +610,10 @@ END
         }
 
     } else {
+        if ($attribute->signature->type eq "EventListener" && $dataNode->name eq "DOMWindow") {
+            push(@implContentDecls, "    if (!imp->document())\n");
+            push(@implContentDecls, "      return v8::Undefined();\n");
+        }
         push(@implContentDecls, "    $nativeType v = ");
 
         push(@implContentDecls, "$getterString;\n");
@@ -675,7 +695,7 @@ sub GenerateNormalAttrSetter
         # perform lookup first
         push(@implContentDecls, <<END);
     v8::Handle<v8::Object> holder = V8DOMWrapper::lookupDOMWrapper(V8ClassIndex::$classIndex, info.This());
-    if (holder.IsEmpty()) return v8::Undefined();
+    if (holder.IsEmpty()) return;
 END
         HolderToNative($dataNode, $implClassName, $classIndex);
     } else {
@@ -687,7 +707,11 @@ END
 
     my $nativeType = GetNativeTypeFromSignature($attribute->signature, 0);
     if ($attribute->signature->type eq "EventListener") {
-        push(@implContentDecls, "    $nativeType v = V8DOMWrapper::getEventListener(imp, value, true, false);\n");
+        if ($dataNode->name eq "DOMWindow") {
+            push(@implContentDecls, "    if (!imp->document())\n");
+            push(@implContentDecls, "      return;\n");
+        }
+        push(@implContentDecls, "    $nativeType v = V8DOMWrapper::getEventListener(imp, value, true, ListenerFindOrCreate);\n");
     } else {
         push(@implContentDecls, "    $nativeType v = " . JSValueToNative($attribute->signature, "value") . ";\n");
     }
@@ -725,14 +749,17 @@ END
         } elsif ($attribute->signature->type eq "EventListener") {
             $implIncludes{"V8AbstractEventListener.h"} = 1;
             $implIncludes{"V8CustomBinding.h"} = 1;
+            $cacheIndex = GetHiddenDependencyIndex($dataNode, $attrName);
             push(@implContentDecls, "    $nativeType old = imp->$attrName();\n");
-            push(@implContentDecls, "    if (old && static_cast<V8AbstractEventListener*>(old.get())->isObjectListener()) {\n");
-            push(@implContentDecls, "      v8::Local<v8::Object> oldListener = static_cast<V8AbstractEventListener*>(old.get())->getListenerObject();\n");
-            push(@implContentDecls, "      removeHiddenDependency(holder, oldListener, V8Custom::kNodeEventListenerCacheIndex);\n");
+            push(@implContentDecls, "    V8AbstractEventListener* oldListener = old ? V8AbstractEventListener::cast(old.get()) : 0;\n");
+            push(@implContentDecls, "    if (oldListener) {\n");
+            push(@implContentDecls, "      v8::Local<v8::Object> oldListenerObject = oldListener->getExistingListenerObject();\n");
+            push(@implContentDecls, "      if (!oldListenerObject.IsEmpty())\n");
+            push(@implContentDecls, "        removeHiddenDependency(holder, oldListenerObject, $cacheIndex);\n");
             push(@implContentDecls, "    }\n");
             push(@implContentDecls, "    imp->set$implSetterFunctionName($result);\n");
             push(@implContentDecls, "    if ($result)\n");
-            push(@implContentDecls, "      createHiddenDependency(holder, value, V8Custom::kNodeEventListenerCacheIndex");
+            push(@implContentDecls, "      createHiddenDependency(holder, value, $cacheIndex");
         } else {
             push(@implContentDecls, "    imp->set$implSetterFunctionName(" . $result);
         }
@@ -967,26 +994,6 @@ sub GenerateBatchedAttributeData
             $setter = "0";
             $propAttr = "v8::ReadOnly";
 
-        # EventListeners
-        } elsif ($attribute->signature->type eq "EventListener" && RequiresCustomEventListenerAccessors($dataNode)) {
-            if ($interfaceName eq "DOMWindow") {
-                $getter = "V8Custom::v8DOMWindowEventHandlerAccessorGetter";
-                $setter = "V8Custom::v8DOMWindowEventHandlerAccessorSetter";
-            } elsif ($interfaceName eq "DOMApplicationCache") {
-                $getter = "V8Custom::v8DOMApplicationCacheEventHandlerAccessorGetter";
-                $setter = "V8Custom::v8DOMApplicationCacheEventHandlerAccessorSetter";
-            } elsif ($interfaceName eq "Notification") {
-                $getter = "V8Custom::v8NotificationEventHandlerAccessorGetter";
-                $setter = "V8Custom::v8NotificationEventHandlerAccessorSetter";
-            } else {
-                $getter = "V8Custom::v8${customAccessor}AccessorGetter";
-                if ($interfaceName eq "WorkerContext" and $attrName eq "self") {
-                    $setter = "0";
-                    $propAttr = "v8::ReadOnly";
-                } else {
-                    $setter = "V8Custom::v8${customAccessor}AccessorSetter";
-                }
-            }
         } else {
             # Default Getter and Setter
             $getter = "${interfaceName}Internal::${attrName}AttrGetter";
@@ -1100,16 +1107,8 @@ sub GenerateImplementation
             next;
         }
 
-        # Make EventListeners custom for some types.
-        # FIXME: make the perl code capable of generating the
-        #   event setters/getters.  For now, WebKit has started removing the
-        #   [Custom] attribute, so just automatically insert it to avoid forking
-        #   other files.  This should be okay because we can't generate stubs
-        #   for any event getter/setters anyway.
-        if ($attrType eq "EventListener" && RequiresCustomEventListenerAccessors($dataNode)) {
-            $attribute->signature->extendedAttributes->{"Custom"} = 1;
-            $implIncludes{"V8CustomBinding.h"} = 1;
-            next;
+        if ($attrType eq "EventListener" && $interfaceName eq "DOMWindow") {
+            $attribute->signature->extendedAttributes->{"v8OnProto"} = 1;
         }
 
         # Do not generate accessor if this is a custom attribute.  The
diff --git a/WebCore/bindings/v8/DOMObjectsInclude.h b/WebCore/bindings/v8/DOMObjectsInclude.h
index e5796e7..0124165 100644
--- a/WebCore/bindings/v8/DOMObjectsInclude.h
+++ b/WebCore/bindings/v8/DOMObjectsInclude.h
@@ -157,7 +157,6 @@
 #include "V8HTMLElement.h"
 #include "V8LazyEventListener.h"
 #include "V8NodeFilterCondition.h"
-#include "V8ObjectEventListener.h"
 #include "ValidityState.h"
 #include "WebKitAnimationEvent.h"
 #include "WebKitCSSKeyframeRule.h"
diff --git a/WebCore/bindings/v8/V8AbstractEventListener.cpp b/WebCore/bindings/v8/V8AbstractEventListener.cpp
index d1ee730..3385791 100644
--- a/WebCore/bindings/v8/V8AbstractEventListener.cpp
+++ b/WebCore/bindings/v8/V8AbstractEventListener.cpp
@@ -37,12 +37,20 @@
 #include "Frame.h"
 #include "Tokenizer.h"
 #include "V8Binding.h"
+#include "V8EventListenerList.h"
 #include "V8Utilities.h"
 
 namespace WebCore {
 
+static void weakEventListenerCallback(v8::Persistent<v8::Value>, void* parameter)
+{
+    V8AbstractEventListener* listener = static_cast<V8AbstractEventListener*>(parameter);
+    listener->disposeListenerObject();
+}
+
 V8AbstractEventListener::V8AbstractEventListener(Frame* frame, bool isAttribute)
     : EventListener(JSEventListenerType)
+    , m_isWeak(true)
     , m_isAttribute(isAttribute)
     , m_frame(frame)
     , m_lineNumber(0)
@@ -63,6 +71,70 @@ V8AbstractEventListener::V8AbstractEventListener(Frame* frame, bool isAttribute)
     }
 }
 
+V8AbstractEventListener::~V8AbstractEventListener()
+{
+    if (!m_listener.IsEmpty())
+        V8EventListenerList::clearWrapper(m_listener, m_isAttribute);
+    disposeListenerObject();
+}
+
+void V8AbstractEventListener::handleEvent(ScriptExecutionContext* scriptExecutionContext, Event* event)
+{
+    // EventListener could be disconnected from the frame.
+    if (disconnected())
+        return;
+
+    // The callback function on XMLHttpRequest can clear the event listener and destroys 'this' object. Keep a local reference to it.
+    // See issue 889829.
+    RefPtr<V8AbstractEventListener> protect(this);
+
+    v8::HandleScope handleScope;
+
+    if (!m_context)
+        return;
+
+    // Create a new local handle since the persistent handle stored in
+    // m_context may be disposed before we're done.
+    v8::Handle<v8::Context> v8Context = v8::Local<v8::Context>::New(m_context->get());
+    if (v8Context.IsEmpty())
+        return;
+
+    // m_frame can removed by the callback function, protect it until the callback function returns.
+    RefPtr<Frame> protectFrame(m_frame);
+
+    // Enter the V8 context in which to perform the event handling.
+    v8::Context::Scope scope(v8Context);
+
+    // Get the V8 wrapper for the event object.
+    v8::Handle<v8::Value> jsEvent = V8DOMWrapper::convertEventToV8Object(event);
+
+    invokeEventHandler(v8Context, event, jsEvent);
+
+    Document::updateStyleForAllDocuments();
+}
+
+void V8AbstractEventListener::disposeListenerObject()
+{
+    if (!m_listener.IsEmpty()) {
+#ifndef NDEBUG
+        V8GCController::unregisterGlobalHandle(this, m_listener);
+#endif
+        m_listener.Dispose();
+        m_listener.Clear();
+    }
+}
+
+void V8AbstractEventListener::setListenerObject(v8::Handle<v8::Object> listener)
+{
+    disposeListenerObject();
+    m_listener = v8::Persistent<v8::Object>::New(listener);
+#ifndef NDEBUG
+    V8GCController::registerGlobalHandle(EVENT_LISTENER, this, m_listener);
+#endif
+    if (m_isWeak)
+        m_listener.MakeWeak(this, &weakEventListenerCallback);
+}
+
 void V8AbstractEventListener::invokeEventHandler(v8::Handle<v8::Context> v8Context, Event* event, v8::Handle<v8::Value> jsEvent)
 {
     // We push the event being processed into the global object, so that it can be exposed by DOMWindow's bindings.
@@ -124,52 +196,6 @@ void V8AbstractEventListener::invokeEventHandler(v8::Handle<v8::Context> v8Conte
         event->preventDefault();
 }
 
-void V8AbstractEventListener::handleEvent(ScriptExecutionContext* scriptExecutionContext, Event* event)
-{
-    // EventListener could be disconnected from the frame.
-    if (disconnected())
-        return;
-
-    // The callback function on XMLHttpRequest can clear the event listener and destroys 'this' object. Keep a local reference to it.
-    // See issue 889829.
-    RefPtr<V8AbstractEventListener> protect(this);
-
-    v8::HandleScope handleScope;
-
-    if (!m_context)
-        return;
-
-    // Create a new local handle since the persistent handle stored in
-    // m_context may be disposed before we're done.
-    v8::Handle<v8::Context> v8Context = v8::Local<v8::Context>::New(m_context->get());
-    if (v8Context.IsEmpty())
-        return;
-
-    // m_frame can removed by the callback function, protect it until the callback function returns.
-    RefPtr<Frame> protectFrame(m_frame);
-
-    // Enter the V8 context in which to perform the event handling.
-    v8::Context::Scope scope(v8Context);
-
-    // Get the V8 wrapper for the event object.
-    v8::Handle<v8::Value> jsEvent = V8DOMWrapper::convertEventToV8Object(event);
-
-    invokeEventHandler(v8Context, event, jsEvent);
-
-    Document::updateStyleForAllDocuments();
-}
-
-void V8AbstractEventListener::disposeListenerObject()
-{
-    if (!m_listener.IsEmpty()) {
-#ifndef NDEBUG
-        V8GCController::unregisterGlobalHandle(this, m_listener);
-#endif
-        m_listener.Dispose();
-        m_listener.Clear();
-    }
-}
-
 v8::Local<v8::Object> V8AbstractEventListener::getReceiverObject(Event* event)
 {
     if (!m_listener.IsEmpty() && !m_listener->IsFunction())
diff --git a/WebCore/bindings/v8/V8AbstractEventListener.h b/WebCore/bindings/v8/V8AbstractEventListener.h
index 8f1061b..f6e58e2 100644
--- a/WebCore/bindings/v8/V8AbstractEventListener.h
+++ b/WebCore/bindings/v8/V8AbstractEventListener.h
@@ -51,43 +51,84 @@ namespace WebCore {
     // but ALLOWs duplicated non-HTML event handlers.
     class V8AbstractEventListener : public EventListener {
     public:
-        virtual ~V8AbstractEventListener() { }
+        virtual ~V8AbstractEventListener();
+
+        static const V8AbstractEventListener* cast(const EventListener* listener)
+        {
+            return listener->type() == JSEventListenerType
+                ? static_cast<const V8AbstractEventListener*>(listener)
+                : 0;
+        }
+
+        static V8AbstractEventListener* cast(EventListener* listener)
+        {
+            return const_cast<V8AbstractEventListener*>(cast(const_cast<const EventListener*>(listener)));
+        }
+
+        // Implementation of EventListener interface.
 
         virtual bool operator==(const EventListener& other) { return this == &other; }
 
+        virtual void handleEvent(ScriptExecutionContext*, Event*);
+
         // Returns the owner frame of the listener.
         Frame* frame() { return m_frame; }
 
-        virtual void handleEvent(ScriptExecutionContext*, Event*);
-        void invokeEventHandler(v8::Handle<v8::Context>, Event*, v8::Handle<v8::Value> jsEvent);
+        virtual bool isLazy() const { return false; }
 
         // Returns the listener object, either a function or an object.
-        virtual v8::Local<v8::Object> getListenerObject()
+        v8::Local<v8::Object> getListenerObject()
+        {
+            prepareListenerObject();
+            return v8::Local<v8::Object>::New(m_listener);
+        }
+
+        v8::Local<v8::Object> getExistingListenerObject()
         {
             return v8::Local<v8::Object>::New(m_listener);
         }
 
+        bool hasExistingListenerObject()
+        {
+            return !m_listener.IsEmpty();
+        }
+
         // Dispose listener object and clear the handle.
         void disposeListenerObject();
 
-        virtual bool disconnected() const { return !m_frame; }
+        // Detach the listener from its owner frame.
+        void disconnectFrame() { m_frame = 0; }
 
-        virtual bool isObjectListener() const { return false; }
+        virtual bool disconnected() const { return !m_frame; }
 
     protected:
-        v8::Persistent<v8::Object> m_listener;
+        V8AbstractEventListener(Frame*, bool isAttribute);
 
-        // Indicates if this is an HTML type listener.
-        bool m_isAttribute;
+        virtual void prepareListenerObject() { }
 
-    private:
-        V8AbstractEventListener(Frame*, bool isInline);
+        void setListenerObject(v8::Handle<v8::Object> listener);
 
-        virtual v8::Local<v8::Value> callListenerFunction(v8::Handle<v8::Value> jsevent, Event*) = 0;
+        void invokeEventHandler(v8::Handle<v8::Context>, Event*, v8::Handle<v8::Value> jsEvent);
 
         // Get the receiver object to use for event listener call.
         v8::Local<v8::Object> getReceiverObject(Event*);
 
+        int lineNumber() const { return m_lineNumber; }
+
+    private:
+        // Implementation of EventListener function.
+        virtual bool virtualisAttribute() const { return m_isAttribute; }
+
+        virtual v8::Local<v8::Value> callListenerFunction(v8::Handle<v8::Value> jsevent, Event*) = 0;
+
+        v8::Persistent<v8::Object> m_listener;
+
+        // Indicates if the above handle is weak.
+        bool m_isWeak;
+
+        // Indicates if this is an HTML type listener.
+        bool m_isAttribute;
+
         // Frame to which the event listener is attached to. An event listener must be destroyed before its owner frame is
         // deleted. See fast/dom/replaceChild.html
         // FIXME: this could hold m_frame live until the event listener is deleted.
@@ -97,10 +138,6 @@ namespace WebCore {
         // Position in the HTML source for HTML event listeners.
         int m_lineNumber;
         int m_columnNumber;
-
-        friend class V8EventListener;
-        friend class V8ObjectEventListener;
-        friend class V8LazyEventListener;
     };
 
 } // namespace WebCore
diff --git a/WebCore/bindings/v8/V8DOMWrapper.cpp b/WebCore/bindings/v8/V8DOMWrapper.cpp
index 6f62d59..ac36444 100644
--- a/WebCore/bindings/v8/V8DOMWrapper.cpp
+++ b/WebCore/bindings/v8/V8DOMWrapper.cpp
@@ -36,18 +36,19 @@
 #include "DOMObjectsInclude.h"
 #include "DocumentLoader.h"
 #include "FrameLoaderClient.h"
+#include "Notification.h"
 #include "SVGElementInstance.h"
 #include "ScriptController.h"
 #include "V8AbstractEventListener.h"
 #include "V8Binding.h"
 #include "V8Collection.h"
 #include "V8CustomBinding.h"
+#include "V8CustomEventListener.h"
 #include "V8DOMMap.h"
 #include "V8DOMWindow.h"
 #include "V8EventListenerList.h"
 #include "V8Index.h"
 #include "V8IsolatedWorld.h"
-#include "V8ObjectEventListener.h"
 #include "V8Proxy.h"
 #include "WorkerContextExecutionProxy.h"
 
@@ -393,6 +394,15 @@ v8::Persistent<v8::FunctionTemplate> V8DOMWrapper::getTemplate(V8ClassIndex::V8W
     }
 #endif // NOTIFICATIONS
 
+#if ENABLE(SVG)
+    case V8ClassIndex::SVGELEMENTINSTANCE: {
+        // Reserve one more internal field for keeping event listeners.
+        v8::Local<v8::ObjectTemplate> instanceTemplate = descriptor->InstanceTemplate();
+        instanceTemplate->SetInternalFieldCount(V8Custom::kSVGElementInstanceInternalFieldCount);
+        break;
+    }
+#endif
+
 #if ENABLE(WORKERS)
     case V8ClassIndex::ABSTRACTWORKER: {
         // Reserve one more internal field for keeping event listeners.
@@ -1375,7 +1385,7 @@ v8::Handle<v8::Value> V8DOMWrapper::convertEventListenerToV8Object(EventListener
     return v8listener->getListenerObject();
 }
 
-PassRefPtr<EventListener> V8DOMWrapper::getEventListener(Node* node, v8::Local<v8::Value> value, bool isAttribute, bool findOnly)
+PassRefPtr<EventListener> V8DOMWrapper::getEventListener(Node* node, v8::Local<v8::Value> value, bool isAttribute, ListenerLookupType lookup)
 {
     ScriptExecutionContext* context = node->scriptExecutionContext();
     if (!context)
@@ -1387,19 +1397,85 @@ PassRefPtr<EventListener> V8DOMWrapper::getEventListener(Node* node, v8::Local<v
     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);
+    if (proxy)
+        return (lookup == ListenerFindOnly) ? V8EventListenerList::findWrapper(value, isAttribute) : V8EventListenerList::findOrCreateWrapper<V8EventListener>(proxy->frame(), value, isAttribute);
+
+    return 0;
+}
+
+PassRefPtr<EventListener> V8DOMWrapper::getEventListener(SVGElementInstance* element, v8::Local<v8::Value> value, bool isAttribute, ListenerLookupType lookup)
+{
+    return getEventListener(element->correspondingElement(), value, isAttribute, lookup);
+}
+
+PassRefPtr<EventListener> V8DOMWrapper::getEventListener(AbstractWorker* worker, v8::Local<v8::Value> value, bool isAttribute, ListenerLookupType lookup)
+{
+    if (worker->scriptExecutionContext()->isWorkerContext()) {
+        WorkerContextExecutionProxy* workerContextProxy = WorkerContextExecutionProxy::retrieve();
+        ASSERT(workerContextProxy);
+        return workerContextProxy->findOrCreateEventListener(value, isAttribute, lookup == ListenerFindOnly);
     }
 
+    V8Proxy* proxy = V8Proxy::retrieve(worker->scriptExecutionContext());
+    if (proxy)
+        return (lookup == ListenerFindOnly) ? V8EventListenerList::findWrapper(value, isAttribute) : V8EventListenerList::findOrCreateWrapper<V8EventListener>(proxy->frame(), value, isAttribute);
+
     return 0;
 }
 
-PassRefPtr<EventListener> V8DOMWrapper::getEventListener(SVGElementInstance* element, v8::Local<v8::Value> value, bool isAttribute, bool findOnly)
+#if ENABLE(NOTIFICATIONS)
+PassRefPtr<EventListener> V8DOMWrapper::getEventListener(Notification* notification, v8::Local<v8::Value> value, bool isAttribute, ListenerLookupType lookup)
 {
-    return getEventListener(element->correspondingElement(), value, isAttribute, findOnly);
+    if (notification->scriptExecutionContext()->isWorkerContext()) {
+        WorkerContextExecutionProxy* workerContextProxy = WorkerContextExecutionProxy::retrieve();
+        ASSERT(workerContextProxy);
+        return workerContextProxy->findOrCreateEventListener(value, isAttribute, lookup == ListenerFindOnly);
+    }
+
+    V8Proxy* proxy = V8Proxy::retrieve(notification->scriptExecutionContext());
+    if (proxy)
+        return (lookup == ListenerFindOnly) ? V8EventListenerList::findWrapper(value, isAttribute) : V8EventListenerList::findOrCreateWrapper<V8EventListener>(proxy->frame(), value, isAttribute);
+
+    return 0;
 }
+#endif
+
+PassRefPtr<EventListener> V8DOMWrapper::getEventListener(WorkerContext* workerContext, v8::Local<v8::Value> value, bool isAttribute, ListenerLookupType lookup)
+{
+    WorkerContextExecutionProxy* workerContextProxy = workerContext->script()->proxy();
+    if (workerContextProxy)
+        return workerContextProxy->findOrCreateEventListener(value, isAttribute, lookup == ListenerFindOnly);
+
+    return 0;
+}
+
+PassRefPtr<EventListener> V8DOMWrapper::getEventListener(XMLHttpRequestUpload* upload, v8::Local<v8::Value> value, bool isAttribute, ListenerLookupType lookup)
+{
+    return getEventListener(upload->associatedXMLHttpRequest(), value, isAttribute, lookup);
+}
+
+PassRefPtr<EventListener> V8DOMWrapper::getEventListener(EventTarget* eventTarget, v8::Local<v8::Value> value, bool isAttribute, ListenerLookupType lookup)
+{
+    V8Proxy* proxy = V8Proxy::retrieve(eventTarget->scriptExecutionContext());
+    if (proxy)
+        return (lookup == ListenerFindOnly) ? V8EventListenerList::findWrapper(value, isAttribute) : V8EventListenerList::findOrCreateWrapper<V8EventListener>(proxy->frame(), value, isAttribute);
 
+#if ENABLE(WORKERS)
+    WorkerContextExecutionProxy* workerContextProxy = WorkerContextExecutionProxy::retrieve();
+    if (workerContextProxy)
+        return workerContextProxy->findOrCreateEventListener(value, isAttribute, lookup == ListenerFindOnly);
+#endif
+
+    return 0;
+}
+
+PassRefPtr<EventListener> V8DOMWrapper::getEventListener(V8Proxy* proxy, v8::Local<v8::Value> value, bool isAttribute, ListenerLookupType lookup)
+{
+    if (proxy)
+        return (lookup == ListenerFindOnly) ? V8EventListenerList::findWrapper(value, isAttribute) : V8EventListenerList::findOrCreateWrapper<V8EventListener>(proxy->frame(), value, isAttribute);
+
+    return 0;
+}
 
 v8::Handle<v8::Value> V8DOMWrapper::convertDOMImplementationToV8Object(DOMImplementation* impl)
 {
diff --git a/WebCore/bindings/v8/V8DOMWrapper.h b/WebCore/bindings/v8/V8DOMWrapper.h
index ae1fb91..43b7070 100644
--- a/WebCore/bindings/v8/V8DOMWrapper.h
+++ b/WebCore/bindings/v8/V8DOMWrapper.h
@@ -93,6 +93,11 @@ namespace WebCore {
 #endif
     class WorkerContext;
 
+    enum ListenerLookupType {
+        ListenerFindOnly,
+        ListenerFindOrCreate,
+    };
+
     class V8DOMWrapper {
     public:
 #ifndef NDEBUG
@@ -215,9 +220,24 @@ namespace WebCore {
 
         static v8::Handle<v8::Value> convertEventListenerToV8Object(EventListener*);
 
-        static PassRefPtr<EventListener> getEventListener(Node* node, v8::Local<v8::Value> value, bool isAttribute, bool findOnly);
+        static PassRefPtr<EventListener> getEventListener(Node* node, v8::Local<v8::Value> value, bool isAttribute, ListenerLookupType lookup);
+
+        static PassRefPtr<EventListener> getEventListener(SVGElementInstance* element, v8::Local<v8::Value> value, bool isAttribute, ListenerLookupType lookup);
+
+        static PassRefPtr<EventListener> getEventListener(AbstractWorker* worker, v8::Local<v8::Value> value, bool isAttribute, ListenerLookupType lookup);
+
+#if ENABLE(NOTIFICATIONS)
+        static PassRefPtr<EventListener> getEventListener(Notification* notification, v8::Local<v8::Value> value, bool isAttribute, ListenerLookupType lookup);
+#endif
+
+        static PassRefPtr<EventListener> getEventListener(WorkerContext* workerContext, v8::Local<v8::Value> value, bool isAttribute, ListenerLookupType lookup);
+
+        static PassRefPtr<EventListener> getEventListener(XMLHttpRequestUpload* upload, v8::Local<v8::Value> value, bool isAttribute, ListenerLookupType lookup);
+
+        static PassRefPtr<EventListener> getEventListener(EventTarget* eventTarget, v8::Local<v8::Value> value, bool isAttribute, ListenerLookupType lookup);
+
+        static PassRefPtr<EventListener> getEventListener(V8Proxy* proxy, v8::Local<v8::Value> value, bool isAttribute, ListenerLookupType lookup);
 
-        static PassRefPtr<EventListener> getEventListener(SVGElementInstance* element, v8::Local<v8::Value> value, bool isAttribute, bool findOnly);
 
         // DOMImplementation is a singleton and it is handled in a special
         // way. A wrapper is generated per document and stored in an
diff --git a/WebCore/bindings/v8/V8EventListenerList.cpp b/WebCore/bindings/v8/V8EventListenerList.cpp
index c9aaa12..e37d630 100644
--- a/WebCore/bindings/v8/V8EventListenerList.cpp
+++ b/WebCore/bindings/v8/V8EventListenerList.cpp
@@ -31,165 +31,6 @@
 #include "config.h"
 #include "V8EventListenerList.h"
 
-#include "V8CustomEventListener.h"
-
 namespace WebCore {
 
-V8EventListenerListIterator::V8EventListenerListIterator(V8EventListenerList* list)
-    : m_list(list)
-    , m_vectorIndex(0)
-    , m_iter(list->m_table.begin())
-{
-}
-
-V8EventListenerListIterator::V8EventListenerListIterator(V8EventListenerList* list, bool shouldSeekToEnd)
-    : m_list(list)
-    , m_vectorIndex(0)
-    , m_iter(list->m_table.begin())
-{
-    if (shouldSeekToEnd)
-        seekToEnd();
-}
-
-V8EventListenerListIterator::~V8EventListenerListIterator() { }
-
-void V8EventListenerListIterator::operator++()
-{
-    if (m_iter != m_list->m_table.end()) {
-        Vector<V8EventListener*>* vector = m_iter->second;
-        if (m_vectorIndex + 1 < vector->size()) {
-            m_vectorIndex++;
-            return;
-        }
-        m_vectorIndex = 0;
-        ++m_iter;
-    }
-}
-
-bool V8EventListenerListIterator::operator==(const V8EventListenerListIterator& other)
-{
-    return other.m_iter == m_iter && other.m_vectorIndex == m_vectorIndex && other.m_list == m_list;
-}
-
-bool V8EventListenerListIterator::operator!=(const V8EventListenerListIterator& other)
-{
-    return !operator==(other);
-}
-
-V8EventListener* V8EventListenerListIterator::operator*()
-{
-    if (m_iter != m_list->m_table.end()) {
-        Vector<V8EventListener*>* vector = m_iter->second;
-        if (m_vectorIndex < vector->size())
-            return vector->at(m_vectorIndex);
-    }
-    return 0;
-}
-
-void V8EventListenerListIterator::seekToEnd()
-{
-    m_iter = m_list->m_table.end();
-    m_vectorIndex = 0;
-}
-
-
-V8EventListenerList::V8EventListenerList()
-{
-}
-
-V8EventListenerList::~V8EventListenerList()
-{
-}
-
-V8EventListenerListIterator V8EventListenerList::begin()
-{
-    return iterator(this);
-}
-
-V8EventListenerListIterator V8EventListenerList::end()
-{
-    return iterator(this, true);
-}
-
-
-static int getKey(v8::Local<v8::Object> object)
-{
-    // 0 is a sentinel value for the HashMap key, so we map it to 1.
-    int hash = object->GetIdentityHash();
-    if (!hash)
-        return 1;
-    return hash;
-}
-
-void V8EventListenerList::add(V8EventListener* listener)
-{
-    ASSERT(v8::Context::InContext());
-    v8::HandleScope handleScope;
-
-    v8::Local<v8::Object> object = listener->getListenerObject();
-    int key = getKey(object);
-    Vector<V8EventListener*>* vector = m_table.get(key);
-    if (!vector) {
-        vector = new Vector<V8EventListener*>();
-        m_table.set(key, vector);
-    }
-    vector->append(listener);
-    m_reverseTable.set(listener, key);
-}
-
-void V8EventListenerList::remove(V8EventListener* listener)
-{
-    if (m_reverseTable.contains(listener)) {
-        int key = m_reverseTable.get(listener);
-        Vector<V8EventListener*>* vector = m_table.get(key);
-        if (!vector)
-            return;
-        for (size_t j = 0; j < vector->size(); j++) {
-            if (vector->at(j) == listener) {
-                vector->remove(j);
-                if (!vector->size()) {
-                    m_table.remove(key);
-                    delete vector;
-                    vector = 0;
-                }
-                m_reverseTable.remove(listener);
-                return;
-            }
-        }
-    }
-}
-
-void V8EventListenerList::clear()
-{
-    m_table.clear();
-    m_reverseTable.clear();
-}
-
-V8EventListener* V8EventListenerList::find(v8::Local<v8::Object> object, bool isAttribute)
-{
-    ASSERT(v8::Context::InContext());
-    int key = getKey(object);
-
-    Vector<V8EventListener*>* vector = m_table.get(key);
-    if (!vector)
-        return 0;
-
-    for (size_t i = 0; i < vector->size(); i++) {
-        V8EventListener* element = vector->at(i);
-        if (isAttribute == element->isAttribute() && object == element->getListenerObject())
-            return element;
-    }
-    return 0;
-}
-
-PassRefPtr<V8EventListener> V8EventListenerList::findWrapper(v8::Local<v8::Value> object, bool isAttribute)
-{
-    ASSERT(v8::Context::InContext());
-    if (!object->IsObject())
-        return 0;
-
-    // FIXME: Should this be v8::Local<v8::Object>::Cast instead?
-    return find(object->ToObject(), isAttribute);
-}
-
 } // namespace WebCore
diff --git a/WebCore/bindings/v8/V8EventListenerList.h b/WebCore/bindings/v8/V8EventListenerList.h
index 4255050..a863ed9 100644
--- a/WebCore/bindings/v8/V8EventListenerList.h
+++ b/WebCore/bindings/v8/V8EventListenerList.h
@@ -32,92 +32,74 @@
 #define V8EventListenerList_h
 
 #include <v8.h>
-#include <wtf/Vector.h>
-#include <wtf/HashMap.h>
 
 #include "PassRefPtr.h"
+#include "V8CustomEventListener.h"
+#include "V8HiddenPropertyName.h"
 
 namespace WebCore {
     class Frame;
     class V8EventListener;
-    class V8EventListenerListIterator;
 
-    // This is a container for V8EventListener objects that uses the identity hash of the v8::Object to
-    // speed up lookups
+    // This is a container for V8EventListener objects that uses hidden properties of v8::Object to speed up lookups.
     class V8EventListenerList {
     public:
-        // Because v8::Object identity hashes are not guaranteed to be unique, we unfortunately can't just map
-        // an int to V8EventListener. Instead we define a HashMap of int to Vector of V8EventListener
-        // called a ListenerMultiMap.
-        typedef Vector<V8EventListener*>* Values;
-        struct ValuesTraits : HashTraits<Values> {
-            static const bool needsDestruction = true;
-        };
-        typedef HashMap<int, Values, DefaultHash<int>::Hash, HashTraits<int>, ValuesTraits> ListenerMultiMap;
-
-        V8EventListenerList();
-        ~V8EventListenerList();
-
-        friend class V8EventListenerListIterator;
-        typedef V8EventListenerListIterator iterator;        
-
-        iterator begin();
-        iterator end();
-
-        void add(V8EventListener*);
-        void remove(V8EventListener*);
-        V8EventListener* find(v8::Local<v8::Object>, bool isAttribute);
-        void clear();
-        size_t size() { return m_table.size(); }
-
-        PassRefPtr<V8EventListener> findWrapper(v8::Local<v8::Value>, bool isAttribute);
-        template<typename WrapperType>
-        PassRefPtr<V8EventListener> findOrCreateWrapper(Frame*, v8::Local<v8::Value>, bool isAttribute);
+        static PassRefPtr<V8EventListener> findWrapper(v8::Local<v8::Value> value, bool isAttribute)
+        {
+            ASSERT(v8::Context::InContext());
+            if (!value->IsObject())
+                return 0;
 
-    private:
-        ListenerMultiMap m_table;
+            v8::Handle<v8::String> wrapperProperty = getHiddenProperty(isAttribute);
+            return doFindWrapper(v8::Local<v8::Object>::Cast(value), wrapperProperty);
+        }
 
-        // we also keep a reverse mapping of V8EventListener to v8::Object identity hash,
-        // in order to speed up removal by V8EventListener
-        HashMap<V8EventListener*, int> m_reverseTable;
-    };
+        template<typename WrapperType, typename ContextType>
+        static PassRefPtr<V8EventListener> findOrCreateWrapper(ContextType*, v8::Local<v8::Value>, bool isAttribute);
+
+        static void clearWrapper(v8::Handle<v8::Object> listenerObject, bool isAttribute)
+        {
+            v8::Handle<v8::String> wrapperProperty = getHiddenProperty(isAttribute);
+            listenerObject->DeleteHiddenValue(wrapperProperty);
+        }
 
-    class V8EventListenerListIterator {
-    public:
-        ~V8EventListenerListIterator();
-        void operator++();
-        bool operator==(const V8EventListenerListIterator&);
-        bool operator!=(const V8EventListenerListIterator&);
-        V8EventListener* operator*();
     private:
-        friend class V8EventListenerList;
-        explicit V8EventListenerListIterator(V8EventListenerList*);
-        V8EventListenerListIterator(V8EventListenerList*, bool shouldSeekToEnd);
-        void seekToEnd();
-
-        V8EventListenerList* m_list;
-        V8EventListenerList::ListenerMultiMap::iterator m_iter;
-        size_t m_vectorIndex;
+        static V8EventListener* doFindWrapper(v8::Local<v8::Object> object, v8::Handle<v8::String> wrapperProperty)
+        {
+            ASSERT(v8::Context::InContext());
+            v8::HandleScope scope;
+            v8::Local<v8::Value> listener = object->GetHiddenValue(wrapperProperty);
+            if (listener.IsEmpty())
+                return 0;
+            return static_cast<V8EventListener*>(v8::External::Unwrap(listener));
+        }
+
+        static inline v8::Handle<v8::String> getHiddenProperty(bool isAttribute)
+        {
+            return isAttribute ? V8HiddenPropertyName::attributeListener() : V8HiddenPropertyName::listener();
+        }
     };
 
-    template<typename WrapperType>
-    PassRefPtr<V8EventListener> V8EventListenerList::findOrCreateWrapper(Frame* frame, v8::Local<v8::Value> object, bool isAttribute)
+    template<typename WrapperType, typename ContextType>
+    PassRefPtr<V8EventListener> V8EventListenerList::findOrCreateWrapper(ContextType* context, v8::Local<v8::Value> value, bool isAttribute)
     {
         ASSERT(v8::Context::InContext());
-        if (!object->IsObject())
+        if (!value->IsObject())
             return 0;
 
-        // FIXME: Should this be v8::Local<v8::Object>::Cast instead?
-        V8EventListener* wrapper = find(object->ToObject(), isAttribute);
+        v8::Local<v8::Object> object = v8::Local<v8::Object>::Cast(value);
+        v8::Handle<v8::String> wrapperProperty = getHiddenProperty(isAttribute);
+
+        V8EventListener* wrapper = doFindWrapper(object, wrapperProperty);
         if (wrapper)
             return wrapper;
 
-        // Create a new one, and add to cache.
-        RefPtr<WrapperType> newListener = WrapperType::create(frame, v8::Local<v8::Object>::Cast(object), isAttribute);
-        add(newListener.get());
+        PassRefPtr<V8EventListener> wrapperPtr = WrapperType::create(context, object, isAttribute);
+        if (wrapperPtr)
+            object->SetHiddenValue(wrapperProperty, v8::External::Wrap(wrapperPtr.get()));
 
-        return newListener;
-    };
+        return wrapperPtr;
+    }
 
 } // namespace WebCore
 
diff --git a/WebCore/bindings/v8/V8HiddenPropertyName.cpp b/WebCore/bindings/v8/V8HiddenPropertyName.cpp
index 16ac232..7ea2a4c 100644
--- a/WebCore/bindings/v8/V8HiddenPropertyName.cpp
+++ b/WebCore/bindings/v8/V8HiddenPropertyName.cpp
@@ -36,19 +36,30 @@ namespace WebCore {
 v8::Handle<v8::String> V8HiddenPropertyName::objectPrototype()
 {
     static v8::Persistent<v8::String>* string = createString("WebCore::V8HiddenPropertyName::objectPrototype");
-
     return *string;
 }
 
 v8::Handle<v8::String> V8HiddenPropertyName::isolatedWorld()
 {
     static v8::Persistent<v8::String>* string = createString("WebCore::V8HiddenPropertyName::isolatedWorld");
+    return *string;
+}
+
+v8::Handle<v8::String> V8HiddenPropertyName::listener()
+{
+    static v8::Persistent<v8::String>* string = createString("WebCore::V8HiddenPropertyName::listener");
+    return *string;
+}
 
+v8::Handle<v8::String> V8HiddenPropertyName::attributeListener()
+{
+    static v8::Persistent<v8::String>* string = createString("WebCore::V8HiddenPropertyName::attributeListener");
     return *string;
 }
 
 v8::Persistent<v8::String>* V8HiddenPropertyName::createString(const char* key)
 {
+    v8::HandleScope scope;
     return new v8::Persistent<v8::String>(v8::Persistent<v8::String>::New(v8::String::NewSymbol(key)));
 }
 
diff --git a/WebCore/bindings/v8/V8HiddenPropertyName.h b/WebCore/bindings/v8/V8HiddenPropertyName.h
index 874b525..dbe992f 100644
--- a/WebCore/bindings/v8/V8HiddenPropertyName.h
+++ b/WebCore/bindings/v8/V8HiddenPropertyName.h
@@ -39,6 +39,8 @@ namespace WebCore {
     public:
         static v8::Handle<v8::String> objectPrototype();
         static v8::Handle<v8::String> isolatedWorld();
+        static v8::Handle<v8::String> listener();
+        static v8::Handle<v8::String> attributeListener();
 
     private:
         static v8::Persistent<v8::String>* createString(const char* key);
diff --git a/WebCore/bindings/v8/V8LazyEventListener.cpp b/WebCore/bindings/v8/V8LazyEventListener.cpp
index ccf32a7..46f5649 100644
--- a/WebCore/bindings/v8/V8LazyEventListener.cpp
+++ b/WebCore/bindings/v8/V8LazyEventListener.cpp
@@ -37,195 +37,105 @@
 
 namespace WebCore {
 
-V8LazyEventListener::V8LazyEventListener(Frame *frame, const String& code, const String& functionName, bool isSVGEvent)
+V8LazyEventListener::V8LazyEventListener(Frame* frame, const String& code, const String& functionName, bool isSVGEvent)
     : V8AbstractEventListener(frame, true)
     , m_code(code)
     , m_functionName(functionName)
     , m_isSVGEvent(isSVGEvent)
-    , m_compiled(false)
-    , m_wrappedFunctionCompiled(false)
 {
 }
 
-V8LazyEventListener::~V8LazyEventListener()
-{
-    disposeListenerObject();
-
-    // Dispose wrapped function
-    if (!m_wrappedFunction.IsEmpty()) {
-#ifndef NDEBUG
-        V8GCController::unregisterGlobalHandle(this, m_wrappedFunction);
-#endif
-        m_wrappedFunction.Dispose();
-        m_wrappedFunction.Clear();
-    }
-}
-
-v8::Local<v8::Function> V8LazyEventListener::getListenerFunction()
-{
-    if (m_compiled) {
-        ASSERT(m_listener.IsEmpty() || m_listener->IsFunction());
-        return m_listener.IsEmpty() ? v8::Local<v8::Function>() : v8::Local<v8::Function>::New(v8::Persistent<v8::Function>::Cast(m_listener));
-    }
-
-    m_compiled = true;
-
-    ASSERT(m_frame);
-
-    {
-        // Switch to the context of m_frame.
-        v8::HandleScope handleScope;
-
-        // Use the outer scope to hold context.
-        v8::Handle<v8::Context> v8Context = V8Proxy::mainWorldContext(m_frame);
-        // Bail out if we could not get the context.
-        if (v8Context.IsEmpty())
-            return v8::Local<v8::Function>();
-
-        v8::Context::Scope scope(v8Context);
-
-        // Wrap function around the event code.  The parenthesis around the function are needed so that evaluating the code yields
-        // the function value.  Without the parenthesis the function value is thrown away.
-
-        // Make it an anonymous function to avoid name conflict for cases like
-        // <body onload='onload()'>
-        // <script> function onload() { alert('hi'); } </script>.
-        // Set function name to function object instead.
-        // See issue 944690.
-        //
-        // The ECMAScript spec says (very obliquely) that the parameter to an event handler is named "evt".
-        //
-        // Don't use new lines so that lines in the modified handler
-        // have the same numbers as in the original code.
-        String code = "(function (evt) {";
-        code.append(m_code);
-        code.append("\n})");
-
-        v8::Handle<v8::String> codeExternalString = v8ExternalString(code);
-        v8::Handle<v8::Script> script = V8Proxy::compileScript(codeExternalString, m_frame->document()->url(), m_lineNumber - 1);
-        if (!script.IsEmpty()) {
-            V8Proxy* proxy = V8Proxy::retrieve(m_frame);
-            ASSERT(proxy);
-            v8::Local<v8::Value> value = proxy->runScript(script, false);
-            if (!value.IsEmpty()) {
-                ASSERT(value->IsFunction());
-                v8::Local<v8::Function> listenerFunction = v8::Local<v8::Function>::Cast(value);
-                listenerFunction->SetName(v8::String::New(fromWebCoreString(m_functionName), m_functionName.length()));
-
-                m_listener = v8::Persistent<v8::Function>::New(listenerFunction);
-#ifndef NDEBUG
-                V8GCController::registerGlobalHandle(EVENT_LISTENER, this, m_listener);
-#endif
-            }
-        }
-    }
-
-    ASSERT(m_listener.IsEmpty() || m_listener->IsFunction());
-    return m_listener.IsEmpty() ? v8::Local<v8::Function>() : v8::Local<v8::Function>::New(v8::Persistent<v8::Function>::Cast(m_listener));
-}
-
 v8::Local<v8::Value> V8LazyEventListener::callListenerFunction(v8::Handle<v8::Value> jsEvent, Event* event)
 {
-    v8::Local<v8::Function> handlerFunction = getWrappedListenerFunction();
+    v8::Local<v8::Function> handlerFunction = v8::Local<v8::Function>::Cast(getListenerObject());
     v8::Local<v8::Object> receiver = getReceiverObject(event);
     if (handlerFunction.IsEmpty() || receiver.IsEmpty())
         return v8::Local<v8::Value>();
 
     v8::Handle<v8::Value> parameters[1] = { jsEvent };
 
-    V8Proxy* proxy = V8Proxy::retrieve(m_frame);
+    V8Proxy* proxy = V8Proxy::retrieve(frame());
     return proxy->callFunction(handlerFunction, receiver, 1, parameters);
 }
 
-
 static v8::Handle<v8::Value> V8LazyEventListenerToString(const v8::Arguments& args)
 {
     return args.Callee()->GetHiddenValue(v8::String::New("toStringString"));
 }
 
-
-v8::Local<v8::Function> V8LazyEventListener::getWrappedListenerFunction()
+void V8LazyEventListener::prepareListenerObject()
 {
-    if (m_wrappedFunctionCompiled) {
-        ASSERT(m_wrappedFunction.IsEmpty() || m_wrappedFunction->IsFunction());
-        return m_wrappedFunction.IsEmpty() ? v8::Local<v8::Function>() : v8::Local<v8::Function>::New(m_wrappedFunction);
-    }
-
-    m_wrappedFunctionCompiled = true;
-
-    {
-        // Switch to the context of m_frame.
-        v8::HandleScope handleScope;
-
-        // Use the outer scope to hold context.
-        v8::Handle<v8::Context> v8Context = V8Proxy::mainWorldContext(m_frame);
-        // Bail out if we cannot get the context.
-        if (v8Context.IsEmpty())
-            return v8::Local<v8::Function>();
-
-        v8::Context::Scope scope(v8Context);
-
-        // FIXME: cache the wrapper function.
-
-        // Nodes other than the document object, when executing inline event handlers push document, form, and the target node on the scope chain.
-        // We do this by using 'with' statement.
-        // See chrome/fast/forms/form-action.html
-        //     chrome/fast/forms/selected-index-value.html
-        //     base/fast/overflow/onscroll-layer-self-destruct.html
-        //
-        // Don't use new lines so that lines in the modified handler
-        // have the same numbers as in the original code.
-        String code = "(function (evt) {" \
-                      "with (this.ownerDocument ? this.ownerDocument : {}) {" \
-                      "with (this.form ? this.form : {}) {" \
-                      "with (this) {" \
-                      "return (function(evt){";
-        code.append(m_code);
-        // Insert '\n' otherwise //-style comments could break the handler.
-        code.append(  "\n}).call(this, evt);}}}})");
-        v8::Handle<v8::String> codeExternalString = v8ExternalString(code);
-        v8::Handle<v8::Script> script = V8Proxy::compileScript(codeExternalString, m_frame->document()->url(), m_lineNumber);
-        if (!script.IsEmpty()) {
-            V8Proxy* proxy = V8Proxy::retrieve(m_frame);
-            ASSERT(proxy);
-            v8::Local<v8::Value> value = proxy->runScript(script, false);
-            if (!value.IsEmpty()) {
-                ASSERT(value->IsFunction());
-
-                m_wrappedFunction = v8::Persistent<v8::Function>::New(v8::Local<v8::Function>::Cast(value));
-
-                // Change the toString function on the wrapper function to avoid it returning the source for the actual wrapper function. Instead
-                // it returns source for a clean wrapper function with the event argument wrapping the event source code. The reason for this
-                // is that some web sites uses toString on event functions and the evals the source returned (some times a RegExp is applied as
-                // well) for some other use. That fails miserably if the actual wrapper source is returned.
-                v8::Local<v8::FunctionTemplate> toStringTemplate = v8::FunctionTemplate::New(V8LazyEventListenerToString);
-                v8::Local<v8::Function> toStringFunction;
-                if (!toStringTemplate.IsEmpty())
-                    toStringFunction = toStringTemplate->GetFunction();
-                if (!toStringFunction.IsEmpty()) {
-                    String toStringResult = "function ";
-                    toStringResult.append(m_functionName);
-                    toStringResult.append("(");
-                    if (m_isSVGEvent)
-                        toStringResult.append("evt");
-                    else
-                        toStringResult.append("event");
-                    toStringResult.append(") {\n  ");
-                    toStringResult.append(m_code);
-                    toStringResult.append("\n}");
-                    toStringFunction->SetHiddenValue(v8::String::New("toStringString"), v8ExternalString(toStringResult));
-                    m_wrappedFunction->Set(v8::String::New("toString"), toStringFunction);
-                }
-
-#ifndef NDEBUG
-                V8GCController::registerGlobalHandle(EVENT_LISTENER, this, m_wrappedFunction);
-#endif
-                m_wrappedFunction->SetName(v8::String::New(fromWebCoreString(m_functionName), m_functionName.length()));
+    if (hasExistingListenerObject())
+        return;
+
+    // Switch to the context of m_frame.
+    v8::HandleScope handleScope;
+
+    // Use the outer scope to hold context.
+    v8::Handle<v8::Context> v8Context = V8Proxy::mainWorldContext(frame());
+    // Bail out if we cannot get the context.
+    if (v8Context.IsEmpty())
+        return;
+
+    v8::Context::Scope scope(v8Context);
+
+    // FIXME: cache the wrapper function.
+
+    // Nodes other than the document object, when executing inline event handlers push document, form, and the target node on the scope chain.
+    // We do this by using 'with' statement.
+    // See chrome/fast/forms/form-action.html
+    //     chrome/fast/forms/selected-index-value.html
+    //     base/fast/overflow/onscroll-layer-self-destruct.html
+    //
+    // Don't use new lines so that lines in the modified handler
+    // have the same numbers as in the original code.
+    String code = "(function (evt) {" \
+            "with (this.ownerDocument ? this.ownerDocument : {}) {" \
+            "with (this.form ? this.form : {}) {" \
+            "with (this) {" \
+            "return (function(evt){";
+    code.append(m_code);
+    // Insert '\n' otherwise //-style comments could break the handler.
+    code.append(  "\n}).call(this, evt);}}}})");
+    v8::Handle<v8::String> codeExternalString = v8ExternalString(code);
+    v8::Handle<v8::Script> script = V8Proxy::compileScript(codeExternalString, frame()->document()->url(), lineNumber());
+    if (!script.IsEmpty()) {
+        V8Proxy* proxy = V8Proxy::retrieve(frame());
+        ASSERT(proxy);
+        v8::Local<v8::Value> value = proxy->runScript(script, false);
+        if (!value.IsEmpty()) {
+            ASSERT(value->IsFunction());
+
+            v8::Local<v8::Function> wrappedFunction = v8::Local<v8::Function>::Cast(value);
+
+            // Change the toString function on the wrapper function to avoid it returning the source for the actual wrapper function. Instead
+            // it returns source for a clean wrapper function with the event argument wrapping the event source code. The reason for this
+            // is that some web sites uses toString on event functions and the evals the source returned (some times a RegExp is applied as
+            // well) for some other use. That fails miserably if the actual wrapper source is returned.
+            v8::Local<v8::FunctionTemplate> toStringTemplate = v8::FunctionTemplate::New(V8LazyEventListenerToString);
+            v8::Local<v8::Function> toStringFunction;
+            if (!toStringTemplate.IsEmpty())
+                toStringFunction = toStringTemplate->GetFunction();
+            if (!toStringFunction.IsEmpty()) {
+                String toStringResult = "function ";
+                toStringResult.append(m_functionName);
+                toStringResult.append("(");
+                if (m_isSVGEvent)
+                    toStringResult.append("evt");
+                else
+                    toStringResult.append("event");
+                toStringResult.append(") {\n  ");
+                toStringResult.append(m_code);
+                toStringResult.append("\n}");
+                toStringFunction->SetHiddenValue(v8::String::New("toStringString"), v8ExternalString(toStringResult));
+                wrappedFunction->Set(v8::String::New("toString"), toStringFunction);
             }
+
+            wrappedFunction->SetName(v8::String::New(fromWebCoreString(m_functionName), m_functionName.length()));
+
+            setListenerObject(wrappedFunction);
         }
     }
-
-    return v8::Local<v8::Function>::New(m_wrappedFunction);
 }
 
 } // namespace WebCore
diff --git a/WebCore/bindings/v8/V8LazyEventListener.h b/WebCore/bindings/v8/V8LazyEventListener.h
index c9f6a84..ba460e6 100644
--- a/WebCore/bindings/v8/V8LazyEventListener.h
+++ b/WebCore/bindings/v8/V8LazyEventListener.h
@@ -50,30 +50,19 @@ namespace WebCore {
             return adoptRef(new V8LazyEventListener(frame, code, functionName, isSVGEvent));
         }
 
-        // For lazy event listener, the listener object is the same as its listener
-        // function without additional scope chains.
-        virtual v8::Local<v8::Object> getListenerObject() { return getWrappedListenerFunction(); }
+        virtual bool isLazy() const { return true; }
+
+    protected:
+        virtual void prepareListenerObject();
 
     private:
         V8LazyEventListener(Frame*, const String& code, const String& functionName, bool isSVGEvent);
-        virtual ~V8LazyEventListener();
 
-        virtual bool virtualisAttribute() const { return true; }
+        virtual v8::Local<v8::Value> callListenerFunction(v8::Handle<v8::Value> jsEvent, Event*);
 
         String m_code;
         String m_functionName;
         bool m_isSVGEvent;
-        bool m_compiled;
-
-        // If the event listener is on a non-document dom node, we compile the function with some implicit scope chains before it.
-        bool m_wrappedFunctionCompiled;
-        v8::Persistent<v8::Function> m_wrappedFunction;
-
-        v8::Local<v8::Function> getWrappedListenerFunction();
-
-        virtual v8::Local<v8::Value> callListenerFunction(v8::Handle<v8::Value> jsEvent, Event*);
-
-        v8::Local<v8::Function> getListenerFunction();
     };
 
 } // namespace WebCore
diff --git a/WebCore/bindings/v8/V8ObjectEventListener.cpp b/WebCore/bindings/v8/V8ObjectEventListener.cpp
deleted file mode 100644
index f10766c..0000000
--- a/WebCore/bindings/v8/V8ObjectEventListener.cpp
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (C) 2006, 2007, 2008, 2009 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "V8ObjectEventListener.h"
-
-#include "Frame.h"
-#include "V8Proxy.h"
-
-namespace WebCore {
-
-static void weakObjectEventListenerCallback(v8::Persistent<v8::Value>, void* parameter)
-{
-    V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(parameter);
-
-    // Remove the wrapper
-    Frame* frame = listener->frame();
-    if (frame) {
-        V8Proxy* proxy = V8Proxy::retrieve(frame);
-        if (proxy)
-            proxy->objectListeners()->remove(listener);
-
-        // Because the listener is no longer in the list, it must be disconnected from the frame to avoid dangling frame pointer
-        // in the destructor.
-        listener->disconnectFrame();
-    }
-    listener->disposeListenerObject();
-}
-
-// An object event listener wrapper only holds a weak reference to the
-// JS function. A strong reference can create a cycle.
-//
-// The lifetime of these objects is bounded by the life time of the JS
-// wrapper of XHR or Node. So we can create a hidden reference from
-// the JS wrapper to to its JS function.
-//
-//                          (map)
-//          XHR or Node  <----------  JS_wrapper
-//               |             (hidden) :  ^
-//               V                      V  : (may be reachable by closure)
-//           V8_listener  --------> JS_function
-//                         (weak)  <-- may create a cycle if it is strong
-//
-// The persistent reference is made weak in the constructor of
-// V8ObjectEventListener.
-
-V8ObjectEventListener::V8ObjectEventListener(Frame* frame, v8::Local<v8::Object> listener, bool isInline)
-    : V8EventListener(frame, listener, isInline)
-{
-    m_listener.MakeWeak(this, weakObjectEventListenerCallback);
-}
-
-V8ObjectEventListener::~V8ObjectEventListener()
-{
-    if (m_frame) {
-        ASSERT(!m_listener.IsEmpty());
-        V8Proxy* proxy = V8Proxy::retrieve(m_frame);
-        if (proxy)
-            proxy->objectListeners()->remove(this);
-    }
-
-    disposeListenerObject();
-}
-
-} // namespace WebCore
diff --git a/WebCore/bindings/v8/V8ObjectEventListener.h b/WebCore/bindings/v8/V8ObjectEventListener.h
deleted file mode 100644
index 3c5ae10..0000000
--- a/WebCore/bindings/v8/V8ObjectEventListener.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2006, 2007, 2008, 2009 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef V8ObjectEventListener_h
-#define V8ObjectEventListener_h
-
-#include "V8CustomEventListener.h"
-#include <v8.h>
-#include <wtf/PassRefPtr.h>
-
-namespace WebCore {
-
-    class Frame;
-
-    // V8ObjectEventListener is a special listener wrapper for objects not in the DOM.  It keeps the JS listener as a weak pointer.
-    class V8ObjectEventListener : public V8EventListener {
-    public:
-        static PassRefPtr<V8ObjectEventListener> create(Frame* frame, v8::Local<v8::Object> listener, bool isInline)
-        {
-            return adoptRef(new V8ObjectEventListener(frame, listener, isInline));
-        }
-
-        virtual bool isObjectListener() const { return true; }
-
-    private:
-        V8ObjectEventListener(Frame*, v8::Local<v8::Object> listener, bool isInline);
-        virtual ~V8ObjectEventListener();
-    };
-
-} // namespace WebCore
-
-#endif // V8ObjectEventListener_h
diff --git a/WebCore/bindings/v8/V8Proxy.cpp b/WebCore/bindings/v8/V8Proxy.cpp
index 4fb0f68..2a6dd62 100644
--- a/WebCore/bindings/v8/V8Proxy.cpp
+++ b/WebCore/bindings/v8/V8Proxy.cpp
@@ -228,22 +228,6 @@ void V8Proxy::destroyGlobal()
     }
 }
 
-static void disconnectEventListenersInList(V8EventListenerList& list)
-{
-    V8EventListenerList::iterator it = list.begin();
-    while (it != list.end()) {
-        (*it)->disconnectFrame();
-        ++it;
-    }
-    list.clear();
-}
-
-void V8Proxy::disconnectEventListeners()
-{
-    disconnectEventListenersInList(m_eventListeners);
-    disconnectEventListenersInList(m_objectListeners);
-}
-
 v8::Handle<v8::Script> V8Proxy::compileScript(v8::Handle<v8::String> code, const String& fileName, int baseLine)
 {
     const uint16_t* fileNameString = fromWebCoreString(fileName);
@@ -566,7 +550,6 @@ V8Proxy* V8Proxy::retrieve(ScriptExecutionContext* context)
 
 void V8Proxy::disconnectFrame()
 {
-    disconnectEventListeners();
 }
 
 bool V8Proxy::isEnabled()
@@ -712,8 +695,6 @@ void V8Proxy::clearForClose()
 
 void V8Proxy::clearForNavigation()
 {
-    disconnectEventListeners();
-
     if (!context().IsEmpty()) {
         v8::HandleScope handle;
         clearDocumentWrapper();
diff --git a/WebCore/bindings/v8/V8Proxy.h b/WebCore/bindings/v8/V8Proxy.h
index 8ca9520..f14a903 100644
--- a/WebCore/bindings/v8/V8Proxy.h
+++ b/WebCore/bindings/v8/V8Proxy.h
@@ -36,7 +36,6 @@
 #include "SecurityOrigin.h" // for WebCore::SecurityOrigin
 #include "SharedPersistent.h"
 #include "V8DOMWrapper.h"
-#include "V8EventListenerList.h"
 #include "V8GCController.h"
 #include "V8Index.h"
 #include <v8.h>
@@ -160,9 +159,6 @@ namespace WebCore {
 
         bool isEnabled();
 
-        V8EventListenerList* eventListeners() { return &m_eventListeners; }
-        V8EventListenerList* objectListeners() { return &m_objectListeners; }
-
 #if ENABLE(SVG)
         static void setSVGContext(void*, SVGElement*);
         static SVGElement* svgContext(void*);
@@ -334,7 +330,6 @@ namespace WebCore {
         static const char* kContextDebugDataType;
         static const char* kContextDebugDataValue;
 
-        void disconnectEventListeners();
         void setSecurityToken();
         void clearDocumentWrapper();
 
@@ -400,14 +395,6 @@ namespace WebCore {
 
         int m_handlerLineNumber;
 
-        // A list of event listeners created for this frame,
-        // the list gets cleared when removing all timeouts.
-        V8EventListenerList m_eventListeners;
-
-        // A list of event listeners create for XMLHttpRequest object for this frame,
-        // the list gets cleared when removing all timeouts.
-        V8EventListenerList m_objectListeners;
-
         // True for <a href="javascript:foo()"> and false for <script>foo()</script>.
         // Only valid during execution.
         bool m_inlineCode;
diff --git a/WebCore/bindings/v8/V8WorkerContextEventListener.cpp b/WebCore/bindings/v8/V8WorkerContextEventListener.cpp
index 2437458..6fa7869 100644
--- a/WebCore/bindings/v8/V8WorkerContextEventListener.cpp
+++ b/WebCore/bindings/v8/V8WorkerContextEventListener.cpp
@@ -46,13 +46,6 @@ V8WorkerContextEventListener::V8WorkerContextEventListener(WorkerContextExecutio
 {
 }
 
-V8WorkerContextEventListener::~V8WorkerContextEventListener()
-{
-    if (m_proxy)
-        m_proxy->removeEventListener(this);
-    disposeListenerObject();
-}
-
 void V8WorkerContextEventListener::handleEvent(ScriptExecutionContext*, Event* event)
 {
     // Is the EventListener disconnected?
@@ -96,6 +89,7 @@ bool V8WorkerContextEventListener::reportError(const String& message, const Stri
     // Enter the V8 context in which to perform the event handling.
     v8::Context::Scope scope(context);
 
+    v8::Local<v8::Object> listener = getListenerObject();
     v8::Local<v8::Value> returnValue;
     {
         // Catch exceptions thrown in calling the function so they do not propagate to javascript code that caused the event to fire.
@@ -103,8 +97,8 @@ bool V8WorkerContextEventListener::reportError(const String& message, const Stri
         tryCatch.SetVerbose(true);
 
         // Call the function.
-        if (!m_listener.IsEmpty() && m_listener->IsFunction()) {
-            v8::Local<v8::Function> callFunction = v8::Local<v8::Function>::New(v8::Persistent<v8::Function>::Cast(m_listener));
+        if (!listener.IsEmpty() && listener->IsFunction()) {
+            v8::Local<v8::Function> callFunction = v8::Local<v8::Function>::Cast(listener);
             v8::Local<v8::Object> thisValue = v8::Context::GetCurrent()->Global();
 
             v8::Handle<v8::Value> parameters[3] = { v8String(message), v8String(url), v8::Integer::New(lineNumber) };
@@ -141,8 +135,10 @@ v8::Local<v8::Value> V8WorkerContextEventListener::callListenerFunction(v8::Hand
 
 v8::Local<v8::Object> V8WorkerContextEventListener::getReceiverObject(Event* event)
 {
-    if (!m_listener.IsEmpty() && !m_listener->IsFunction())
-        return v8::Local<v8::Object>::New(m_listener);
+    v8::Local<v8::Object> listener = getListenerObject();
+
+    if (!listener.IsEmpty() && !listener->IsFunction())
+        return listener;
 
     EventTarget* target = event->currentTarget();
     v8::Handle<v8::Value> value = WorkerContextExecutionProxy::convertEventTargetToV8Object(target);
diff --git a/WebCore/bindings/v8/V8WorkerContextEventListener.h b/WebCore/bindings/v8/V8WorkerContextEventListener.h
index 4609533..d448601 100644
--- a/WebCore/bindings/v8/V8WorkerContextEventListener.h
+++ b/WebCore/bindings/v8/V8WorkerContextEventListener.h
@@ -50,7 +50,6 @@ namespace WebCore {
         }
         V8WorkerContextEventListener(WorkerContextExecutionProxy*, v8::Local<v8::Object> listener, bool isInline);
 
-        virtual ~V8WorkerContextEventListener();
         virtual void handleEvent(ScriptExecutionContext*, Event*);
         virtual bool reportError(const String& message, const String& url, int lineNumber);
         virtual bool disconnected() const { return !m_proxy; }
diff --git a/WebCore/bindings/v8/V8WorkerContextObjectEventListener.cpp b/WebCore/bindings/v8/V8WorkerContextObjectEventListener.cpp
deleted file mode 100644
index ce56563..0000000
--- a/WebCore/bindings/v8/V8WorkerContextObjectEventListener.cpp
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2009 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-
-#if ENABLE(WORKERS)
-
-#include "V8WorkerContextObjectEventListener.h"
-
-#include "WorkerContextExecutionProxy.h"
-
-namespace WebCore {
-
-static void weakObjectEventListenerCallback(v8::Persistent<v8::Value>, void* parameter)
-{
-    V8WorkerContextObjectEventListener* listener = static_cast<V8WorkerContextObjectEventListener*>(parameter);
-
-    // Remove the wrapper
-    listener->proxy()->removeEventListener(listener);
-
-    listener->disposeListenerObject();
-}
-
-V8WorkerContextObjectEventListener::V8WorkerContextObjectEventListener(WorkerContextExecutionProxy* proxy, v8::Local<v8::Object> listener, bool isInline)
-    : V8WorkerContextEventListener(proxy, listener, isInline)
-{
-    m_listener.MakeWeak(this, weakObjectEventListenerCallback);
-}
-
-} // namespace WebCore
-
-#endif // WORKERS
diff --git a/WebCore/bindings/v8/V8WorkerContextObjectEventListener.h b/WebCore/bindings/v8/V8WorkerContextObjectEventListener.h
deleted file mode 100644
index 6471637..0000000
--- a/WebCore/bindings/v8/V8WorkerContextObjectEventListener.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2009 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef V8WorkerContextObjectEventListener_h
-#define V8WorkerContextObjectEventListener_h
-
-#if ENABLE(WORKERS)
-
-#include "V8WorkerContextEventListener.h"
-#include <v8.h>
-#include <wtf/PassRefPtr.h>
-
-namespace WebCore {
-
-    class WorkerContextExecutionProxy;
-
-    class V8WorkerContextObjectEventListener : public V8WorkerContextEventListener {
-    public:
-        static PassRefPtr<V8WorkerContextObjectEventListener> create(WorkerContextExecutionProxy* proxy, v8::Local<v8::Object> listener, bool isInline)
-        {
-            return adoptRef(new V8WorkerContextObjectEventListener(proxy, listener, isInline));
-        }
-
-    private:
-        V8WorkerContextObjectEventListener(WorkerContextExecutionProxy*, v8::Local<v8::Object> listener, bool isInline);
-    };
-
-} // namespace WebCore
-
-#endif // WORKERS
-
-#endif // V8WorkerContextObjectEventListener_h
diff --git a/WebCore/bindings/v8/WorkerContextExecutionProxy.cpp b/WebCore/bindings/v8/WorkerContextExecutionProxy.cpp
index 1411097..68d938e 100644
--- a/WebCore/bindings/v8/WorkerContextExecutionProxy.cpp
+++ b/WebCore/bindings/v8/WorkerContextExecutionProxy.cpp
@@ -48,7 +48,6 @@
 #include "V8Index.h"
 #include "V8Proxy.h"
 #include "V8WorkerContextEventListener.h"
-#include "V8WorkerContextObjectEventListener.h"
 #if ENABLE(WEB_SOCKETS)
 #include "WebSocket.h"
 #endif
@@ -82,14 +81,6 @@ WorkerContextExecutionProxy::~WorkerContextExecutionProxy()
 
 void WorkerContextExecutionProxy::dispose()
 {
-    // Disconnect all event listeners.
-    if (m_listeners.get()) {
-        for (V8EventListenerList::iterator iterator(m_listeners->begin()); iterator != m_listeners->end(); ++iterator)
-           static_cast<V8WorkerContextEventListener*>(*iterator)->disconnect();
-
-        m_listeners->clear();
-    }
-
     // Detach all events from their JS wrappers.
     for (size_t eventIndex = 0; eventIndex < m_events.size(); ++eventIndex) {
         Event* event = m_events[eventIndex];
@@ -169,8 +160,6 @@ void WorkerContextExecutionProxy::initContextIfNeeded()
     // Insert the object instance as the prototype of the shadow object.
     v8::Handle<v8::Object> globalObject = m_context->Global();
     globalObject->Set(implicitProtoString, jsWorkerContext);
-
-    m_listeners.set(new V8EventListenerList());
 }
 
 v8::Handle<v8::Value> WorkerContextExecutionProxy::convertToV8Object(V8ClassIndex::V8WrapperType type, void* impl)
@@ -405,39 +394,9 @@ v8::Local<v8::Value> WorkerContextExecutionProxy::runScript(v8::Handle<v8::Scrip
     return result;
 }
 
-PassRefPtr<V8EventListener> WorkerContextExecutionProxy::findOrCreateEventListenerHelper(v8::Local<v8::Value> object, bool isInline, bool findOnly, bool createObjectEventListener)
-{
-    if (!object->IsObject())
-        return 0;
-
-    V8EventListener* listener = m_listeners->find(object->ToObject(), isInline);
-    if (findOnly)
-        return listener;
-
-    // Create a new one, and add to cache.
-    RefPtr<V8EventListener> newListener;
-    if (createObjectEventListener)
-        newListener = V8WorkerContextObjectEventListener::create(this, v8::Local<v8::Object>::Cast(object), isInline);
-    else
-        newListener = V8WorkerContextEventListener::create(this, v8::Local<v8::Object>::Cast(object), isInline);
-    m_listeners->add(newListener.get());
-
-    return newListener.release();
-}
-
 PassRefPtr<V8EventListener> WorkerContextExecutionProxy::findOrCreateEventListener(v8::Local<v8::Value> object, bool isInline, bool findOnly)
 {
-    return findOrCreateEventListenerHelper(object, isInline, findOnly, false);
-}
-
-PassRefPtr<V8EventListener> WorkerContextExecutionProxy::findOrCreateObjectEventListener(v8::Local<v8::Value> object, bool isInline, bool findOnly)
-{
-    return findOrCreateEventListenerHelper(object, isInline, findOnly, true);
-}
-
-void WorkerContextExecutionProxy::removeEventListener(V8EventListener* listener)
-{
-    m_listeners->remove(listener);
+    return findOnly ? V8EventListenerList::findWrapper(object, isInline) : V8EventListenerList::findOrCreateWrapper<V8WorkerContextEventListener>(this, object, isInline);
 }
 
 void WorkerContextExecutionProxy::trackEvent(Event* event)
diff --git a/WebCore/bindings/v8/WorkerContextExecutionProxy.h b/WebCore/bindings/v8/WorkerContextExecutionProxy.h
index 75024df..11f15d6 100644
--- a/WebCore/bindings/v8/WorkerContextExecutionProxy.h
+++ b/WebCore/bindings/v8/WorkerContextExecutionProxy.h
@@ -64,12 +64,8 @@ namespace WebCore {
         WorkerContextExecutionProxy(WorkerContext*);
         ~WorkerContextExecutionProxy();
 
-        void removeEventListener(V8EventListener*);
-
         // Finds/creates event listener wrappers.
         PassRefPtr<V8EventListener> findOrCreateEventListener(v8::Local<v8::Value> listener, bool isInline, bool findOnly);
-        PassRefPtr<V8EventListener> findOrCreateObjectEventListener(v8::Local<v8::Value> object, bool isInline, bool findOnly);
-        PassRefPtr<V8EventListener> findOrCreateEventListenerHelper(v8::Local<v8::Value> object, bool isInline, bool findOnly, bool createObjectEventListener);
 
         // Track the event so that we can detach it from the JS wrapper when a worker
         // terminates. This is needed because we need to be able to dispose these
@@ -115,7 +111,6 @@ namespace WebCore {
         v8::Persistent<v8::Context> m_context;
         int m_recursion;
 
-        OwnPtr<V8EventListenerList> m_listeners;
         Vector<Event*> m_events;
     };
 
diff --git a/WebCore/bindings/v8/custom/V8AbstractWorkerCustom.cpp b/WebCore/bindings/v8/custom/V8AbstractWorkerCustom.cpp
index ce759eb..0240895 100644
--- a/WebCore/bindings/v8/custom/V8AbstractWorkerCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8AbstractWorkerCustom.cpp
@@ -38,75 +38,18 @@
 #include "ScriptExecutionContext.h"
 #include "V8Binding.h"
 #include "V8CustomBinding.h"
-#include "V8ObjectEventListener.h"
 #include "V8Proxy.h"
 #include "V8Utilities.h"
 #include "WorkerContextExecutionProxy.h"
 
 namespace WebCore {
 
-PassRefPtr<EventListener> getEventListener(AbstractWorker* worker, v8::Local<v8::Value> value, bool isAttribute, bool findOnly)
-{
-    if (worker->scriptExecutionContext()->isWorkerContext()) {
-        WorkerContextExecutionProxy* workerContextProxy = WorkerContextExecutionProxy::retrieve();
-        ASSERT(workerContextProxy);
-        return workerContextProxy->findOrCreateObjectEventListener(value, isAttribute, findOnly);
-    }
-
-    V8Proxy* proxy = V8Proxy::retrieve(worker->scriptExecutionContext());
-    if (proxy) {
-        V8EventListenerList* list = proxy->objectListeners();
-        return findOnly ? list->findWrapper(value, isAttribute) : list->findOrCreateWrapper<V8ObjectEventListener>(proxy->frame(), value, isAttribute);
-    }
-
-    return 0;
-}
-
-ACCESSOR_GETTER(AbstractWorkerOnerror)
-{
-    INC_STATS(L"DOM.AbstractWorker.onerror._get");
-    AbstractWorker* worker = V8DOMWrapper::convertToNativeObject<AbstractWorker>(V8ClassIndex::ABSTRACTWORKER, info.Holder());
-    if (worker->onerror()) {
-        V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(worker->onerror());
-        v8::Local<v8::Object> v8Listener = listener->getListenerObject();
-        return v8Listener;
-    }
-    return v8::Undefined();
-}
-
-ACCESSOR_SETTER(AbstractWorkerOnerror)
-{
-    INC_STATS(L"DOM.AbstractWorker.onerror._set");
-    AbstractWorker* worker = V8DOMWrapper::convertToNativeObject<AbstractWorker>(V8ClassIndex::ABSTRACTWORKER, info.Holder());
-    V8ObjectEventListener* oldListener = static_cast<V8ObjectEventListener*>(worker->onerror());
-    if (value->IsNull()) {
-        if (oldListener) {
-            v8::Local<v8::Object> oldV8Listener = oldListener->getListenerObject();
-            removeHiddenDependency(info.Holder(), oldV8Listener, V8Custom::kAbstractWorkerRequestCacheIndex);
-        }
-
-        // Clear the listener.
-        worker->setOnerror(0);
-    } else {
-        RefPtr<EventListener> listener = getEventListener(worker, value, true, false);
-        if (listener) {
-            if (oldListener) {
-                v8::Local<v8::Object> oldV8Listener = oldListener->getListenerObject();
-                removeHiddenDependency(info.Holder(), oldV8Listener, V8Custom::kAbstractWorkerRequestCacheIndex);
-            }
-
-            worker->setOnerror(listener);
-            createHiddenDependency(info.Holder(), value, V8Custom::kAbstractWorkerRequestCacheIndex);
-        }
-    }
-}
-
 CALLBACK_FUNC_DECL(AbstractWorkerAddEventListener)
 {
     INC_STATS(L"DOM.AbstractWorker.addEventListener()");
     AbstractWorker* worker = V8DOMWrapper::convertToNativeObject<AbstractWorker>(V8ClassIndex::ABSTRACTWORKER, args.Holder());
 
-    RefPtr<EventListener> listener = getEventListener(worker, args[1], false, false);
+    RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(worker, args[1], false, ListenerFindOrCreate);
     if (listener) {
         String type = toWebCoreString(args[0]);
         bool useCapture = args[2]->BooleanValue();
@@ -122,7 +65,7 @@ CALLBACK_FUNC_DECL(AbstractWorkerRemoveEventListener)
     INC_STATS(L"DOM.AbstractWorker.removeEventListener()");
     AbstractWorker* worker = V8DOMWrapper::convertToNativeObject<AbstractWorker>(V8ClassIndex::ABSTRACTWORKER, args.Holder());
 
-    RefPtr<EventListener> listener = getEventListener(worker, args[1], false, true);
+    RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(worker, args[1], false, ListenerFindOnly);
     if (listener) {
         String type = toWebCoreString(args[0]);
         bool useCapture = args[2]->BooleanValue();
diff --git a/WebCore/bindings/v8/custom/V8CustomBinding.h b/WebCore/bindings/v8/custom/V8CustomBinding.h
index aab56f0..c91f23f 100644
--- a/WebCore/bindings/v8/custom/V8CustomBinding.h
+++ b/WebCore/bindings/v8/custom/V8CustomBinding.h
@@ -140,6 +140,11 @@ namespace WebCore {
         static const int kNotificationInternalFieldCount = kDefaultWrapperInternalFieldCount + 1;
 #endif
 
+#if ENABLE(SVG)
+        static const int kSVGElementInstanceEventListenerCacheIndex = kDefaultWrapperInternalFieldCount + 0;
+        static const int kSVGElementInstanceInternalFieldCount = kDefaultWrapperInternalFieldCount + 1;
+#endif
+
         static const int kDOMWindowConsoleIndex = kDefaultWrapperInternalFieldCount + 0;
         static const int kDOMWindowHistoryIndex = kDefaultWrapperInternalFieldCount + 1;
         static const int kDOMWindowLocationbarIndex = kDefaultWrapperInternalFieldCount + 2;
@@ -153,7 +158,8 @@ namespace WebCore {
         static const int kDOMWindowToolbarIndex = kDefaultWrapperInternalFieldCount + 10;
         static const int kDOMWindowLocationIndex = kDefaultWrapperInternalFieldCount + 11;
         static const int kDOMWindowDOMSelectionIndex = kDefaultWrapperInternalFieldCount + 12;
-        static const int kDOMWindowInternalFieldCount = kDefaultWrapperInternalFieldCount + 13;
+        static const int kDOMWindowEventListenerCacheIndex = kDefaultWrapperInternalFieldCount + 13;
+        static const int kDOMWindowInternalFieldCount = kDefaultWrapperInternalFieldCount + 14;
 
         static const int kStyleSheetOwnerNodeIndex = kDefaultWrapperInternalFieldCount + 0;
         static const int kStyleSheetInternalFieldCount = kDefaultWrapperInternalFieldCount + 1;
diff --git a/WebCore/bindings/v8/custom/V8CustomEventListener.cpp b/WebCore/bindings/v8/custom/V8CustomEventListener.cpp
index b11c496..6a4ede2 100644
--- a/WebCore/bindings/v8/custom/V8CustomEventListener.cpp
+++ b/WebCore/bindings/v8/custom/V8CustomEventListener.cpp
@@ -38,34 +38,22 @@ namespace WebCore {
 V8EventListener::V8EventListener(Frame* frame, v8::Local<v8::Object> listener, bool isAttribute)
     : V8AbstractEventListener(frame, isAttribute)
 {
-    m_listener = v8::Persistent<v8::Object>::New(listener);
-#ifndef NDEBUG
-    V8GCController::registerGlobalHandle(EVENT_LISTENER, this, m_listener);
-#endif
-}
-
-V8EventListener::~V8EventListener()
-{
-    if (m_frame) {
-        V8Proxy* proxy = V8Proxy::retrieve(m_frame);
-        if (proxy)
-            proxy->eventListeners()->remove(this);
-    }
-
-    disposeListenerObject();
+    setListenerObject(listener);
 }
 
 v8::Local<v8::Function> V8EventListener::getListenerFunction()
 {
+    v8::Local<v8::Object> listener = getListenerObject();
+
     // Has the listener been disposed?
-    if (m_listener.IsEmpty())
+    if (listener.IsEmpty())
         return v8::Local<v8::Function>();
 
-    if (m_listener->IsFunction())
-        return v8::Local<v8::Function>::New(v8::Persistent<v8::Function>::Cast(m_listener));
+    if (listener->IsFunction())
+        return v8::Local<v8::Function>::Cast(listener);
 
-    if (m_listener->IsObject()) {
-        v8::Local<v8::Value> property = m_listener->Get(v8::String::NewSymbol("handleEvent"));
+    if (listener->IsObject()) {
+        v8::Local<v8::Value> property = listener->Get(v8::String::NewSymbol("handleEvent"));
         if (property->IsFunction())
             return v8::Local<v8::Function>::Cast(property);
     }
@@ -82,7 +70,7 @@ v8::Local<v8::Value> V8EventListener::callListenerFunction(v8::Handle<v8::Value>
 
     v8::Handle<v8::Value> parameters[1] = { jsEvent };
 
-    V8Proxy* proxy = V8Proxy::retrieve(m_frame);
+    V8Proxy* proxy = V8Proxy::retrieve(frame());
     if (!proxy)
         return v8::Local<v8::Value>();
     return proxy->callFunction(handlerFunction, receiver, 1, parameters);
diff --git a/WebCore/bindings/v8/custom/V8CustomEventListener.h b/WebCore/bindings/v8/custom/V8CustomEventListener.h
index 93ad8fb..3f9790c 100644
--- a/WebCore/bindings/v8/custom/V8CustomEventListener.h
+++ b/WebCore/bindings/v8/custom/V8CustomEventListener.h
@@ -49,18 +49,14 @@ namespace WebCore {
             return adoptRef(new V8EventListener(frame, listener, isAttribute));
         }
 
-        // Detach the listener from its owner frame.
-        void disconnectFrame() { m_frame = 0; }
-
     protected:
         V8EventListener(Frame*, v8::Local<v8::Object> listener, bool isAttribute);
-        virtual ~V8EventListener();
+
         v8::Local<v8::Function> getListenerFunction();
 
     private:
         virtual v8::Local<v8::Value> callListenerFunction(v8::Handle<v8::Value> jsEvent, Event*);
-        virtual bool virtualisAttribute() const { return m_isAttribute; }
-    };
+     };
 
 } // namespace WebCore
 
diff --git a/WebCore/bindings/v8/custom/V8DOMApplicationCacheCustom.cpp b/WebCore/bindings/v8/custom/V8DOMApplicationCacheCustom.cpp
index 63fc698..134de95 100644
--- a/WebCore/bindings/v8/custom/V8DOMApplicationCacheCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8DOMApplicationCacheCustom.cpp
@@ -37,76 +37,19 @@
 #include "V8Binding.h"
 #include "V8CustomBinding.h"
 #include "V8Document.h"
-#include "V8ObjectEventListener.h"
 #include "V8Proxy.h"
 #include "V8Utilities.h"
 #include "WorkerContextExecutionProxy.h"
 
 namespace WebCore {
 
-static const bool kFindOnly = true;
-static const bool kFindOrCreate = false;
-
-static PassRefPtr<EventListener> argumentToEventListener(DOMApplicationCache* appcache, v8::Local<v8::Value> value, bool findOnly)
-{
-    V8Proxy* proxy = V8Proxy::retrieve(appcache->scriptExecutionContext());
-    if (proxy)
-        return findOnly ? proxy->objectListeners()->findWrapper(value, false)
-                        : proxy->objectListeners()->findOrCreateWrapper<V8ObjectEventListener>(proxy->frame(), value, false);
-    return 0;
-}
-
-static v8::Local<v8::Object> eventListenerToV8Object(EventListener* listener)
-{
-    return (static_cast<V8ObjectEventListener*>(listener))->getListenerObject();
-}
-
-static inline String toEventID(v8::Local<v8::String> value)
-{
-    String key = toWebCoreString(value);
-    ASSERT(key.startsWith("on"));
-    return key.substring(2);
-}
-
-// Handles appcache.onfooevent attribute getting
-ACCESSOR_GETTER(DOMApplicationCacheEventHandler)
-{
-    INC_STATS("DOMApplicationCache.onevent_getter");
-    DOMApplicationCache* appcache = V8DOMWrapper::convertToNativeObject<DOMApplicationCache>(V8ClassIndex::DOMAPPLICATIONCACHE, info.Holder());
-    if (EventListener* listener = appcache->getAttributeEventListener(toEventID(name)))
-        return eventListenerToV8Object(listener);
-    return v8::Null();
-}
-
-// Handles appcache.onfooevent attribute setting
-ACCESSOR_SETTER(DOMApplicationCacheEventHandler)
-{
-    INC_STATS("DOMApplicationCache.onevent_setter");
-    DOMApplicationCache* appcache = V8DOMWrapper::convertToNativeObject<DOMApplicationCache>(V8ClassIndex::DOMAPPLICATIONCACHE, info.Holder());
-    String eventType = toEventID(name);
-
-    if (EventListener* oldListener = appcache->getAttributeEventListener(eventType)) {
-        v8::Local<v8::Object> object = eventListenerToV8Object(oldListener);
-        removeHiddenDependency(info.Holder(), object, V8Custom::kDOMApplicationCacheCacheIndex);
-        appcache->clearAttributeEventListener(eventType);
-    }
-
-    if (value->IsFunction()) {
-        RefPtr<EventListener> newListener = argumentToEventListener(appcache, value, kFindOrCreate);
-        if (newListener) {
-            createHiddenDependency(info.Holder(), value, V8Custom::kDOMApplicationCacheCacheIndex);
-            appcache->setAttributeEventListener(eventType, newListener);
-        }
-    }
-}
-
 // Handles appcache.addEventListner(name, func, capture) method calls
 CALLBACK_FUNC_DECL(DOMApplicationCacheAddEventListener)
 {
     INC_STATS("DOMApplicationCache.addEventListener()");
     DOMApplicationCache* appcache = V8DOMWrapper::convertToNativeObject<DOMApplicationCache>(V8ClassIndex::DOMAPPLICATIONCACHE, args.Holder());
 
-    RefPtr<EventListener> listener = argumentToEventListener(appcache, args[1], kFindOrCreate);
+    RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(appcache, args[1], false, ListenerFindOrCreate);
     if (listener) {
         createHiddenDependency(args.Holder(), args[1], V8Custom::kDOMApplicationCacheCacheIndex);
         String eventType = toWebCoreString(args[0]);
@@ -122,7 +65,7 @@ CALLBACK_FUNC_DECL(DOMApplicationCacheRemoveEventListener)
     INC_STATS("DOMApplicationCache.removeEventListener()");
     DOMApplicationCache* appcache = V8DOMWrapper::convertToNativeObject<DOMApplicationCache>(V8ClassIndex::DOMAPPLICATIONCACHE, args.Holder());
 
-    RefPtr<EventListener> listener = argumentToEventListener(appcache, args[1], kFindOnly);
+    RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(appcache, args[1], false, ListenerFindOnly);
     if (listener) {
         removeHiddenDependency(args.Holder(), args[1], V8Custom::kDOMApplicationCacheCacheIndex);
         String eventType = toWebCoreString(args[0]);
diff --git a/WebCore/bindings/v8/custom/V8DOMWindowCustom.cpp b/WebCore/bindings/v8/custom/V8DOMWindowCustom.cpp
index da5d1bf..424d681 100644
--- a/WebCore/bindings/v8/custom/V8DOMWindowCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8DOMWindowCustom.cpp
@@ -274,10 +274,12 @@ CALLBACK_FUNC_DECL(DOMWindowAddEventListener)
     if (!proxy)
         return v8::Undefined();
 
-    RefPtr<EventListener> listener = proxy->eventListeners()->findOrCreateWrapper<V8EventListener>(proxy->frame(), args[1], false);
+    RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(proxy, args[1], false, ListenerFindOrCreate);
 
-    if (listener)
+    if (listener) {
         imp->addEventListener(eventType, listener, useCapture);
+        createHiddenDependency(args.Holder(), args[1], V8Custom::kDOMWindowEventListenerCacheIndex);
+    }
 
     return v8::Undefined();
 }
@@ -304,10 +306,12 @@ CALLBACK_FUNC_DECL(DOMWindowRemoveEventListener)
     if (!proxy)
         return v8::Undefined();
 
-    RefPtr<EventListener> listener = proxy->eventListeners()->findWrapper(args[1], false);
+    RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(proxy, args[1], false, ListenerFindOnly);
 
-    if (listener)
+    if (listener) {
         imp->removeEventListener(eventType, listener.get(), useCapture);
+        removeHiddenDependency(args.Holder(), args[1], V8Custom::kDOMWindowEventListenerCacheIndex);
+    }
 
     return v8::Undefined();
 }
@@ -402,82 +406,6 @@ CALLBACK_FUNC_DECL(DOMWindowNOP)
     return v8::Undefined();
 }
 
-static String eventNameFromAttributeName(const String& name)
-{
-    ASSERT(name.startsWith("on"));
-    String eventType = name.substring(2);
-
-    if (eventType.startsWith("w")) {
-        switch(eventType[eventType.length() - 1]) {
-        case 't':
-            eventType = "webkitAnimationStart";
-            break;
-        case 'n':
-            eventType = "webkitAnimationIteration";
-            break;
-        case 'd':
-            ASSERT(eventType.length() > 7);
-            if (eventType[7] == 'a')
-                eventType = "webkitAnimationEnd";
-            else
-                eventType = "webkitTransitionEnd";
-            break;
-        }
-    }
-
-    return eventType;
-}
-
-ACCESSOR_SETTER(DOMWindowEventHandler)
-{
-    v8::Handle<v8::Object> holder = V8DOMWrapper::lookupDOMWrapper(V8ClassIndex::DOMWINDOW, info.This());
-    if (holder.IsEmpty())
-        return;
-
-    DOMWindow* imp = V8DOMWrapper::convertToNativeObject<DOMWindow>(V8ClassIndex::DOMWINDOW, holder);
-
-    Document* doc = imp->document();
-
-    if (!doc)
-        return;
-
-    String key = toWebCoreString(name);
-    String eventType = eventNameFromAttributeName(key);
-
-    if (value->IsNull()) {
-        // Clear the event listener
-        imp->clearAttributeEventListener(eventType);
-    } else {
-        V8Proxy* proxy = V8Proxy::retrieve(imp->frame());
-        if (!proxy)
-            return;
-
-        RefPtr<EventListener> listener = proxy->eventListeners()->findOrCreateWrapper<V8EventListener>(proxy->frame(), value, true);
-        if (listener)
-            imp->setAttributeEventListener(eventType, listener);
-    }
-}
-
-ACCESSOR_GETTER(DOMWindowEventHandler)
-{
-    v8::Handle<v8::Object> holder = V8DOMWrapper::lookupDOMWrapper(V8ClassIndex::DOMWINDOW, info.This());
-    if (holder.IsEmpty())
-        return v8::Undefined();
-
-    DOMWindow* imp = V8DOMWrapper::convertToNativeObject<DOMWindow>(V8ClassIndex::DOMWINDOW, holder);
-
-    Document* doc = imp->document();
-
-    if (!doc)
-        return v8::Undefined();
-
-    String key = toWebCoreString(name);
-    String eventType = eventNameFromAttributeName(key);
-
-    EventListener* listener = imp->getAttributeEventListener(eventType);
-    return V8DOMWrapper::convertEventListenerToV8Object(listener);
-}
-
 static bool canShowModalDialogNow(const Frame* frame)
 {
     // A frame can out live its page. See bug 1219613.
diff --git a/WebCore/bindings/v8/custom/V8DedicatedWorkerContextCustom.cpp b/WebCore/bindings/v8/custom/V8DedicatedWorkerContextCustom.cpp
index 77e2fa4..56794ab 100644
--- a/WebCore/bindings/v8/custom/V8DedicatedWorkerContextCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8DedicatedWorkerContextCustom.cpp
@@ -42,45 +42,6 @@
 
 namespace WebCore {
 
-ACCESSOR_GETTER(DedicatedWorkerContextOnmessage)
-{
-    INC_STATS(L"DOM.DedicatedWorkerContext.onmessage._get");
-    DedicatedWorkerContext* workerContext = V8DOMWrapper::convertToNativeObject<DedicatedWorkerContext>(V8ClassIndex::DEDICATEDWORKERCONTEXT, info.Holder());
-    if (workerContext->onmessage()) {
-        V8WorkerContextEventListener* listener = static_cast<V8WorkerContextEventListener*>(workerContext->onmessage());
-        v8::Local<v8::Object> v8Listener = listener->getListenerObject();
-        return v8Listener;
-    }
-    return v8::Undefined();
-}
-
-ACCESSOR_SETTER(DedicatedWorkerContextOnmessage)
-{
-    INC_STATS(L"DOM.DedicatedWorkerContext.onmessage._set");
-    DedicatedWorkerContext* workerContext = V8DOMWrapper::convertToNativeObject<DedicatedWorkerContext>(V8ClassIndex::DEDICATEDWORKERCONTEXT, info.Holder());
-    V8WorkerContextEventListener* oldListener = static_cast<V8WorkerContextEventListener*>(workerContext->onmessage());
-    if (value->IsNull()) {
-        if (workerContext->onmessage()) {
-            v8::Local<v8::Object> oldV8Listener = oldListener->getListenerObject();
-            removeHiddenDependency(info.Holder(), oldV8Listener, V8Custom::kDedicatedWorkerContextRequestCacheIndex);
-        }
-
-        // Clear the listener.
-        workerContext->setOnmessage(0);
-    } else {
-        RefPtr<V8EventListener> listener = workerContext->script()->proxy()->findOrCreateEventListener(v8::Local<v8::Object>::Cast(value), false, false);
-        if (listener) {
-            if (oldListener) {
-                v8::Local<v8::Object> oldV8Listener = oldListener->getListenerObject();
-                removeHiddenDependency(info.Holder(), oldV8Listener, V8Custom::kDedicatedWorkerContextRequestCacheIndex);
-            }
-
-            workerContext->setOnmessage(listener);
-            createHiddenDependency(info.Holder(), value, V8Custom::kDedicatedWorkerContextRequestCacheIndex);
-        }
-    }
-}
-
 CALLBACK_FUNC_DECL(DedicatedWorkerContextPostMessage)
 {
     INC_STATS(L"DOM.DedicatedWorkerContext.postMessage");
diff --git a/WebCore/bindings/v8/custom/V8MessagePortCustom.cpp b/WebCore/bindings/v8/custom/V8MessagePortCustom.cpp
index 0616cc8..200e4d5 100644
--- a/WebCore/bindings/v8/custom/V8MessagePortCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8MessagePortCustom.cpp
@@ -36,64 +36,17 @@
 #include "V8CustomBinding.h"
 #include "V8MessagePortCustom.h"
 #include "V8MessagePort.h"
-#include "V8ObjectEventListener.h"
 #include "V8Proxy.h"
 #include "V8Utilities.h"
 #include "WorkerContextExecutionProxy.h"
 
 namespace WebCore {
 
-PassRefPtr<EventListener> getEventListener(MessagePort* messagePort, v8::Local<v8::Value> value, bool findOnly, bool createObjectEventListener)
-{
-    V8Proxy* proxy = V8Proxy::retrieve(messagePort->scriptExecutionContext());
-    if (proxy) {
-        V8EventListenerList* list = proxy->objectListeners();
-        return findOnly ? list->findWrapper(value, false) : list->findOrCreateWrapper<V8ObjectEventListener>(proxy->frame(), value, false);
-    }
-
-#if ENABLE(WORKERS)
-    WorkerContextExecutionProxy* workerContextProxy = WorkerContextExecutionProxy::retrieve();
-    if (workerContextProxy)
-        return workerContextProxy->findOrCreateEventListenerHelper(value, false, findOnly, createObjectEventListener);
-#endif
-
-    return PassRefPtr<EventListener>();
-}
-
-ACCESSOR_GETTER(MessagePortOnmessage)
-{
-    INC_STATS("DOM.MessagePort.onmessage._get");
-    MessagePort* messagePort = V8DOMWrapper::convertToNativeObject<MessagePort>(V8ClassIndex::MESSAGEPORT, info.Holder());
-    return V8DOMWrapper::convertEventListenerToV8Object(messagePort->onmessage());
-}
-
-ACCESSOR_SETTER(MessagePortOnmessage)
-{
-    INC_STATS("DOM.MessagePort.onmessage._set");
-    MessagePort* messagePort = V8DOMWrapper::convertToNativeObject<MessagePort>(V8ClassIndex::MESSAGEPORT, info.Holder());
-    if (value->IsNull()) {
-        if (messagePort->onmessage()) {
-            V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(messagePort->onmessage());
-            removeHiddenDependency(info.Holder(), listener->getListenerObject(), V8Custom::kMessagePortRequestCacheIndex);
-        }
-
-        // Clear the listener.
-        messagePort->setOnmessage(0);
-
-    } else {
-        RefPtr<EventListener> listener = getEventListener(messagePort, value, false, false);
-        if (listener) {
-            messagePort->setOnmessage(listener);
-            createHiddenDependency(info.Holder(), value, V8Custom::kMessagePortRequestCacheIndex);
-        }
-    }
-}
-
 CALLBACK_FUNC_DECL(MessagePortAddEventListener)
 {
     INC_STATS("DOM.MessagePort.addEventListener()");
     MessagePort* messagePort = V8DOMWrapper::convertToNativeObject<MessagePort>(V8ClassIndex::MESSAGEPORT, args.Holder());
-    RefPtr<EventListener> listener = getEventListener(messagePort, args[1], false, true);
+    RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(messagePort, args[1], false, ListenerFindOrCreate);
     if (listener) {
         String type = toWebCoreString(args[0]);
         bool useCapture = args[2]->BooleanValue();
@@ -108,7 +61,7 @@ CALLBACK_FUNC_DECL(MessagePortRemoveEventListener)
 {
     INC_STATS("DOM.MessagePort.removeEventListener()");
     MessagePort* messagePort = V8DOMWrapper::convertToNativeObject<MessagePort>(V8ClassIndex::MESSAGEPORT, args.Holder());
-    RefPtr<EventListener> listener = getEventListener(messagePort, args[1], true, true);
+    RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(messagePort, args[1], false, ListenerFindOnly);
     if (listener) {
         String type = toWebCoreString(args[0]);
         bool useCapture = args[2]->BooleanValue();
diff --git a/WebCore/bindings/v8/custom/V8NodeCustom.cpp b/WebCore/bindings/v8/custom/V8NodeCustom.cpp
index 61ab867..9b4b9aa 100644
--- a/WebCore/bindings/v8/custom/V8NodeCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8NodeCustom.cpp
@@ -39,26 +39,18 @@
 #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);
-}
-
 CALLBACK_FUNC_DECL(NodeAddEventListener)
 {
     INC_STATS("DOM.Node.addEventListener()");
     Node* node = V8DOMWrapper::convertDOMWrapperToNode<Node>(args.Holder());
 
-    RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(node, args[1], false, false);
+    RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(node, args[1], false, ListenerFindOrCreate);
     if (listener) {
         String type = toWebCoreString(args[0]);
         bool useCapture = args[2]->BooleanValue();
@@ -76,9 +68,9 @@ CALLBACK_FUNC_DECL(NodeRemoveEventListener)
     // It is possbile that the owner document of the node is detached
     // from the frame.
     // See issue http://b/878909
-    RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(node, args[1], false, true);
+    RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(node, args[1], false, ListenerFindOnly);
     if (listener) {
-        String type = toWebCoreString(args[0]);
+        AtomicString type = v8ValueToAtomicWebCoreString(args[0]);
         bool useCapture = args[2]->BooleanValue();
         node->removeEventListener(type, listener.get(), useCapture);
         removeHiddenDependency(args.Holder(), args[1], V8Custom::kNodeEventListenerCacheIndex);
diff --git a/WebCore/bindings/v8/custom/V8NotificationCenterCustom.cpp b/WebCore/bindings/v8/custom/V8NotificationCenterCustom.cpp
index e1df06d..bd5fb4a 100644
--- a/WebCore/bindings/v8/custom/V8NotificationCenterCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8NotificationCenterCustom.cpp
@@ -51,21 +51,12 @@ CALLBACK_FUNC_DECL(NotificationAddEventListener)
     INC_STATS("DOM.Notification.addEventListener()");
     Notification* notification = V8DOMWrapper::convertToNativeObject<Notification>(V8ClassIndex::NOTIFICATION, args.Holder());
 
-    RefPtr<EventListener> listener;
-    ScriptExecutionContext* context = notification->scriptExecutionContext();
-    if (context->isWorkerContext())
-        listener = static_cast<WorkerContext*>(context)->script()->proxy()->findOrCreateEventListener(v8::Local<v8::Object>::Cast(args[1]), false, false);
-    else {
-        V8Proxy* proxy = V8Proxy::retrieve(context);
-        if (!proxy)
-            return v8::Undefined();
-        listener = proxy->eventListeners()->findOrCreateWrapper<V8EventListener>(proxy->frame(), args[1], true);
-    }
-
+    RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(notification, args[1], false, ListenerFindOrCreate);
     if (listener) {
         String type = toWebCoreString(args[0]);
         bool useCapture = args[2]->BooleanValue();
         notification->addEventListener(type, listener, useCapture);
+        createHiddenDependency(args.Holder(), args[1], V8Custom::kNotificationRequestCacheIndex);
     }
 
     return v8::Undefined();
@@ -76,77 +67,17 @@ CALLBACK_FUNC_DECL(NotificationRemoveEventListener)
     INC_STATS("DOM.Notification.removeEventListener()");
     Notification* notification = V8DOMWrapper::convertToNativeObject<Notification>(V8ClassIndex::NOTIFICATION, args.Holder());
 
-    RefPtr<EventListener> listener;
-    ScriptExecutionContext* context = notification->scriptExecutionContext();
-    if (context->isWorkerContext())
-        listener = static_cast<WorkerContext*>(context)->script()->proxy()->findOrCreateEventListener(v8::Local<v8::Object>::Cast(args[1]), false, true);
-    else {
-        V8Proxy* proxy = V8Proxy::retrieve(context);
-        if (!proxy)
-            return v8::Undefined();
-        RefPtr<EventListener> listener = proxy->eventListeners()->findWrapper(args[1], false);
-    }
-
+    RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(notification, args[1], false, ListenerFindOnly);
     if (listener) {
         String type = toWebCoreString(args[0]);
         bool useCapture = args[2]->BooleanValue();
         notification->removeEventListener(type, listener.get(), useCapture);
+        removeHiddenDependency(args.Holder(), args[1], V8Custom::kNotificationRequestCacheIndex);
     }
 
     return v8::Undefined();
 }
 
-ACCESSOR_SETTER(NotificationEventHandler)
-{
-    v8::Handle<v8::Object> holder = V8DOMWrapper::lookupDOMWrapper(V8ClassIndex::NOTIFICATION, info.This());
-    if (holder.IsEmpty())
-        return;
-
-    Notification* notification = V8DOMWrapper::convertToNativeObject<Notification>(V8ClassIndex::NOTIFICATION, holder);
-    ScriptExecutionContext* context = notification->scriptExecutionContext();
-
-    if (!context)
-        return;
-
-    String key = toWebCoreString(name);
-    ASSERT(key.startsWith("on"));
-    String eventType = key.substring(2);
-
-    if (value->IsNull()) {
-        // Clear the event listener
-        notification->clearAttributeEventListener(eventType);
-    } else {
-        RefPtr<EventListener> listener;
-        if (context->isWorkerContext())
-            listener = static_cast<WorkerContext*>(context)->script()->proxy()->findOrCreateEventListener(v8::Local<v8::Object>::Cast(value), false, false);
-        else {
-            V8Proxy* proxy = V8Proxy::retrieve(context);
-            if (!proxy)
-                return;
-            listener = proxy->eventListeners()->findOrCreateWrapper<V8EventListener>(proxy->frame(), value, true);
-        }
-
-        if (listener)
-            notification->setAttributeEventListener(eventType, listener);
-    }
-}
-
-ACCESSOR_GETTER(NotificationEventHandler)
-{
-    v8::Handle<v8::Object> holder = V8DOMWrapper::lookupDOMWrapper(V8ClassIndex::DOMWINDOW, info.This());
-    if (holder.IsEmpty())
-        return v8::Undefined();
-
-    Notification* notification = V8DOMWrapper::convertToNativeObject<Notification>(V8ClassIndex::NOTIFICATION, holder);
-
-    String key = toWebCoreString(name);
-    ASSERT(key.startsWith("on"));
-    String eventType = key.substring(2);
-
-    EventListener* listener = notification->getAttributeEventListener(eventType);
-    return V8DOMWrapper::convertEventListenerToV8Object(listener);
-}
-
 CALLBACK_FUNC_DECL(NotificationCenterCreateHTMLNotification)
 {
     INC_STATS(L"DOM.NotificationCenter.CreateHTMLNotification()");
diff --git a/WebCore/bindings/v8/custom/V8SVGElementInstanceCustom.cpp b/WebCore/bindings/v8/custom/V8SVGElementInstanceCustom.cpp
index ce9c345..dff4ff4 100644
--- a/WebCore/bindings/v8/custom/V8SVGElementInstanceCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8SVGElementInstanceCustom.cpp
@@ -49,15 +49,12 @@ CALLBACK_FUNC_DECL(SVGElementInstanceAddEventListener)
     INC_STATS("DOM.SVGElementInstance.AddEventListener()");
     SVGElementInstance* instance = V8DOMWrapper::convertDOMWrapperToNative<SVGElementInstance>(args.Holder());
 
-    V8Proxy* proxy = V8Proxy::retrieve(instance->scriptExecutionContext());
-    if (!proxy)
-        return v8::Undefined();
-
-    RefPtr<EventListener> listener = proxy->eventListeners()->findOrCreateWrapper<V8EventListener>(proxy->frame(), args[1], false);
+    RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(instance, args[1], false, ListenerFindOrCreate);
     if (listener) {
         String type = toWebCoreString(args[0]);
         bool useCapture = args[2]->BooleanValue();
         instance->addEventListener(type, listener, useCapture);
+        createHiddenDependency(args.Holder(), args[1], V8Custom::kNodeEventListenerCacheIndex);
     }
 
     return v8::Undefined();
@@ -68,15 +65,12 @@ CALLBACK_FUNC_DECL(SVGElementInstanceRemoveEventListener)
     INC_STATS("DOM.SVGElementInstance.RemoveEventListener()");
     SVGElementInstance* instance = V8DOMWrapper::convertDOMWrapperToNative<SVGElementInstance>(args.Holder());
 
-    V8Proxy* proxy = V8Proxy::retrieve(instance->scriptExecutionContext());
-    if (!proxy)
-        return v8::Undefined();
-
-    RefPtr<EventListener> listener = proxy->eventListeners()->findWrapper(args[1], false);
+    RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(instance, args[1], false, ListenerFindOnly);
     if (listener) {
         String type = toWebCoreString(args[0]);
         bool useCapture = args[2]->BooleanValue();
         instance->removeEventListener(type, listener.get(), useCapture);
+        removeHiddenDependency(args.Holder(), args[1], V8Custom::kNodeEventListenerCacheIndex);
     }
 
     return v8::Undefined();
diff --git a/WebCore/bindings/v8/custom/V8WebSocketCustom.cpp b/WebCore/bindings/v8/custom/V8WebSocketCustom.cpp
index 024419d..a8fdf84 100644
--- a/WebCore/bindings/v8/custom/V8WebSocketCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8WebSocketCustom.cpp
@@ -45,122 +45,6 @@
 
 namespace WebCore {
 
-static PassRefPtr<EventListener> getEventListener(WebSocket* webSocket, v8::Local<v8::Value> value, bool findOnly)
-{
-#if ENABLE(WORKERS)
-    WorkerContextExecutionProxy* workerContextProxy = WorkerContextExecutionProxy::retrieve();
-    if (workerContextProxy)
-        return workerContextProxy->findOrCreateObjectEventListener(value, false, findOnly);
-#endif
-
-    V8Proxy* proxy = V8Proxy::retrieve(webSocket->scriptExecutionContext());
-    if (proxy) {
-        V8EventListenerList* list = proxy->objectListeners();
-        return findOnly ? list->findWrapper(value, false) : list->findOrCreateWrapper<V8ObjectEventListener>(proxy->frame(), value, false);
-    }
-
-    return PassRefPtr<EventListener>();
-}
-
-ACCESSOR_GETTER(WebSocketOnopen)
-{
-    INC_STATS("DOM.WebSocket.onopen._get");
-    WebSocket* webSocket = V8DOMWrapper::convertToNativeObject<WebSocket>(V8ClassIndex::WEBSOCKET, info.Holder());
-    if (webSocket->onopen()) {
-        V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(webSocket->onopen());
-        v8::Local<v8::Object> v8Listener = listener->getListenerObject();
-        return v8Listener;
-    }
-    return v8::Null();
-}
-
-ACCESSOR_SETTER(WebSocketOnopen)
-{
-    INC_STATS("DOM.WebSocket.onopen._set");
-    WebSocket* webSocket = V8DOMWrapper::convertToNativeObject<WebSocket>(V8ClassIndex::WEBSOCKET, info.Holder());
-    if (value->IsNull()) {
-        if (webSocket->onopen()) {
-            V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(webSocket->onopen());
-            v8::Local<v8::Object> v8Listener = listener->getListenerObject();
-            removeHiddenDependency(info.Holder(), v8Listener, V8Custom::kWebSocketCacheIndex);
-        }
-        // Clear the listener.
-        webSocket->setOnopen(0);
-    } else {
-        RefPtr<EventListener> listener = getEventListener(webSocket, value, false);
-        if (listener) {
-            webSocket->setOnopen(listener);
-            createHiddenDependency(info.Holder(), value, V8Custom::kWebSocketCacheIndex);
-        }
-    }
-}
-
-ACCESSOR_GETTER(WebSocketOnmessage)
-{
-    INC_STATS("DOM.WebSocket.onmessage._get");
-    WebSocket* webSocket = V8DOMWrapper::convertToNativeObject<WebSocket>(V8ClassIndex::WEBSOCKET, info.Holder());
-    if (webSocket->onmessage()) {
-        RefPtr<V8ObjectEventListener> listener = static_cast<V8ObjectEventListener*>(webSocket->onmessage());
-        v8::Local<v8::Object> v8Listener = listener->getListenerObject();
-        return v8Listener;
-    }
-    return v8::Null();
-}
-
-ACCESSOR_SETTER(WebSocketOnmessage)
-{
-    INC_STATS("DOM.WebSocket.onmessage._set");
-    WebSocket* webSocket = V8DOMWrapper::convertToNativeObject<WebSocket>(V8ClassIndex::WEBSOCKET, info.Holder());
-    if (value->IsNull()) {
-        if (webSocket->onmessage()) {
-            V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(webSocket->onmessage());
-            v8::Local<v8::Object> v8Listener = listener->getListenerObject();
-            removeHiddenDependency(info.Holder(), v8Listener, V8Custom::kWebSocketCacheIndex);
-        }
-        // Clear the listener.
-        webSocket->setOnmessage(0);
-    } else {
-        RefPtr<EventListener> listener = getEventListener(webSocket, value, false);
-        if (listener) {
-            webSocket->setOnmessage(listener);
-            createHiddenDependency(info.Holder(), value, V8Custom::kWebSocketCacheIndex);
-        }
-    }
-}
-
-ACCESSOR_GETTER(WebSocketOnclose)
-{
-    INC_STATS("DOM.WebSocket.onclose._get");
-    WebSocket* webSocket = V8DOMWrapper::convertToNativeObject<WebSocket>(V8ClassIndex::WEBSOCKET, info.Holder());
-    if (webSocket->onclose()) {
-        V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(webSocket->onclose());
-        v8::Local<v8::Object> v8Listener = listener->getListenerObject();
-        return v8Listener;
-    }
-    return v8::Null();
-}
-
-ACCESSOR_SETTER(WebSocketOnclose)
-{
-    INC_STATS("DOM.WebSocket.onclose._set");
-    WebSocket* webSocket = V8DOMWrapper::convertToNativeObject<WebSocket>(V8ClassIndex::WEBSOCKET, info.Holder());
-    if (value->IsNull()) {
-        if (webSocket->onclose()) {
-            V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(webSocket->onclose());
-            v8::Local<v8::Object> v8Listener = listener->getListenerObject();
-            removeHiddenDependency(info.Holder(), v8Listener, V8Custom::kWebSocketCacheIndex);
-        }
-        // Clear the listener.
-        webSocket->setOnclose(0);
-    } else {
-        RefPtr<EventListener> listener = getEventListener(webSocket, value, false);
-        if (listener) {
-            webSocket->setOnclose(listener);
-            createHiddenDependency(info.Holder(), value, V8Custom::kWebSocketCacheIndex);
-        }
-    }
-}
-
 // ??? AddEventListener, RemoveEventListener
 
 CALLBACK_FUNC_DECL(WebSocketConstructor)
diff --git a/WebCore/bindings/v8/custom/V8WorkerContextCustom.cpp b/WebCore/bindings/v8/custom/V8WorkerContextCustom.cpp
index 4934f0d..21b3c30 100644
--- a/WebCore/bindings/v8/custom/V8WorkerContextCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8WorkerContextCustom.cpp
@@ -52,45 +52,6 @@ ACCESSOR_GETTER(WorkerContextSelf)
     return WorkerContextExecutionProxy::convertWorkerContextToV8Object(workerContext);
 }
 
-ACCESSOR_GETTER(WorkerContextOnerror)
-{
-    INC_STATS(L"DOM.WorkerContext.onerror._get");
-    WorkerContext* workerContext = V8DOMWrapper::convertToNativeObject<WorkerContext>(V8ClassIndex::WORKERCONTEXT, info.Holder());
-    if (workerContext->onerror()) {
-        V8WorkerContextEventListener* listener = static_cast<V8WorkerContextEventListener*>(workerContext->onerror());
-        v8::Local<v8::Object> v8Listener = listener->getListenerObject();
-        return v8Listener;
-    }
-    return v8::Undefined();
-}
-
-ACCESSOR_SETTER(WorkerContextOnerror)
-{
-    INC_STATS(L"DOM.WorkerContext.onerror._set");
-    WorkerContext* workerContext = V8DOMWrapper::convertToNativeObject<WorkerContext>(V8ClassIndex::WORKERCONTEXT, info.Holder());
-    V8WorkerContextEventListener* oldListener = static_cast<V8WorkerContextEventListener*>(workerContext->onerror());
-    if (value->IsNull()) {
-        if (workerContext->onerror()) {
-            v8::Local<v8::Object> oldV8Listener = oldListener->getListenerObject();
-            removeHiddenDependency(info.Holder(), oldV8Listener, V8Custom::kWorkerContextRequestCacheIndex);
-        }
-
-        // Clear the listener.
-        workerContext->setOnerror(0);
-    } else {
-        RefPtr<V8EventListener> listener = workerContext->script()->proxy()->findOrCreateEventListener(v8::Local<v8::Object>::Cast(value), true, false);
-        if (listener) {
-            if (oldListener) {
-                v8::Local<v8::Object> oldV8Listener = oldListener->getListenerObject();
-                removeHiddenDependency(info.Holder(), oldV8Listener, V8Custom::kWorkerContextRequestCacheIndex);
-            }
-
-            workerContext->setOnerror(listener);
-            createHiddenDependency(info.Holder(), value, V8Custom::kWorkerContextRequestCacheIndex);
-        }
-    }
-}
-
 v8::Handle<v8::Value> SetTimeoutOrInterval(const v8::Arguments& args, bool singleShot)
 {
     WorkerContext* workerContext = V8DOMWrapper::convertDOMWrapperToNative<WorkerContext>(args.Holder());
@@ -171,8 +132,7 @@ CALLBACK_FUNC_DECL(WorkerContextAddEventListener)
     INC_STATS(L"DOM.WorkerContext.addEventListener()");
     WorkerContext* workerContext = V8DOMWrapper::convertDOMWrapperToNative<WorkerContext>(args.Holder());
 
-    RefPtr<V8EventListener> listener = workerContext->script()->proxy()->findOrCreateEventListener(v8::Local<v8::Object>::Cast(args[1]), false, false);
-
+    RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(workerContext, args[1], false, ListenerFindOrCreate);
     if (listener) {
         String type = toWebCoreString(args[0]);
         bool useCapture = args[2]->BooleanValue();
@@ -187,10 +147,8 @@ CALLBACK_FUNC_DECL(WorkerContextRemoveEventListener)
 {
     INC_STATS(L"DOM.WorkerContext.removeEventListener()");
     WorkerContext* workerContext = V8DOMWrapper::convertDOMWrapperToNative<WorkerContext>(args.Holder());
-    WorkerContextExecutionProxy* proxy = workerContext->script()->proxy();
-
-    RefPtr<V8EventListener> listener = proxy->findOrCreateEventListener(v8::Local<v8::Object>::Cast(args[1]), false, true);
 
+    RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(workerContext, args[1], false, ListenerFindOnly);
     if (listener) {
         String type = toWebCoreString(args[0]);
         bool useCapture = args[2]->BooleanValue();
@@ -198,7 +156,6 @@ CALLBACK_FUNC_DECL(WorkerContextRemoveEventListener)
 
         removeHiddenDependency(args.Holder(), args[1], V8Custom::kWorkerContextRequestCacheIndex);
     }
-
     return v8::Undefined();
 }
 
diff --git a/WebCore/bindings/v8/custom/V8WorkerCustom.cpp b/WebCore/bindings/v8/custom/V8WorkerCustom.cpp
index 1cecde0..352c7a4 100644
--- a/WebCore/bindings/v8/custom/V8WorkerCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8WorkerCustom.cpp
@@ -39,7 +39,6 @@
 #include "V8Binding.h"
 #include "V8CustomBinding.h"
 #include "V8MessagePortCustom.h"
-#include "V8ObjectEventListener.h"
 #include "V8Proxy.h"
 #include "V8Utilities.h"
 #include "WorkerContext.h"
@@ -87,62 +86,6 @@ CALLBACK_FUNC_DECL(WorkerConstructor)
     return wrapperObject;
 }
 
-PassRefPtr<EventListener> getEventListener(Worker* worker, v8::Local<v8::Value> value, bool isAttribute, bool findOnly)
-{
-    if (worker->scriptExecutionContext()->isWorkerContext()) {
-        WorkerContextExecutionProxy* workerContextProxy = WorkerContextExecutionProxy::retrieve();
-        ASSERT(workerContextProxy);
-        return workerContextProxy->findOrCreateObjectEventListener(value, isAttribute, findOnly);
-    }
-
-    V8Proxy* proxy = V8Proxy::retrieve(worker->scriptExecutionContext());
-    if (proxy) {
-        V8EventListenerList* list = proxy->objectListeners();
-        return findOnly ? list->findWrapper(value, isAttribute) : list->findOrCreateWrapper<V8ObjectEventListener>(proxy->frame(), value, isAttribute);
-    }
-
-    return 0;
-}
-
-ACCESSOR_GETTER(WorkerOnmessage)
-{
-    INC_STATS(L"DOM.Worker.onmessage._get");
-    Worker* worker = V8DOMWrapper::convertToNativeObject<Worker>(V8ClassIndex::WORKER, info.Holder());
-    if (worker->onmessage()) {
-        V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(worker->onmessage());
-        v8::Local<v8::Object> v8Listener = listener->getListenerObject();
-        return v8Listener;
-    }
-    return v8::Undefined();
-}
-
-ACCESSOR_SETTER(WorkerOnmessage)
-{
-    INC_STATS(L"DOM.Worker.onmessage._set");
-    Worker* worker = V8DOMWrapper::convertToNativeObject<Worker>(V8ClassIndex::WORKER, info.Holder());
-    V8ObjectEventListener* oldListener = static_cast<V8ObjectEventListener*>(worker->onmessage());
-    if (value->IsNull()) {
-        if (oldListener) {
-            v8::Local<v8::Object> oldV8Listener = oldListener->getListenerObject();
-            removeHiddenDependency(info.Holder(), oldV8Listener, V8Custom::kWorkerRequestCacheIndex);
-        }
-
-        // Clear the listener.
-        worker->setOnmessage(0);
-    } else {
-        RefPtr<EventListener> listener = getEventListener(worker, value, true, false);
-        if (listener) {
-            if (oldListener) {
-                v8::Local<v8::Object> oldV8Listener = oldListener->getListenerObject();
-                removeHiddenDependency(info.Holder(), oldV8Listener, V8Custom::kWorkerRequestCacheIndex);
-            }
-
-            worker->setOnmessage(listener);
-            createHiddenDependency(info.Holder(), value, V8Custom::kWorkerRequestCacheIndex);
-        }
-    }
-}
-
 CALLBACK_FUNC_DECL(WorkerPostMessage)
 {
     INC_STATS("DOM.Worker.postMessage");
diff --git a/WebCore/bindings/v8/custom/V8XMLHttpRequestConstructor.cpp b/WebCore/bindings/v8/custom/V8XMLHttpRequestConstructor.cpp
index 62e923f..af647cd 100644
--- a/WebCore/bindings/v8/custom/V8XMLHttpRequestConstructor.cpp
+++ b/WebCore/bindings/v8/custom/V8XMLHttpRequestConstructor.cpp
@@ -33,7 +33,6 @@
 #include "Frame.h"
 #include "V8Binding.h"
 #include "V8CustomBinding.h"
-#include "V8ObjectEventListener.h"
 #include "V8Proxy.h"
 #include "V8Utilities.h"
 #include "XMLHttpRequest.h"
diff --git a/WebCore/bindings/v8/custom/V8XMLHttpRequestCustom.cpp b/WebCore/bindings/v8/custom/V8XMLHttpRequestCustom.cpp
index 46c7a7f..39105de 100644
--- a/WebCore/bindings/v8/custom/V8XMLHttpRequestCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8XMLHttpRequestCustom.cpp
@@ -37,7 +37,6 @@
 #include "V8Document.h"
 #include "V8File.h"
 #include "V8HTMLDocument.h"
-#include "V8ObjectEventListener.h"
 #include "V8Proxy.h"
 #include "V8Utilities.h"
 #include "WorkerContext.h"
@@ -45,230 +44,6 @@
 
 namespace WebCore {
 
-enum EventListenerType { AttributeEventListenerType, ObjectEventListenerType };
-
-static PassRefPtr<EventListener> getEventListener(XMLHttpRequest* xmlHttpRequest, v8::Local<v8::Value> value, EventListenerType type, bool findOnly)
-{
-    bool isAttribute = type == AttributeEventListenerType;
-#if ENABLE(WORKERS)
-    WorkerContextExecutionProxy* workerContextProxy = WorkerContextExecutionProxy::retrieve();
-    if (workerContextProxy)
-        return workerContextProxy->findOrCreateObjectEventListener(value, isAttribute, findOnly);
-#endif
-
-    V8Proxy* proxy = V8Proxy::retrieve(xmlHttpRequest->scriptExecutionContext());
-    if (proxy) {
-        V8EventListenerList* list = proxy->objectListeners();
-        return findOnly ? list->findWrapper(value, isAttribute) : list->findOrCreateWrapper<V8ObjectEventListener>(proxy->frame(), value, isAttribute);
-    }
-
-    return PassRefPtr<EventListener>();
-}
-
-ACCESSOR_GETTER(XMLHttpRequestOnabort)
-{
-    INC_STATS("DOM.XMLHttpRequest.onabort._get");
-    XMLHttpRequest* xmlHttpRequest = V8DOMWrapper::convertToNativeObject<XMLHttpRequest>(V8ClassIndex::XMLHTTPREQUEST, info.Holder());
-    if (xmlHttpRequest->onabort()) {
-        V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequest->onabort());
-        v8::Local<v8::Object> v8Listener = listener->getListenerObject();
-        return v8Listener;
-    }
-    return v8::Null();
-}
-
-ACCESSOR_SETTER(XMLHttpRequestOnabort)
-{
-    INC_STATS("DOM.XMLHttpRequest.onabort._set");
-    XMLHttpRequest* xmlHttpRequest = V8DOMWrapper::convertToNativeObject<XMLHttpRequest>(V8ClassIndex::XMLHTTPREQUEST, info.Holder());
-    if (value->IsNull()) {
-        if (xmlHttpRequest->onabort()) {
-            V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequest->onabort());
-            v8::Local<v8::Object> v8Listener = listener->getListenerObject();
-            removeHiddenDependency(info.Holder(), v8Listener, V8Custom::kXMLHttpRequestCacheIndex);
-        }
-
-        // Clear the listener.
-        xmlHttpRequest->setOnabort(0);
-    } else {
-        RefPtr<EventListener> listener = getEventListener(xmlHttpRequest, value, AttributeEventListenerType, false);
-        if (listener) {
-            xmlHttpRequest->setOnabort(listener);
-            createHiddenDependency(info.Holder(), value, V8Custom::kXMLHttpRequestCacheIndex);
-        }
-    }
-}
-
-ACCESSOR_GETTER(XMLHttpRequestOnerror)
-{
-    INC_STATS("DOM.XMLHttpRequest.onerror._get");
-    XMLHttpRequest* xmlHttpRequest = V8DOMWrapper::convertToNativeObject<XMLHttpRequest>(V8ClassIndex::XMLHTTPREQUEST, info.Holder());
-    if (xmlHttpRequest->onerror()) {
-        RefPtr<V8ObjectEventListener> listener = static_cast<V8ObjectEventListener*>(xmlHttpRequest->onerror());
-        v8::Local<v8::Object> v8Listener = listener->getListenerObject();
-        return v8Listener;
-    }
-    return v8::Null();
-}
-
-ACCESSOR_SETTER(XMLHttpRequestOnerror)
-{
-    INC_STATS("DOM.XMLHttpRequest.onerror._set");
-    XMLHttpRequest* xmlHttpRequest = V8DOMWrapper::convertToNativeObject<XMLHttpRequest>(V8ClassIndex::XMLHTTPREQUEST, info.Holder());
-    if (value->IsNull()) {
-        if (xmlHttpRequest->onerror()) {
-            V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequest->onerror());
-            v8::Local<v8::Object> v8Listener = listener->getListenerObject();
-            removeHiddenDependency(info.Holder(), v8Listener, V8Custom::kXMLHttpRequestCacheIndex);
-        }
-
-        // Clear the listener.
-        xmlHttpRequest->setOnerror(0);
-    } else {
-        RefPtr<EventListener> listener = getEventListener(xmlHttpRequest, value, AttributeEventListenerType, false);
-        if (listener) {
-            xmlHttpRequest->setOnerror(listener);
-            createHiddenDependency(info.Holder(), value, V8Custom::kXMLHttpRequestCacheIndex);
-        }
-    }
-}
-
-ACCESSOR_GETTER(XMLHttpRequestOnload)
-{
-    INC_STATS("DOM.XMLHttpRequest.onload._get");
-    XMLHttpRequest* xmlHttpRequest = V8DOMWrapper::convertToNativeObject<XMLHttpRequest>(V8ClassIndex::XMLHTTPREQUEST, info.Holder());
-    if (xmlHttpRequest->onload()) {
-        V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequest->onload());
-        v8::Local<v8::Object> v8Listener = listener->getListenerObject();
-        return v8Listener;
-    }
-    return v8::Null();
-}
-
-ACCESSOR_SETTER(XMLHttpRequestOnload)
-{
-    INC_STATS("DOM.XMLHttpRequest.onload._set");
-    XMLHttpRequest* xmlHttpRequest = V8DOMWrapper::convertToNativeObject<XMLHttpRequest>(V8ClassIndex::XMLHTTPREQUEST, info.Holder());
-    if (value->IsNull()) {
-        if (xmlHttpRequest->onload()) {
-            V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequest->onload());
-            v8::Local<v8::Object> v8Listener = listener->getListenerObject();
-            removeHiddenDependency(info.Holder(), v8Listener, V8Custom::kXMLHttpRequestCacheIndex);
-        }
-
-        xmlHttpRequest->setOnload(0);
-
-    } else {
-        RefPtr<EventListener> listener = getEventListener(xmlHttpRequest, value, AttributeEventListenerType, false);
-        if (listener) {
-            xmlHttpRequest->setOnload(listener.get());
-            createHiddenDependency(info.Holder(), value, V8Custom::kXMLHttpRequestCacheIndex);
-        }
-    }
-}
-
-ACCESSOR_GETTER(XMLHttpRequestOnloadstart)
-{
-    INC_STATS("DOM.XMLHttpRequest.onloadstart._get");
-    XMLHttpRequest* xmlHttpRequest = V8DOMWrapper::convertToNativeObject<XMLHttpRequest>(V8ClassIndex::XMLHTTPREQUEST, info.Holder());
-    if (xmlHttpRequest->onloadstart()) {
-        V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequest->onloadstart());
-        v8::Local<v8::Object> v8Listener = listener->getListenerObject();
-        return v8Listener;
-    }
-    return v8::Null();
-}
-
-ACCESSOR_SETTER(XMLHttpRequestOnloadstart)
-{
-    INC_STATS("DOM.XMLHttpRequest.onloadstart._set");
-    XMLHttpRequest* xmlHttpRequest = V8DOMWrapper::convertToNativeObject<XMLHttpRequest>(V8ClassIndex::XMLHTTPREQUEST, info.Holder());
-    if (value->IsNull()) {
-        if (xmlHttpRequest->onloadstart()) {
-            V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequest->onloadstart());
-            v8::Local<v8::Object> v8Listener = listener->getListenerObject();
-            removeHiddenDependency(info.Holder(), v8Listener, V8Custom::kXMLHttpRequestCacheIndex);
-        }
-
-        // Clear the listener.
-        xmlHttpRequest->setOnloadstart(0);
-    } else {
-        RefPtr<EventListener> listener = getEventListener(xmlHttpRequest, value, AttributeEventListenerType, false);
-        if (listener) {
-            xmlHttpRequest->setOnloadstart(listener);
-            createHiddenDependency(info.Holder(), value, V8Custom::kXMLHttpRequestCacheIndex);
-        }
-    }
-}
-
-ACCESSOR_GETTER(XMLHttpRequestOnprogress)
-{
-    INC_STATS("DOM.XMLHttpRequest.onprogress._get");
-    XMLHttpRequest* xmlHttpRequest = V8DOMWrapper::convertToNativeObject<XMLHttpRequest>(V8ClassIndex::XMLHTTPREQUEST, info.Holder());
-    if (xmlHttpRequest->onprogress()) {
-        V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequest->onprogress());
-        v8::Local<v8::Object> v8Listener = listener->getListenerObject();
-        return v8Listener;
-    }
-    return v8::Null();
-}
-
-ACCESSOR_SETTER(XMLHttpRequestOnprogress)
-{
-    INC_STATS("DOM.XMLHttpRequest.onprogress._set");
-    XMLHttpRequest* xmlHttpRequest = V8DOMWrapper::convertToNativeObject<XMLHttpRequest>(V8ClassIndex::XMLHTTPREQUEST, info.Holder());
-    if (value->IsNull()) {
-        if (xmlHttpRequest->onprogress()) {
-            V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequest->onprogress());
-            v8::Local<v8::Object> v8Listener = listener->getListenerObject();
-            removeHiddenDependency(info.Holder(), v8Listener, V8Custom::kXMLHttpRequestCacheIndex);
-        }
-
-        // Clear the listener.
-        xmlHttpRequest->setOnprogress(0);
-    } else {
-        RefPtr<EventListener> listener = getEventListener(xmlHttpRequest, value, AttributeEventListenerType, false);
-        if (listener) {
-            xmlHttpRequest->setOnprogress(listener);
-            createHiddenDependency(info.Holder(), value, V8Custom::kXMLHttpRequestCacheIndex);
-        }
-    }
-}
-
-ACCESSOR_GETTER(XMLHttpRequestOnreadystatechange)
-{
-    INC_STATS("DOM.XMLHttpRequest.onreadystatechange._get");
-    XMLHttpRequest* xmlHttpRequest = V8DOMWrapper::convertToNativeObject<XMLHttpRequest>(V8ClassIndex::XMLHTTPREQUEST, info.Holder());
-    if (xmlHttpRequest->onreadystatechange()) {
-        V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequest->onreadystatechange());
-        v8::Local<v8::Object> v8Listener = listener->getListenerObject();
-        return v8Listener;
-    }
-    return v8::Null();
-}
-
-ACCESSOR_SETTER(XMLHttpRequestOnreadystatechange)
-{
-    INC_STATS("DOM.XMLHttpRequest.onreadystatechange._set");
-    XMLHttpRequest* xmlHttpRequest = V8DOMWrapper::convertToNativeObject<XMLHttpRequest>(V8ClassIndex::XMLHTTPREQUEST, info.Holder());
-    if (value->IsNull()) {
-        if (xmlHttpRequest->onreadystatechange()) {
-            V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequest->onreadystatechange());
-            v8::Local<v8::Object> v8Listener = listener->getListenerObject();
-            removeHiddenDependency(info.Holder(), v8Listener, V8Custom::kXMLHttpRequestCacheIndex);
-        }
-
-        // Clear the listener.
-        xmlHttpRequest->setOnreadystatechange(0);
-    } else {
-        RefPtr<EventListener> listener = getEventListener(xmlHttpRequest, value, AttributeEventListenerType, false);
-        if (listener) {
-            xmlHttpRequest->setOnreadystatechange(listener.get());
-            createHiddenDependency(info.Holder(), value, V8Custom::kXMLHttpRequestCacheIndex);
-        }
-    }
-}
-
 ACCESSOR_GETTER(XMLHttpRequestResponseText)
 {
     // FIXME: This is only needed because webkit set this getter as custom.
@@ -283,7 +58,7 @@ CALLBACK_FUNC_DECL(XMLHttpRequestAddEventListener)
     INC_STATS("DOM.XMLHttpRequest.addEventListener()");
     XMLHttpRequest* xmlHttpRequest = V8DOMWrapper::convertToNativeObject<XMLHttpRequest>(V8ClassIndex::XMLHTTPREQUEST, args.Holder());
 
-    RefPtr<EventListener> listener = getEventListener(xmlHttpRequest, args[1], ObjectEventListenerType, false);
+    RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(xmlHttpRequest, args[1], false, ListenerFindOrCreate);
     if (listener) {
         String type = toWebCoreString(args[0]);
         bool useCapture = args[2]->BooleanValue();
@@ -299,7 +74,7 @@ CALLBACK_FUNC_DECL(XMLHttpRequestRemoveEventListener)
     INC_STATS("DOM.XMLHttpRequest.removeEventListener()");
     XMLHttpRequest* xmlHttpRequest = V8DOMWrapper::convertToNativeObject<XMLHttpRequest>(V8ClassIndex::XMLHTTPREQUEST, args.Holder());
 
-    RefPtr<EventListener> listener = getEventListener(xmlHttpRequest, args[1], ObjectEventListenerType, true);
+    RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(xmlHttpRequest, args[1], false, ListenerFindOnly);
     if (listener) {
         String type = toWebCoreString(args[0]);
         bool useCapture = args[2]->BooleanValue();
diff --git a/WebCore/bindings/v8/custom/V8XMLHttpRequestUploadCustom.cpp b/WebCore/bindings/v8/custom/V8XMLHttpRequestUploadCustom.cpp
index bbc69dd..9323f71 100644
--- a/WebCore/bindings/v8/custom/V8XMLHttpRequestUploadCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8XMLHttpRequestUploadCustom.cpp
@@ -34,7 +34,6 @@
 #include "ExceptionCode.h"
 #include "V8Binding.h"
 #include "V8CustomBinding.h"
-#include "V8ObjectEventListener.h"
 #include "V8Proxy.h"
 #include "V8Utilities.h"
 #include "XMLHttpRequest.h"
@@ -43,212 +42,14 @@
 
 namespace WebCore {
 
-ACCESSOR_GETTER(XMLHttpRequestUploadOnabort)
-{
-    INC_STATS("DOM.XMLHttpRequestUpload.onabort._get");
-    XMLHttpRequestUpload* xmlHttpRequestUpload = V8DOMWrapper::convertToNativeObject<XMLHttpRequestUpload>(V8ClassIndex::XMLHTTPREQUESTUPLOAD, info.Holder());
-    if (xmlHttpRequestUpload->onabort()) {
-        V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequestUpload->onabort());
-        v8::Local<v8::Object> v8Listener = listener->getListenerObject();
-        return v8Listener;
-    }
-    return v8::Null();
-}
-
-ACCESSOR_SETTER(XMLHttpRequestUploadOnabort)
-{
-    INC_STATS("DOM.XMLHttpRequestUpload.onabort._set");
-    XMLHttpRequestUpload* xmlHttpRequestUpload = V8DOMWrapper::convertToNativeObject<XMLHttpRequestUpload>(V8ClassIndex::XMLHTTPREQUESTUPLOAD, info.Holder());
-    if (value->IsNull()) {
-        if (xmlHttpRequestUpload->onabort()) {
-            V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequestUpload->onabort());
-            v8::Local<v8::Object> v8Listener = listener->getListenerObject();
-            removeHiddenDependency(info.Holder(), v8Listener, V8Custom::kXMLHttpRequestCacheIndex);
-        }
-
-        // Clear the listener.
-        xmlHttpRequestUpload->setOnabort(0);
-    } else {
-        XMLHttpRequest* xmlHttpRequest = xmlHttpRequestUpload->associatedXMLHttpRequest();
-        V8Proxy* proxy = V8Proxy::retrieve(xmlHttpRequest->scriptExecutionContext());
-        if (!proxy)
-            return;
-
-        RefPtr<EventListener> listener = proxy->objectListeners()->findOrCreateWrapper<V8ObjectEventListener>(proxy->frame(), value, false);
-        if (listener) {
-            xmlHttpRequestUpload->setOnabort(listener);
-            createHiddenDependency(info.Holder(), value, V8Custom::kXMLHttpRequestCacheIndex);
-        }
-    }
-}
-
-ACCESSOR_GETTER(XMLHttpRequestUploadOnerror)
-{
-    INC_STATS("DOM.XMLHttpRequestUpload.onerror._get");
-    XMLHttpRequestUpload* xmlHttpRequestUpload = V8DOMWrapper::convertToNativeObject<XMLHttpRequestUpload>(V8ClassIndex::XMLHTTPREQUESTUPLOAD, info.Holder());
-    if (xmlHttpRequestUpload->onerror()) {
-        V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequestUpload->onerror());
-        v8::Local<v8::Object> v8Listener = listener->getListenerObject();
-        return v8Listener;
-    }
-    return v8::Null();
-}
-
-ACCESSOR_SETTER(XMLHttpRequestUploadOnerror)
-{
-    INC_STATS("DOM.XMLHttpRequestUpload.onerror._set");
-    XMLHttpRequestUpload* xmlHttpRequestUpload = V8DOMWrapper::convertToNativeObject<XMLHttpRequestUpload>(V8ClassIndex::XMLHTTPREQUESTUPLOAD, info.Holder());
-    if (value->IsNull()) {
-        if (xmlHttpRequestUpload->onerror()) {
-            V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequestUpload->onerror());
-            v8::Local<v8::Object> v8Listener = listener->getListenerObject();
-            removeHiddenDependency(info.Holder(), v8Listener, V8Custom::kXMLHttpRequestCacheIndex);
-        }
-
-        // Clear the listener.
-        xmlHttpRequestUpload->setOnerror(0);
-    } else {
-        XMLHttpRequest* xmlHttpRequest = xmlHttpRequestUpload->associatedXMLHttpRequest();
-        V8Proxy* proxy = V8Proxy::retrieve(xmlHttpRequest->scriptExecutionContext());
-        if (!proxy)
-            return;
-
-        RefPtr<EventListener> listener = proxy->objectListeners()->findOrCreateWrapper<V8ObjectEventListener>(proxy->frame(), value, false);
-        if (listener) {
-            xmlHttpRequestUpload->setOnerror(listener);
-            createHiddenDependency(info.Holder(), value, V8Custom::kXMLHttpRequestCacheIndex);
-        }
-    }
-}
-
-ACCESSOR_GETTER(XMLHttpRequestUploadOnload)
-{
-    INC_STATS("DOM.XMLHttpRequestUpload.onload._get");
-    XMLHttpRequestUpload* xmlHttpRequestUpload = V8DOMWrapper::convertToNativeObject<XMLHttpRequestUpload>(V8ClassIndex::XMLHTTPREQUESTUPLOAD, info.Holder());
-    if (xmlHttpRequestUpload->onload()) {
-        V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequestUpload->onload());
-        v8::Local<v8::Object> v8Listener = listener->getListenerObject();
-        return v8Listener;
-    }
-    return v8::Null();
-}
-
-ACCESSOR_SETTER(XMLHttpRequestUploadOnload)
-{
-    INC_STATS("DOM.XMLHttpRequestUpload.onload._set");
-    XMLHttpRequestUpload* xmlHttpRequestUpload = V8DOMWrapper::convertToNativeObject<XMLHttpRequestUpload>(V8ClassIndex::XMLHTTPREQUESTUPLOAD, info.Holder());
-    if (value->IsNull()) {
-        if (xmlHttpRequestUpload->onload()) {
-            V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequestUpload->onload());
-            v8::Local<v8::Object> v8Listener = listener->getListenerObject();
-            removeHiddenDependency(info.Holder(), v8Listener, V8Custom::kXMLHttpRequestCacheIndex);
-        }
-
-        // Clear the listener.
-        xmlHttpRequestUpload->setOnload(0);
-    } else {
-        XMLHttpRequest* xmlHttpRequest = xmlHttpRequestUpload->associatedXMLHttpRequest();
-        V8Proxy* proxy = V8Proxy::retrieve(xmlHttpRequest->scriptExecutionContext());
-        if (!proxy)
-            return;
-
-        RefPtr<EventListener> listener = proxy->objectListeners()->findOrCreateWrapper<V8ObjectEventListener>(proxy->frame(), value, false);
-        if (listener) {
-            xmlHttpRequestUpload->setOnload(listener);
-            createHiddenDependency(info.Holder(), value, V8Custom::kXMLHttpRequestCacheIndex);
-        }
-    }
-}
-
-ACCESSOR_GETTER(XMLHttpRequestUploadOnloadstart)
-{
-    INC_STATS("DOM.XMLHttpRequestUpload.onloadstart._get");
-    XMLHttpRequestUpload* xmlHttpRequestUpload = V8DOMWrapper::convertToNativeObject<XMLHttpRequestUpload>(V8ClassIndex::XMLHTTPREQUESTUPLOAD, info.Holder());
-    if (xmlHttpRequestUpload->onloadstart()) {
-        V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequestUpload->onloadstart());
-        v8::Local<v8::Object> v8Listener = listener->getListenerObject();
-        return v8Listener;
-    }
-    return v8::Null();
-}
-
-ACCESSOR_SETTER(XMLHttpRequestUploadOnloadstart)
-{
-    INC_STATS("DOM.XMLHttpRequestUpload.onloadstart._set");
-    XMLHttpRequestUpload* xmlHttpRequestUpload = V8DOMWrapper::convertToNativeObject<XMLHttpRequestUpload>(V8ClassIndex::XMLHTTPREQUESTUPLOAD, info.Holder());
-    if (value->IsNull()) {
-        if (xmlHttpRequestUpload->onloadstart()) {
-            V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequestUpload->onloadstart());
-            v8::Local<v8::Object> v8Listener = listener->getListenerObject();
-            removeHiddenDependency(info.Holder(), v8Listener, V8Custom::kXMLHttpRequestCacheIndex);
-        }
-
-        // Clear the listener.
-        xmlHttpRequestUpload->setOnloadstart(0);
-    } else {
-        XMLHttpRequest* xmlHttpRequest = xmlHttpRequestUpload->associatedXMLHttpRequest();
-        V8Proxy* proxy = V8Proxy::retrieve(xmlHttpRequest->scriptExecutionContext());
-        if (!proxy)
-            return;
-
-        RefPtr<EventListener> listener = proxy->objectListeners()->findOrCreateWrapper<V8ObjectEventListener>(proxy->frame(), value, false);
-        if (listener) {
-            xmlHttpRequestUpload->setOnloadstart(listener);
-            createHiddenDependency(info.Holder(), value, V8Custom::kXMLHttpRequestCacheIndex);
-        }
-    }
-}
-
-ACCESSOR_GETTER(XMLHttpRequestUploadOnprogress)
-{
-    INC_STATS("DOM.XMLHttpRequestUpload.onprogress._get");
-    XMLHttpRequestUpload* xmlHttpRequestUpload = V8DOMWrapper::convertToNativeObject<XMLHttpRequestUpload>(V8ClassIndex::XMLHTTPREQUESTUPLOAD, info.Holder());
-    if (xmlHttpRequestUpload->onprogress()) {
-        V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequestUpload->onprogress());
-        v8::Local<v8::Object> v8Listener = listener->getListenerObject();
-        return v8Listener;
-    }
-    return v8::Null();
-}
-
-ACCESSOR_SETTER(XMLHttpRequestUploadOnprogress)
-{
-    INC_STATS("DOM.XMLHttpRequestUpload.onprogress._set");
-    XMLHttpRequestUpload* xmlHttpRequestUpload = V8DOMWrapper::convertToNativeObject<XMLHttpRequestUpload>(V8ClassIndex::XMLHTTPREQUESTUPLOAD, info.Holder());
-    if (value->IsNull()) {
-        if (xmlHttpRequestUpload->onprogress()) {
-            V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequestUpload->onprogress());
-            v8::Local<v8::Object> v8Listener = listener->getListenerObject();
-            removeHiddenDependency(info.Holder(), v8Listener, V8Custom::kXMLHttpRequestCacheIndex);
-        }
-
-        // Clear the listener.
-        xmlHttpRequestUpload->setOnprogress(0);
-    } else {
-        XMLHttpRequest* xmlHttpRequest = xmlHttpRequestUpload->associatedXMLHttpRequest();
-        V8Proxy* proxy = V8Proxy::retrieve(xmlHttpRequest->scriptExecutionContext());
-        if (!proxy)
-            return;
-
-        RefPtr<EventListener> listener = proxy->objectListeners()->findOrCreateWrapper<V8ObjectEventListener>(proxy->frame(), value, false);
-        if (listener) {
-            xmlHttpRequestUpload->setOnprogress(listener);
-            createHiddenDependency(info.Holder(), value, V8Custom::kXMLHttpRequestCacheIndex);
-        }
-    }
-}
-
 CALLBACK_FUNC_DECL(XMLHttpRequestUploadAddEventListener)
 {
     INC_STATS("DOM.XMLHttpRequestUpload.addEventListener()");
     XMLHttpRequestUpload* xmlHttpRequestUpload = V8DOMWrapper::convertToNativeObject<XMLHttpRequestUpload>(V8ClassIndex::XMLHTTPREQUESTUPLOAD, args.Holder());
 
     XMLHttpRequest* xmlHttpRequest = xmlHttpRequestUpload->associatedXMLHttpRequest();
-    V8Proxy* proxy = V8Proxy::retrieve(xmlHttpRequest->scriptExecutionContext());
-    if (!proxy)
-        return v8::Undefined();
 
-    RefPtr<EventListener> listener = proxy->objectListeners()->findOrCreateWrapper<V8ObjectEventListener>(proxy->frame(), args[1], false);
+    RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(xmlHttpRequest, args[1], false, ListenerFindOrCreate);
     if (listener) {
         String type = toWebCoreString(args[0]);
         bool useCapture = args[2]->BooleanValue();
@@ -265,12 +66,8 @@ CALLBACK_FUNC_DECL(XMLHttpRequestUploadRemoveEventListener)
     XMLHttpRequestUpload* xmlHttpRequestUpload = V8DOMWrapper::convertToNativeObject<XMLHttpRequestUpload>(V8ClassIndex::XMLHTTPREQUESTUPLOAD, args.Holder());
 
     XMLHttpRequest* xmlHttpRequest = xmlHttpRequestUpload->associatedXMLHttpRequest();
-    V8Proxy* proxy = V8Proxy::retrieve(xmlHttpRequest->scriptExecutionContext());
-    if (!proxy)
-        return v8::Undefined(); // Probably leaked.
-
-    RefPtr<EventListener> listener = proxy->objectListeners()->findWrapper(args[1], false);
 
+    RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(xmlHttpRequest, args[1], false, ListenerFindOnly);
     if (listener) {
         String type = toWebCoreString(args[0]);
         bool useCapture = args[2]->BooleanValue();

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list