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

ggaren at apple.com ggaren at apple.com
Thu Oct 29 20:32:53 UTC 2009


The following commit has been merged in the webkit-1.1 branch:
commit 521f64b851214f462b381608be6345d63f722210
Author: ggaren at apple.com <ggaren at apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Thu Sep 24 05:53:23 2009 +0000

    JavaScriptCore: Added the ability to swap vectors with inline capacities, so you can
    store a vector with inline capacity in a hash table.
    
    Patch by Geoffrey Garen <ggaren at apple.com> on 2009-09-23
    Reviewed by Sam Weinig.
    
    * wtf/Vector.h:
    (WTF::swap):
    (WTF::VectorBuffer::swap):
    
    WebCore: Bring a little sanity to this crazy EventTarget world of ours
    https://bugs.webkit.org/show_bug.cgi?id=29701
    
    Patch by Geoffrey Garen <ggaren at apple.com> on 2009-09-23
    Reviewed by Sam Weinig.
    
    Lots of EventTarget refactoring to achieve a single shared implementation
    that fixes some of the performance and correctness bugs of the many individual
    implementations, and makes reasoning about EventTargets and EventListeners
    much easier.
    
    The basic design is this:
        - EventTarget manages a set of EventListeners.
        - onXXX EventListener attributes forward to standard EventTarget APIs.
        - Since the onXXX code is repetitive, it is usually done with macros
          of the form DEFINE_ATTRIBUTE_EVENT_LISTENER(attributeName).
        - EventTarget provides a shared implementation of dispatchEvent,
          which subclasses with special event dispatch rules, like Node, override.
        - To support Node, which lazily instantiates its EventTarget data,
          EventTarget has no data members, and instead makes a virtual call
          to get its data from wherever its subclass chose to store it.
    
    Code that used to call dispatchEvent, passing an ExceptionCode paratmeter,
    even though no exception could be thrown, has been changed not to do so,
    to improve clarity and performance.
    
    Code that used to call a special dispatchXXXEvent function, which just
    turned around and called dispatchEvent, has been changed to call
    dispatchEvent, to improve clarity and performance.
    
    * WebCore.base.exp:
    * WebCore.xcodeproj/project.pbxproj: Another day in the life of a WebKit
    engineer.
    
    * bindings/js/JSDOMBinding.cpp:
    (WebCore::isObservableThroughDOM): Updated for Node API change. Added
    "is not in the document but is firing event listeners" as a condition
    that makes a Node observable in the DOM, so that event listeners firing
    on removed nodes are not destroyed midstream. (This was a long-standing
    bug that was somewhat hidden by the old implementation's habit of
    copying the RegisteredEventListener vector before firing events, which
    would keep almost all the relevant objects from being destroyed.)
    
    * bindings/js/JSEventListener.cpp:
    (WebCore::JSEventListener::handleEvent): Removed the isWindowEvent flag
    because it was one of the most elaborately planned no-ops in the history
    of software crime, and one of the reasons clients thought they needed more
    than one dispatchEvent function even though they didn't.
    * bindings/js/JSEventListener.h:
    
    * bindings/js/JSDOMWindowCustom.cpp:
    (WebCore::JSDOMWindow::markChildren):
    (WebCore::JSMessagePort::markChildren):
    * bindings/js/JSNodeCustom.cpp:
    (WebCore::JSNode::markChildren):
    * bindings/js/JSAbstractWorkerCustom.cpp:
    * bindings/js/JSDOMApplicationCacheCustom.cpp:
    * bindings/js/JSDedicatedWorkerContextCustom.cpp:
    * bindings/js/JSEventSourceCustom.cpp:
    * bindings/js/JSMessagePortCustom.cpp:
    * bindings/js/JSSharedWorkerContextCustom.cpp: Removed.
    * bindings/js/JSWebSocketCustom.cpp:
    * bindings/js/JSWorkerContextCustom.cpp:
    (WebCore::JSWorkerContext::markChildren):
    * bindings/js/JSWorkerCustom.cpp:
    * bindings/js/JSXMLHttpRequestCustom.cpp:
    (WebCore::JSXMLHttpRequest::markChildren):
    * bindings/js/JSXMLHttpRequestUploadCustom.cpp:
    (WebCore::JSXMLHttpRequestUpload::markChildren): EventListener marking is
    now autogenerated. Classes that still have custom mark functions for other
    reasons now call a shared EventTarget API to mark their EventListeners.
    
    * bindings/objc/ObjCEventListener.h:
    * bindings/objc/ObjCEventListener.mm:
    (WebCore::ObjCEventListener::handleEvent): Bye bye isWindowEvent.
    
    * bindings/scripts/CodeGeneratorJS.pm: Autogeneration support for
    marking and invalidating event listeners.
    
    * dom/CharacterData.cpp:
    (WebCore::CharacterData::dispatchModifiedEvent):
    * dom/ContainerNode.cpp:
    (WebCore::ContainerNode::insertBefore):
    (WebCore::ContainerNode::replaceChild):
    (WebCore::willRemoveChild):
    (WebCore::ContainerNode::appendChild):
    (WebCore::dispatchChildInsertionEvents):
    (WebCore::dispatchChildRemovalEvents):
    * dom/Document.cpp:
    (WebCore::Document::removeAllEventListeners):
    (WebCore::Document::implicitClose):
    (WebCore::Document::setFocusedNode):
    (WebCore::Document::dispatchWindowEvent):
    (WebCore::Document::dispatchWindowLoadEvent):
    (WebCore::Document::finishedParsing):
    * dom/Document.h: Use dispatchEvent directly.
    
    * dom/Element.h: Moved a few event listener attributes down from Node,
    since they don't apply to all Nodes, only Elements.
    
    * dom/EventListener.h: Removed isWindowEvent parameter.
    
    * dom/EventNames.h: Added the "display" event name, so it works correctly
    with attribute macros, and for performance.
    
    * dom/EventTarget.cpp:
    (WebCore::forbidEventDispatch):
    (WebCore::allowEventDispatch):
    (WebCore::eventDispatchForbidden): Made this code (embarrasingly) thread
    safe, since it's now called on multiple threads. (Currently, we only forbid
    event dispatch on the main thread. If we ever want to forbid event dispatch
    on secondary threads, we can improve it then.)
    
    (WebCore::EventTarget::addEventListener):
    (WebCore::EventTarget::removeEventListener):
    (WebCore::EventTarget::setAttributeEventListener):
    (WebCore::EventTarget::getAttributeEventListener):
    (WebCore::EventTarget::clearAttributeEventListener):
    (WebCore::EventTarget::dispatchEvent):
    (WebCore::EventTarget::fireEventListeners):
    (WebCore::EventTarget::getEventListeners):
    (WebCore::EventTarget::removeAllEventListeners):
    * dom/EventTarget.h:
    (WebCore::FiringEventEndIterator::FiringEventEndIterator):
    (WebCore::EventTarget::ref):
    (WebCore::EventTarget::deref):
    (WebCore::EventTarget::markEventListeners):
    (WebCore::EventTarget::invalidateEventListeners):
    (WebCore::EventTarget::isFiringEventListeners):
    (WebCore::EventTarget::hasEventListeners): The ONE TRUE IMPLEMENTATION of
    EventTarget APIs, crafted from an amalgam of all the different versions
    we used to have. The most significant change here is that we no longer
    make a copy of an EventListener vector before firing the events in the
    vector -- instead, we use a reference to the original vector, along with
    a notification mechanism for the unlikely case when an EventListener is
    removed from the vector. This substantially reduces malloc, copying, and
    refcount overhead, and complexity.
    
    * dom/InputElement.cpp:
    (WebCore::InputElement::setValueFromRenderer):
    * dom/MessageEvent.h:
    (WebCore::MessageEvent::create): Use dispatchEvent directly.
    
    * dom/MessagePort.cpp:
    (WebCore::MessagePort::dispatchMessages):
    (WebCore::MessagePort::eventTargetData):
    (WebCore::MessagePort::ensureEventTargetData):
    * dom/MessagePort.h:
    (WebCore::MessagePort::setOnmessage):
    (WebCore::MessagePort::onmessage):
    * dom/MessagePort.idl: Removed custom EventTarget implementation.
    
    * dom/MutationEvent.h:
    (WebCore::MutationEvent::create): Added some default values so callers
    can construct MutationEvents more easily, without calling a custom dispatch
    function.
    
    * dom/Node.cpp:
    (WebCore::Node::addEventListener):
    (WebCore::Node::removeEventListener):
    (WebCore::Node::eventTargetData):
    (WebCore::Node::ensureEventTargetData):
    (WebCore::Node::handleLocalEvents):
    (WebCore::Node::dispatchEvent):
    (WebCore::Node::dispatchGenericEvent):
    (WebCore::Node::dispatchSubtreeModifiedEvent):
    (WebCore::Node::dispatchUIEvent):
    (WebCore::Node::dispatchKeyEvent):
    (WebCore::Node::dispatchMouseEvent):
    (WebCore::Node::dispatchWheelEvent):
    (WebCore::Node::dispatchFocusEvent):
    (WebCore::Node::dispatchBlurEvent):
    * dom/Node.h:
    (WebCore::Node::preDispatchEventHandler):
    (WebCore::Node::postDispatchEventHandler):
    * dom/Node.idl:
    * dom/NodeRareData.h:
    (WebCore::NodeRareData::eventTargetData):
    (WebCore::NodeRareData::ensureEventTargetData): Use the shared EventTarget
    interface, and call dispatchEvent directly instead of custom dispatchXXXEvent
    functions that just forwarded to dispatchEvent.
    
    * dom/RegisteredEventListener.cpp:
    * dom/RegisteredEventListener.h:
    (WebCore::RegisteredEventListener::RegisteredEventListener):
    (WebCore::operator==): This is just a simple struct now, since we no longer
    do a complicated copy / refCount / isRemoved dance just to honor the rule
    that an EventListener can be removed during event dispatch.
    
    * history/CachedFrame.cpp:
    (WebCore::CachedFrameBase::restore): Removed another custom dispatchEvent.
    
    * html/HTMLBodyElement.cpp:
    * html/HTMLBodyElement.h: Use the shared EventTarget API.
    
    * html/HTMLFormControlElement.cpp:
    (WebCore::HTMLFormControlElement::dispatchFormControlChangeEvent):
    (WebCore::HTMLFormControlElement::checkValidity):
    * html/HTMLFormElement.cpp:
    (WebCore::HTMLFormElement::handleLocalEvents):
    (WebCore::HTMLFormElement::prepareSubmit):
    (WebCore::HTMLFormElement::reset):
    * html/HTMLFormElement.h: Use the standard dispatchEvent API.
    
    * html/HTMLFrameSetElement.cpp:
    * html/HTMLFrameSetElement.h: Use the shared EventTarget API.
    
    * html/HTMLImageLoader.cpp:
    (WebCore::HTMLImageLoader::dispatchLoadEvent):
    * html/HTMLInputElement.cpp:
    (WebCore::HTMLInputElement::onSearch):
    * html/HTMLMediaElement.cpp:
    (WebCore::HTMLMediaElement::loadInternal):
    * html/HTMLScriptElement.cpp:
    (WebCore::HTMLScriptElement::dispatchLoadEvent):
    (WebCore::HTMLScriptElement::dispatchErrorEvent):
    * html/HTMLSourceElement.cpp:
    (WebCore::HTMLSourceElement::errorEventTimerFired):
    * html/HTMLTokenizer.cpp:
    (WebCore::HTMLTokenizer::notifyFinished): Use the standard dispatchEvent API.
    
    * inspector/InspectorDOMAgent.cpp:
    (WebCore::InspectorDOMAgent::handleEvent):
    * inspector/InspectorDOMAgent.h:
    * inspector/InspectorDOMStorageResource.cpp:
    (WebCore::InspectorDOMStorageResource::handleEvent):
    * inspector/InspectorDOMStorageResource.h:
    * loader/FrameLoader.cpp:
    (WebCore::FrameLoader::stopLoading):
    (WebCore::FrameLoader::canCachePageContainingThisFrame):
    (WebCore::FrameLoader::logCanCacheFrameDecision):
    (WebCore::HashChangeEventTask::performTask):
    (WebCore::FrameLoader::pageHidden): No more isWindowEvent.
    
    * loader/ImageDocument.cpp:
    (WebCore::ImageEventListener::handleEvent):
    * loader/appcache/ApplicationCacheGroup.cpp:
    (WebCore::CallCacheListenerTask::performTask):
    * loader/appcache/ApplicationCacheHost.cpp:
    (WebCore::ApplicationCacheHost::notifyDOMApplicationCache):
    * loader/appcache/ApplicationCacheHost.h:
    * loader/appcache/DOMApplicationCache.cpp:
    (WebCore::DOMApplicationCache::eventTargetData):
    (WebCore::DOMApplicationCache::ensureEventTargetData):
    * loader/appcache/DOMApplicationCache.h:
    * loader/appcache/DOMApplicationCache.idl: Switched to the standard
    EventTarget API. As a part of this, I switched this class from using a
    custom internal event name enumeration to using the standard EventNames.
    
    * notifications/Notification.cpp:
    (WebCore::Notification::eventTargetData):
    (WebCore::Notification::ensureEventTargetData):
    * notifications/Notification.h:
    (WebCore::Notification::scriptExecutionContext):
    * notifications/Notification.idl: Switched to the standard EventTarget API.
    
    * page/DOMWindow.cpp:
    (WebCore::PostMessageTimer::event):
    (WebCore::windowsWithUnloadEventListeners):
    (WebCore::windowsWithBeforeUnloadEventListeners):
    (WebCore::allowsBeforeUnloadListeners):
    (WebCore::DOMWindow::dispatchAllPendingBeforeUnloadEvents):
    (WebCore::DOMWindow::pendingUnloadEventListeners):
    (WebCore::DOMWindow::dispatchAllPendingUnloadEvents): Changed the "pending"
    unload / beforeunload listener tracker just to track which windows had
    such listeners, instead of actually keeping a copy of the listeners. Now,
    this code can use the standard EventTarget API.
    
    (WebCore::DOMWindow::~DOMWindow):
    (WebCore::DOMWindow::postMessageTimerFired):
    (WebCore::DOMWindow::addEventListener):
    (WebCore::DOMWindow::removeEventListener):
    (WebCore::DOMWindow::dispatchLoadEvent):
    (WebCore::DOMWindow::dispatchEvent):
    (WebCore::DOMWindow::removeAllEventListeners):
    (WebCore::DOMWindow::captureEvents):
    (WebCore::DOMWindow::releaseEvents):
    (WebCore::DOMWindow::eventTargetData):
    (WebCore::DOMWindow::ensureEventTargetData):
    * page/DOMWindow.h:
    * page/DOMWindow.idl: Use the standard EventTarget APIs.
    
    * page/EventHandler.cpp:
    (WebCore::EventHandler::canMouseDownStartSelect):
    (WebCore::EventHandler::canMouseDragExtendSelect):
    (WebCore::EventHandler::sendResizeEvent):
    (WebCore::EventHandler::sendScrollEvent): Use dispatchEvent directly.
    
    * page/EventSource.cpp:
    (WebCore::EventSource::endRequest):
    (WebCore::EventSource::didReceiveResponse):
    (WebCore::EventSource::parseEventStreamLine):
    (WebCore::EventSource::stop):
    (WebCore::EventSource::createMessageEvent):
    (WebCore::EventSource::eventTargetData):
    (WebCore::EventSource::ensureEventTargetData):
    * page/EventSource.h:
    * page/EventSource.idl: Use the standard EventTarget APIs.
    
    * page/FocusController.cpp:
    (WebCore::dispatchEventsOnWindowAndFocusedNode):
    (WebCore::FocusController::setFocusedFrame):
    * page/Frame.cpp:
    (WebCore::Frame::shouldClose):
    * page/Frame.h:
    * page/Page.cpp:
    (WebCore::networkStateChanged):
    * page/animation/AnimationController.cpp:
    (WebCore::AnimationControllerPrivate::updateStyleIfNeededDispatcherFired):
    * rendering/RenderListBox.cpp:
    (WebCore::RenderListBox::valueChanged):
    * rendering/RenderTextControl.cpp:
    (WebCore::RenderTextControl::selectionChanged):
    * rendering/RenderTextControlMultiLine.cpp:
    (WebCore::RenderTextControlMultiLine::subtreeHasChanged): Use dispatchEvent.
    
    * svg/SVGElement.cpp:
    (WebCore::hasLoadListener): Rewritten for new EventTarget API.
    
    * svg/SVGElementInstance.cpp:
    (WebCore::dummyEventTargetData):
    (WebCore::SVGElementInstance::addEventListener):
    (WebCore::SVGElementInstance::removeEventListener):
    (WebCore::SVGElementInstance::removeAllEventListeners):
    (WebCore::SVGElementInstance::dispatchEvent):
    (WebCore::SVGElementInstance::eventTargetData):
    (WebCore::SVGElementInstance::ensureEventTargetData): Use the EventTarget API.
    
    * svg/SVGElementInstance.h:
    * svg/SVGImageLoader.cpp:
    (WebCore::SVGImageLoader::dispatchLoadEvent):
    * svg/SVGScriptElement.cpp:
    (WebCore::SVGScriptElement::dispatchErrorEvent): Use dispatchEvent directly.
    
    * svg/SVGUseElement.cpp:
    (WebCore::SVGUseElement::transferEventListenersToShadowTree): Updated for
    new EventTarget API.
    
    * svg/animation/SVGSMILElement.cpp:
    (WebCore::ConditionEventListener::handleEvent): No more isWindowEvent.
    
    * websockets/WebSocket.cpp:
    (WebCore::ProcessWebSocketEventTask::create):
    (WebCore::ProcessWebSocketEventTask::performTask):
    (WebCore::ProcessWebSocketEventTask::ProcessWebSocketEventTask):
    (WebCore::WebSocket::didConnect):
    (WebCore::WebSocket::didReceiveMessage):
    (WebCore::WebSocket::didClose):
    (WebCore::WebSocket::eventTargetData):
    (WebCore::WebSocket::ensureEventTargetData):
    * websockets/WebSocket.h:
    * websockets/WebSocket.idl:
    * workers/AbstractWorker.cpp:
    (WebCore::AbstractWorker::eventTargetData):
    (WebCore::AbstractWorker::ensureEventTargetData):
    * workers/AbstractWorker.h:
    * workers/AbstractWorker.idl:
    * workers/DedicatedWorkerContext.cpp:
    * workers/DedicatedWorkerContext.h:
    * workers/DedicatedWorkerContext.idl:
    * workers/DefaultSharedWorkerRepository.cpp:
    (WebCore::SharedWorkerConnectTask::performTask):
    (WebCore::SharedWorkerScriptLoader::load):
    (WebCore::SharedWorkerScriptLoader::notifyFinished):
    * workers/SharedWorker.idl:
    * workers/SharedWorkerContext.cpp:
    (WebCore::createConnectEvent):
    * workers/SharedWorkerContext.h:
    * workers/SharedWorkerContext.idl:
    * workers/Worker.cpp:
    (WebCore::Worker::notifyFinished):
    * workers/Worker.h:
    * workers/Worker.idl:
    * workers/WorkerContext.cpp:
    (WebCore::WorkerContext::eventTargetData):
    (WebCore::WorkerContext::ensureEventTargetData):
    * workers/WorkerContext.h:
    * workers/WorkerContext.idl:
    * workers/WorkerMessagingProxy.cpp:
    (WebCore::MessageWorkerContextTask::performTask):
    (WebCore::MessageWorkerTask::performTask):
    (WebCore::WorkerExceptionTask::performTask):
    * xml/XMLHttpRequest.cpp:
    (WebCore::XMLHttpRequest::callReadyStateChangeListener):
    (WebCore::XMLHttpRequest::createRequest):
    (WebCore::XMLHttpRequest::abort):
    (WebCore::XMLHttpRequest::networkError):
    (WebCore::XMLHttpRequest::abortError):
    (WebCore::XMLHttpRequest::didSendData):
    (WebCore::XMLHttpRequest::didReceiveData):
    (WebCore::XMLHttpRequest::eventTargetData):
    (WebCore::XMLHttpRequest::ensureEventTargetData):
    * xml/XMLHttpRequest.h:
    * xml/XMLHttpRequest.idl:
    * xml/XMLHttpRequestProgressEvent.h:
    (WebCore::XMLHttpRequestProgressEvent::create):
    * xml/XMLHttpRequestUpload.cpp:
    (WebCore::XMLHttpRequestUpload::eventTargetData):
    (WebCore::XMLHttpRequestUpload::ensureEventTargetData):
    * xml/XMLHttpRequestUpload.h:
    * xml/XMLHttpRequestUpload.idl: Use new EventTarget API.
    
    WebKit/mac: Updated for a WebCore rename.
    
    Patch by Geoffrey Garen <ggaren at apple.com> on 2009-09-23
    Reviewed by Sam Weinig.
    
    * WebView/WebFrame.mm:
    (-[WebFrame _cacheabilityDictionary]):
    
    LayoutTests: Layout tests for event target sanitization.
    
    Patch by Geoffrey Garen <ggaren at apple.com> on 2009-09-23
    Reviewed by Sam Weinig.
    
    New tests for event dispatch:
    
    * fast/events/event-attributes-after-exception-expected.txt: Added.
    * fast/events/event-attributes-after-exception.html: Added.
    * fast/events/event-fire-order-expected.txt: Added.
    * fast/events/event-fire-order.html: Added.
    * fast/events/event-fired-after-removal-expected.txt: Added.
    * fast/events/event-fired-after-removal.html: Added.
    
    Fixed these tests:
    
    * fast/xmlhttprequest/xmlhttprequest-get-expected.txt: eventPhase should
    be AT_TARGET (2) when firing an event on an XHR, not INVALID (0).
    * http/tests/xmlhttprequest/infoOnProgressEvent-expected.txt: ditto
    
    * http/tests/xmlhttprequest/event-target-expected.txt:
    * http/tests/xmlhttprequest/event-target.html: Removing an event listener
    during event dispatch should prevent it from firing. (This test was backwards.)
    
    * svg/custom/loadevents-capturing.svg: Enhanced this test to tell you
    why it fails when it fails. Changed it to register runTest() (now named
    reportResults()) using addEventListener() instead of the 'onload' attribute.
    The test relies on reportResults() running after handler(), so it needs
    to register reportResults() after handler().
    
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@48701 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/JavaScriptCore/ChangeLog b/JavaScriptCore/ChangeLog
index 2b2fe18..6f41112 100644
--- a/JavaScriptCore/ChangeLog
+++ b/JavaScriptCore/ChangeLog
@@ -1,3 +1,14 @@
+2009-09-23  Geoffrey Garen  <ggaren at apple.com>
+
+        Reviewed by Sam Weinig.
+
+        Added the ability to swap vectors with inline capacities, so you can
+        store a vector with inline capacity in a hash table.
+
+        * wtf/Vector.h:
+        (WTF::swap):
+        (WTF::VectorBuffer::swap):
+
 2009-09-23  David Kilzer  <ddkilzer at apple.com>
 
         Move definition of USE(PLUGIN_HOST_PROCESS) from WebKitPrefix.h to Platform.h
diff --git a/JavaScriptCore/wtf/Vector.h b/JavaScriptCore/wtf/Vector.h
index 7cba4e4..e1fc5b4 100644
--- a/JavaScriptCore/wtf/Vector.h
+++ b/JavaScriptCore/wtf/Vector.h
@@ -63,6 +63,13 @@ namespace WTF {
     template <size_t size> struct AlignedBuffer<size, 32> { WTF_ALIGNED(AlignedBufferChar, buffer[size], 32); };
     template <size_t size> struct AlignedBuffer<size, 64> { WTF_ALIGNED(AlignedBufferChar, buffer[size], 64); };
 
+    template <size_t size, size_t alignment>
+    void swap(AlignedBuffer<size, alignment>& a, AlignedBuffer<size, alignment>& b)
+    {
+        for (size_t i = 0; i < size; ++i)
+            std::swap(a.buffer[i], b.buffer[i]);
+    }
+
     template <bool needsDestruction, typename T>
     class VectorDestructor;
 
@@ -404,6 +411,27 @@ namespace WTF {
             Base::deallocateBuffer(bufferToDeallocate);
         }
         
+        void swap(VectorBuffer<T, inlineCapacity>& other)
+        {
+            if (buffer() == inlineBuffer() && other.buffer() == other.inlineBuffer()) {
+                WTF::swap(m_inlineBuffer, other.m_inlineBuffer);
+                std::swap(m_capacity, other.m_capacity);
+            } else if (buffer() == inlineBuffer()) {
+                m_buffer = other.m_buffer;
+                other.m_buffer = other.inlineBuffer();
+                WTF::swap(m_inlineBuffer, other.m_inlineBuffer);
+                std::swap(m_capacity, other.m_capacity);
+            } else if (other.buffer() == other.inlineBuffer()) {
+                other.m_buffer = m_buffer;
+                m_buffer = inlineBuffer();
+                WTF::swap(m_inlineBuffer, other.m_inlineBuffer);
+                std::swap(m_capacity, other.m_capacity);
+            } else {
+                std::swap(m_buffer, other.m_buffer);
+                std::swap(m_capacity, other.m_capacity);
+            }
+        }
+
         void restoreInlineBufferIfNeeded()
         {
             if (m_buffer)
diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index 2138ca7..d6246db 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,34 @@
+2009-09-23  Geoffrey Garen  <ggaren at apple.com>
+
+        Reviewed by Sam Weinig.
+
+        Layout tests for event target sanitization.
+        
+        New tests for event dispatch:
+
+        * fast/events/event-attributes-after-exception-expected.txt: Added.
+        * fast/events/event-attributes-after-exception.html: Added.
+        * fast/events/event-fire-order-expected.txt: Added.
+        * fast/events/event-fire-order.html: Added.
+        * fast/events/event-fired-after-removal-expected.txt: Added.
+        * fast/events/event-fired-after-removal.html: Added.
+        
+        Fixed these tests:
+
+        * fast/xmlhttprequest/xmlhttprequest-get-expected.txt: eventPhase should
+        be AT_TARGET (2) when firing an event on an XHR, not INVALID (0).
+        * http/tests/xmlhttprequest/infoOnProgressEvent-expected.txt: ditto
+
+        * http/tests/xmlhttprequest/event-target-expected.txt:
+        * http/tests/xmlhttprequest/event-target.html: Removing an event listener
+        during event dispatch should prevent it from firing. (This test was backwards.)
+        
+        * svg/custom/loadevents-capturing.svg: Enhanced this test to tell you
+        why it fails when it fails. Changed it to register runTest() (now named 
+        reportResults()) using addEventListener() instead of the 'onload' attribute.
+        The test relies on reportResults() running after handler(), so it needs
+        to register reportResults() after handler().
+
 2009-09-23  Karen Grünberg  <karen+webkit at chromium.org>
 
         Reviewed by Eric Seidel.
diff --git a/LayoutTests/fast/events/event-attributes-after-exception-expected.txt b/LayoutTests/fast/events/event-attributes-after-exception-expected.txt
new file mode 100644
index 0000000..99ef436
--- /dev/null
+++ b/LayoutTests/fast/events/event-attributes-after-exception-expected.txt
@@ -0,0 +1,9 @@
+This page tests various event attributes after dispatchEvent throws an exception.
+
+If the test passes, you'll see a series of PASS messages below.
+
+PASS: event.target should be null and is.
+PASS: event.currentTarget should be null and is.
+PASS: event.relatedTarget should be null and is.
+PASS: event.eventPhase should be 0 and is.
+
diff --git a/LayoutTests/fast/events/event-attributes-after-exception.html b/LayoutTests/fast/events/event-attributes-after-exception.html
new file mode 100644
index 0000000..94117f7
--- /dev/null
+++ b/LayoutTests/fast/events/event-attributes-after-exception.html
@@ -0,0 +1,37 @@
+<p>This page tests various event attributes after dispatchEvent throws an exception.</p>
+<p>If the test passes, you'll see a series of PASS messages below.</p>
+
+<pre id="console"></pre>
+
+<script>
+if (window.layoutTestController)
+    layoutTestController.dumpAsText();
+
+function log(s)
+{
+    document.getElementById("console").appendChild(document.createTextNode(s + "\n"));
+}
+
+function shouldBe(aDescription, a, b)
+{
+    if (a == b) {
+        log("PASS: " + aDescription + " should be " + b + " and is.");
+        return;
+    }
+    log("FAIL: " + aDescription + " should be " + b + " but instead is " + a + ".");
+}
+
+window.onload = function()
+{
+    var event = document.createEvent("MouseEvent");
+    try {
+        document.getElementById("console").dispatchEvent(event);
+    } catch (e) {
+    } finally {
+        shouldBe("event.target", event.target, null);
+        shouldBe("event.currentTarget", event.currentTarget, null);
+        shouldBe("event.relatedTarget", event.relatedTarget, null);
+        shouldBe("event.eventPhase", event.eventPhase, 0);
+    }
+};
+</script>
diff --git a/LayoutTests/fast/events/event-fire-order-expected.txt b/LayoutTests/fast/events/event-fire-order-expected.txt
new file mode 100644
index 0000000..e25895d
--- /dev/null
+++ b/LayoutTests/fast/events/event-fire-order-expected.txt
@@ -0,0 +1,8 @@
+This page tests event listener fire order for a few objects that had it wrong in the past.
+
+If the test passes, you'll see a series of PASS messages below.
+
+PASS: result should be f1,f2 and is.
+PASS: result should be f1,f2 and is.
+PASS: result should be f1,f2 and is.
+
diff --git a/LayoutTests/fast/events/event-fire-order.html b/LayoutTests/fast/events/event-fire-order.html
new file mode 100644
index 0000000..26a322c
--- /dev/null
+++ b/LayoutTests/fast/events/event-fire-order.html
@@ -0,0 +1,106 @@
+<p>This page tests event listener fire order for a few objects that had it wrong in the past.</p>
+<p>If the test passes, you'll see a series of PASS messages below.</p>
+
+<pre id="console"></pre>
+
+<div id="div"></div>
+
+<script>
+if (window.layoutTestController)
+    layoutTestController.dumpAsText();
+
+function log(s)
+{
+    document.getElementById("console").appendChild(document.createTextNode(s + "\n"));
+}
+
+var result;
+
+function reset()
+{
+    result = [ ];
+}
+
+function f1()
+{
+    result.push("f1");
+}
+
+function f2(event)
+{
+    result.push("f2");
+    event.target.removeEventListener(event.type, f3, false); // Removed: should not fire.
+    event.target.addEventListener(event.type, f4, false); // Added after dispatch began: should not fire.
+}
+
+function f3()
+{
+    result.push("f3");
+}
+
+function f4()
+{
+    result.push("f4");
+}
+
+function reportResult(name, expected)
+{
+    var passed = true;
+    var end = result.length > expected.length ? result.length : expected.length;
+    for (var i = 0; i < end; ++i) {
+        if (result[i] != expected[i]) {
+            log("FAIL: " + name + " result[" + i + "] should be " + expected[i] + " but instead is " + result[i] + ".");
+            passed = false;
+        }
+    }
+    if (passed)
+        log("PASS: result should be " + expected + " and is.");
+}
+
+var tests = [
+    function testDiv()
+    {
+        reset();
+        var x = document.getElementById("div");
+        x.addEventListener("click", f1, false);
+        x.onclick = f2;
+        x.addEventListener("click", f3, false);
+
+        var event = document.createEvent("MouseEvent");
+        event.initMouseEvent("click", true, true, document.defaultView, 1, 0, 0, 0, 0, false, false, false, false, 0, document);
+        x.dispatchEvent(event);
+
+        reportResult(arguments.callee.name, [ "f1", "f2" ]);
+    },
+
+    function testXHR()
+    {
+        reset();
+        var x = new XMLHttpRequest;
+        x.addEventListener("readystatechange", f1, false);
+        x.onreadystatechange = f2;
+        x.addEventListener("readystatechange", f3, false);
+
+        x.open("GET", "resources/does-not-exist");
+
+        reportResult(arguments.callee.name, [ "f1", "f2" ]);
+    },
+
+    function testXHRUpload()
+    {
+        reset();
+        var x = new XMLHttpRequest;
+        x.upload.addEventListener("abort", f1, false);
+        x.upload.onabort = f2;
+        x.upload.addEventListener("abort", f3, false);
+
+        x.open("POST", "resources/does-not-exist");
+        x.abort();
+
+        reportResult(arguments.callee.name, [ "f1", "f2" ]);
+    }
+];
+
+for (var i = 0; i < tests.length; ++i)
+    tests[i]();
+</script>
diff --git a/LayoutTests/fast/events/event-fired-after-removal-expected.txt b/LayoutTests/fast/events/event-fired-after-removal-expected.txt
new file mode 100644
index 0000000..01fe76a
--- /dev/null
+++ b/LayoutTests/fast/events/event-fired-after-removal-expected.txt
@@ -0,0 +1,6 @@
+This page verifies that queued event listeners keep firing even after a node has been removed from the document.
+
+If the test passes, you'll see a PASS message below.
+
+PASS: result should be f1,f2 and is.
+
diff --git a/LayoutTests/fast/events/event-fired-after-removal.html b/LayoutTests/fast/events/event-fired-after-removal.html
new file mode 100644
index 0000000..087d45f
--- /dev/null
+++ b/LayoutTests/fast/events/event-fired-after-removal.html
@@ -0,0 +1,48 @@
+<p>This page verifies that queued event listeners keep firing even after a node has been removed from the document.</p>
+<p>If the test passes, you'll see a PASS message below.</p>
+
+<pre id="console"></pre>
+
+<div id="div"></div>
+
+<script>
+if (window.layoutTestController)
+    layoutTestController.dumpAsText();
+
+function log(s)
+{
+    document.getElementById("console").appendChild(document.createTextNode(s + "\n"));
+}
+
+var result = [ ];
+
+function reportResult(expected)
+{
+    var passed = true;
+    var end = result.length > expected.length ? result.length : expected.length;
+    for (var i = 0; i < end; ++i) {
+        if (result[i] != expected[i]) {
+            log("FAIL: " + name + " result[" + i + "] should be " + expected[i] + " but instead is " + result[i] + ".");
+            passed = false;
+        }
+    }
+    if (passed)
+        log("PASS: result should be " + expected + " and is.");
+}
+
+var div = document.getElementById("div");
+div.addEventListener("click", function f1() {
+    result.push(arguments.callee.name);
+    div.parentNode.removeChild(div);
+}, false);
+
+div.addEventListener("click", function f2() {
+    result.push(arguments.callee.name);
+}, false);
+
+var event = document.createEvent("MouseEvent");
+event.initMouseEvent("click", true, true, document.defaultView, 1, 0, 0, 0, 0, false, false, false, false, 0, document);
+div.dispatchEvent(event);
+
+reportResult([ "f1", "f2" ]);
+</script>
diff --git a/LayoutTests/fast/xmlhttprequest/xmlhttprequest-get-expected.txt b/LayoutTests/fast/xmlhttprequest/xmlhttprequest-get-expected.txt
index a345887..06a0026 100644
--- a/LayoutTests/fast/xmlhttprequest/xmlhttprequest-get-expected.txt
+++ b/LayoutTests/fast/xmlhttprequest/xmlhttprequest-get-expected.txt
@@ -47,7 +47,7 @@ cancelBubble : 'false'
 cancelable : 'true'
 clipboardData : 'undefined'
 currentTarget : '[object XMLHttpRequest]'
-eventPhase : '0'
+eventPhase : '2'
 initEvent : 'function initEvent() {
     [native code]
 }'
diff --git a/LayoutTests/http/tests/xmlhttprequest/event-target-expected.txt b/LayoutTests/http/tests/xmlhttprequest/event-target-expected.txt
index 8b93f7b..7e6a0d7 100644
--- a/LayoutTests/http/tests/xmlhttprequest/event-target-expected.txt
+++ b/LayoutTests/http/tests/xmlhttprequest/event-target-expected.txt
@@ -4,7 +4,6 @@ fooListener: this = [object XMLHttpRequest]
 onload: this = [object XMLHttpRequest]
 eventListener: this = [object XMLHttpRequest]
 eventListener2: this = [object XMLHttpRequest]
-eventListener3: this = [object XMLHttpRequest]
 onload: this = [object XMLHttpRequest]
 eventListener: this = [object XMLHttpRequest]
 eventListener2: this = [object XMLHttpRequest]
diff --git a/LayoutTests/http/tests/xmlhttprequest/event-target.html b/LayoutTests/http/tests/xmlhttprequest/event-target.html
index 5b38d8a..28285e0 100644
--- a/LayoutTests/http/tests/xmlhttprequest/event-target.html
+++ b/LayoutTests/http/tests/xmlhttprequest/event-target.html
@@ -26,13 +26,13 @@ XMLHttpRequest should be an EventTarget.</p>
 
     function eventListener2() {
         log("eventListener2: this = " + this);
-        // It is too late to remove this listener, so it will still fire.
+        // Removing this event listener should prevent it from firing.
         req.removeEventListener("load", eventListener3, false);
     }
 
     function eventListener3() { log("eventListener3: this = " + this); }
     
-    // This one is removed just in time to be really removed.
+    // This listener is removed before it gets a chance to fire.
     function eventListener4() { log("eventListener4: this = " + this); }
 
     function fooListener() { log("fooListener: this = " + this); }
diff --git a/LayoutTests/http/tests/xmlhttprequest/infoOnProgressEvent-expected.txt b/LayoutTests/http/tests/xmlhttprequest/infoOnProgressEvent-expected.txt
index 44b62ee..0084597 100644
--- a/LayoutTests/http/tests/xmlhttprequest/infoOnProgressEvent-expected.txt
+++ b/LayoutTests/http/tests/xmlhttprequest/infoOnProgressEvent-expected.txt
@@ -6,7 +6,7 @@ Synchronous case:
 Type: progress
 Bubble: false
 Cancelable: true
-EventPhase: 0
+EventPhase: 2
 Target: [object XMLHttpRequest]
 Current target: [object XMLHttpRequest]
 
@@ -14,7 +14,7 @@ Asynchronous case:
 Type: progress
 Bubble: false
 Cancelable: true
-EventPhase: 0
+EventPhase: 2
 Target: [object XMLHttpRequest]
 Current target: [object XMLHttpRequest]
 
diff --git a/LayoutTests/svg/custom/loadevents-capturing.svg b/LayoutTests/svg/custom/loadevents-capturing.svg
index faff677..681f87e 100644
--- a/LayoutTests/svg/custom/loadevents-capturing.svg
+++ b/LayoutTests/svg/custom/loadevents-capturing.svg
@@ -1,30 +1,29 @@
-<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" onload="runTest();">
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
   <script>
     <![CDATA[
       if (window.layoutTestController)
         layoutTestController.dumpAsText();
 
-      function handler(event) {
+      var results = [ ];
+      function handler(event)
+      {
         results.push(event.target.localName);
       }
+      document.documentElement.addEventListener('load', handler, true);
 
-      var results = new Array();
-
-      var test = document.documentElement;
-      test.addEventListener('load', handler, true);
-
-      function runTest()
+      function reportResults()
       {
-        var test = document.getElementById("console");
-        if ( results.length != 6 || results[0] != "image" ||
-             results[1] != "text" || results[2] != "text" ||
-             results[3] != "text" || results[4] != "g" ||
-             results[5] != "svg") {
-          test.appendChild(document.createTextNode("Failed"));
-        } else {
-          test.appendChild(document.createTextNode("Passed"));
+        var console = document.getElementById("console");
+        var expected = [ "image", "text", "text", "text", "g", "svg" ];
+        for (var i = 0; i < expected.length; ++i) {
+            if (results[i] != expected[i]) {
+              console.appendChild(document.createTextNode("FAIL: " + i + " should be " + expected[i] + " but instead is " + results[i] + ".\n"));
+              return;
+            }
         }
+        console.appendChild(document.createTextNode("Passed"));
       }
+      document.documentElement.addEventListener('load', reportResults);
     ]]>
   </script>
   <g>
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 28b3d4c..3cdc68f 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,406 @@
+2009-09-23  Geoffrey Garen  <ggaren at apple.com>
+
+        Reviewed by Sam Weinig.
+
+        Bring a little sanity to this crazy EventTarget world of ours
+        https://bugs.webkit.org/show_bug.cgi?id=29701
+
+        Lots of EventTarget refactoring to achieve a single shared implementation
+        that fixes some of the performance and correctness bugs of the many individual
+        implementations, and makes reasoning about EventTargets and EventListeners
+        much easier.
+        
+        The basic design is this:
+            - EventTarget manages a set of EventListeners.
+            - onXXX EventListener attributes forward to standard EventTarget APIs.
+            - Since the onXXX code is repetitive, it is usually done with macros
+              of the form DEFINE_ATTRIBUTE_EVENT_LISTENER(attributeName).
+            - EventTarget provides a shared implementation of dispatchEvent,
+              which subclasses with special event dispatch rules, like Node, override.
+            - To support Node, which lazily instantiates its EventTarget data,
+              EventTarget has no data members, and instead makes a virtual call
+              to get its data from wherever its subclass chose to store it.
+              
+        Code that used to call dispatchEvent, passing an ExceptionCode paratmeter,
+        even though no exception could be thrown, has been changed not to do so,
+        to improve clarity and performance.
+        
+        Code that used to call a special dispatchXXXEvent function, which just
+        turned around and called dispatchEvent, has been changed to call
+        dispatchEvent, to improve clarity and performance.
+
+        * WebCore.base.exp:
+        * WebCore.xcodeproj/project.pbxproj: Another day in the life of a WebKit
+        engineer.
+
+        * bindings/js/JSDOMBinding.cpp:
+        (WebCore::isObservableThroughDOM): Updated for Node API change. Added
+        "is not in the document but is firing event listeners" as a condition
+        that makes a Node observable in the DOM, so that event listeners firing
+        on removed nodes are not destroyed midstream. (This was a long-standing
+        bug that was somewhat hidden by the old implementation's habit of
+        copying the RegisteredEventListener vector before firing events, which
+        would keep almost all the relevant objects from being destroyed.)
+
+        * bindings/js/JSEventListener.cpp:
+        (WebCore::JSEventListener::handleEvent): Removed the isWindowEvent flag
+        because it was one of the most elaborately planned no-ops in the history
+        of software crime, and one of the reasons clients thought they needed more
+        than one dispatchEvent function even though they didn't.
+        * bindings/js/JSEventListener.h:
+
+        * bindings/js/JSDOMWindowCustom.cpp:
+        (WebCore::JSDOMWindow::markChildren):
+        (WebCore::JSMessagePort::markChildren):
+        * bindings/js/JSNodeCustom.cpp:
+        (WebCore::JSNode::markChildren):
+        * bindings/js/JSAbstractWorkerCustom.cpp:
+        * bindings/js/JSDOMApplicationCacheCustom.cpp:
+        * bindings/js/JSDedicatedWorkerContextCustom.cpp:
+        * bindings/js/JSEventSourceCustom.cpp:
+        * bindings/js/JSMessagePortCustom.cpp:
+        * bindings/js/JSSharedWorkerContextCustom.cpp: Removed.
+        * bindings/js/JSWebSocketCustom.cpp:
+        * bindings/js/JSWorkerContextCustom.cpp:
+        (WebCore::JSWorkerContext::markChildren):
+        * bindings/js/JSWorkerCustom.cpp:
+        * bindings/js/JSXMLHttpRequestCustom.cpp:
+        (WebCore::JSXMLHttpRequest::markChildren):
+        * bindings/js/JSXMLHttpRequestUploadCustom.cpp:
+        (WebCore::JSXMLHttpRequestUpload::markChildren): EventListener marking is
+        now autogenerated. Classes that still have custom mark functions for other
+        reasons now call a shared EventTarget API to mark their EventListeners.
+
+        * bindings/objc/ObjCEventListener.h:
+        * bindings/objc/ObjCEventListener.mm:
+        (WebCore::ObjCEventListener::handleEvent): Bye bye isWindowEvent.
+
+        * bindings/scripts/CodeGeneratorJS.pm: Autogeneration support for
+        marking and invalidating event listeners.
+
+        * dom/CharacterData.cpp:
+        (WebCore::CharacterData::dispatchModifiedEvent):
+        * dom/ContainerNode.cpp:
+        (WebCore::ContainerNode::insertBefore):
+        (WebCore::ContainerNode::replaceChild):
+        (WebCore::willRemoveChild):
+        (WebCore::ContainerNode::appendChild):
+        (WebCore::dispatchChildInsertionEvents):
+        (WebCore::dispatchChildRemovalEvents):
+        * dom/Document.cpp:
+        (WebCore::Document::removeAllEventListeners):
+        (WebCore::Document::implicitClose):
+        (WebCore::Document::setFocusedNode):
+        (WebCore::Document::dispatchWindowEvent):
+        (WebCore::Document::dispatchWindowLoadEvent):
+        (WebCore::Document::finishedParsing):
+        * dom/Document.h: Use dispatchEvent directly.
+
+        * dom/Element.h: Moved a few event listener attributes down from Node,
+        since they don't apply to all Nodes, only Elements.
+
+        * dom/EventListener.h: Removed isWindowEvent parameter.
+
+        * dom/EventNames.h: Added the "display" event name, so it works correctly
+        with attribute macros, and for performance.
+
+        * dom/EventTarget.cpp:
+        (WebCore::forbidEventDispatch):
+        (WebCore::allowEventDispatch):
+        (WebCore::eventDispatchForbidden): Made this code (embarrasingly) thread
+        safe, since it's now called on multiple threads. (Currently, we only forbid
+        event dispatch on the main thread. If we ever want to forbid event dispatch
+        on secondary threads, we can improve it then.)
+
+        (WebCore::EventTarget::addEventListener):
+        (WebCore::EventTarget::removeEventListener):
+        (WebCore::EventTarget::setAttributeEventListener):
+        (WebCore::EventTarget::getAttributeEventListener):
+        (WebCore::EventTarget::clearAttributeEventListener):
+        (WebCore::EventTarget::dispatchEvent):
+        (WebCore::EventTarget::fireEventListeners):
+        (WebCore::EventTarget::getEventListeners):
+        (WebCore::EventTarget::removeAllEventListeners):
+        * dom/EventTarget.h:
+        (WebCore::FiringEventEndIterator::FiringEventEndIterator):
+        (WebCore::EventTarget::ref):
+        (WebCore::EventTarget::deref):
+        (WebCore::EventTarget::markEventListeners):
+        (WebCore::EventTarget::invalidateEventListeners):
+        (WebCore::EventTarget::isFiringEventListeners):
+        (WebCore::EventTarget::hasEventListeners): The ONE TRUE IMPLEMENTATION of
+        EventTarget APIs, crafted from an amalgam of all the different versions
+        we used to have. The most significant change here is that we no longer
+        make a copy of an EventListener vector before firing the events in the
+        vector -- instead, we use a reference to the original vector, along with
+        a notification mechanism for the unlikely case when an EventListener is
+        removed from the vector. This substantially reduces malloc, copying, and
+        refcount overhead, and complexity.
+
+        * dom/InputElement.cpp:
+        (WebCore::InputElement::setValueFromRenderer):
+        * dom/MessageEvent.h:
+        (WebCore::MessageEvent::create): Use dispatchEvent directly.
+
+        * dom/MessagePort.cpp:
+        (WebCore::MessagePort::dispatchMessages):
+        (WebCore::MessagePort::eventTargetData):
+        (WebCore::MessagePort::ensureEventTargetData):
+        * dom/MessagePort.h:
+        (WebCore::MessagePort::setOnmessage):
+        (WebCore::MessagePort::onmessage):
+        * dom/MessagePort.idl: Removed custom EventTarget implementation.
+
+        * dom/MutationEvent.h:
+        (WebCore::MutationEvent::create): Added some default values so callers
+        can construct MutationEvents more easily, without calling a custom dispatch
+        function.
+
+        * dom/Node.cpp:
+        (WebCore::Node::addEventListener):
+        (WebCore::Node::removeEventListener):
+        (WebCore::Node::eventTargetData):
+        (WebCore::Node::ensureEventTargetData):
+        (WebCore::Node::handleLocalEvents):
+        (WebCore::Node::dispatchEvent):
+        (WebCore::Node::dispatchGenericEvent):
+        (WebCore::Node::dispatchSubtreeModifiedEvent):
+        (WebCore::Node::dispatchUIEvent):
+        (WebCore::Node::dispatchKeyEvent):
+        (WebCore::Node::dispatchMouseEvent):
+        (WebCore::Node::dispatchWheelEvent):
+        (WebCore::Node::dispatchFocusEvent):
+        (WebCore::Node::dispatchBlurEvent):
+        * dom/Node.h:
+        (WebCore::Node::preDispatchEventHandler):
+        (WebCore::Node::postDispatchEventHandler):
+        * dom/Node.idl:
+        * dom/NodeRareData.h:
+        (WebCore::NodeRareData::eventTargetData):
+        (WebCore::NodeRareData::ensureEventTargetData): Use the shared EventTarget
+        interface, and call dispatchEvent directly instead of custom dispatchXXXEvent
+        functions that just forwarded to dispatchEvent.
+
+        * dom/RegisteredEventListener.cpp:
+        * dom/RegisteredEventListener.h:
+        (WebCore::RegisteredEventListener::RegisteredEventListener):
+        (WebCore::operator==): This is just a simple struct now, since we no longer
+        do a complicated copy / refCount / isRemoved dance just to honor the rule
+        that an EventListener can be removed during event dispatch.
+
+        * history/CachedFrame.cpp:
+        (WebCore::CachedFrameBase::restore): Removed another custom dispatchEvent.
+
+        * html/HTMLBodyElement.cpp:
+        * html/HTMLBodyElement.h: Use the shared EventTarget API.
+
+        * html/HTMLFormControlElement.cpp:
+        (WebCore::HTMLFormControlElement::dispatchFormControlChangeEvent):
+        (WebCore::HTMLFormControlElement::checkValidity):
+        * html/HTMLFormElement.cpp:
+        (WebCore::HTMLFormElement::handleLocalEvents):
+        (WebCore::HTMLFormElement::prepareSubmit):
+        (WebCore::HTMLFormElement::reset):
+        * html/HTMLFormElement.h: Use the standard dispatchEvent API.
+
+        * html/HTMLFrameSetElement.cpp:
+        * html/HTMLFrameSetElement.h: Use the shared EventTarget API.
+
+        * html/HTMLImageLoader.cpp:
+        (WebCore::HTMLImageLoader::dispatchLoadEvent):
+        * html/HTMLInputElement.cpp:
+        (WebCore::HTMLInputElement::onSearch):
+        * html/HTMLMediaElement.cpp:
+        (WebCore::HTMLMediaElement::loadInternal):
+        * html/HTMLScriptElement.cpp:
+        (WebCore::HTMLScriptElement::dispatchLoadEvent):
+        (WebCore::HTMLScriptElement::dispatchErrorEvent):
+        * html/HTMLSourceElement.cpp:
+        (WebCore::HTMLSourceElement::errorEventTimerFired):
+        * html/HTMLTokenizer.cpp:
+        (WebCore::HTMLTokenizer::notifyFinished): Use the standard dispatchEvent API.
+
+        * inspector/InspectorDOMAgent.cpp:
+        (WebCore::InspectorDOMAgent::handleEvent):
+        * inspector/InspectorDOMAgent.h:
+        * inspector/InspectorDOMStorageResource.cpp:
+        (WebCore::InspectorDOMStorageResource::handleEvent):
+        * inspector/InspectorDOMStorageResource.h:
+        * loader/FrameLoader.cpp:
+        (WebCore::FrameLoader::stopLoading):
+        (WebCore::FrameLoader::canCachePageContainingThisFrame):
+        (WebCore::FrameLoader::logCanCacheFrameDecision):
+        (WebCore::HashChangeEventTask::performTask):
+        (WebCore::FrameLoader::pageHidden): No more isWindowEvent.
+
+        * loader/ImageDocument.cpp:
+        (WebCore::ImageEventListener::handleEvent):
+        * loader/appcache/ApplicationCacheGroup.cpp:
+        (WebCore::CallCacheListenerTask::performTask):
+        * loader/appcache/ApplicationCacheHost.cpp:
+        (WebCore::ApplicationCacheHost::notifyDOMApplicationCache):
+        * loader/appcache/ApplicationCacheHost.h:
+        * loader/appcache/DOMApplicationCache.cpp:
+        (WebCore::DOMApplicationCache::eventTargetData):
+        (WebCore::DOMApplicationCache::ensureEventTargetData):
+        * loader/appcache/DOMApplicationCache.h:
+        * loader/appcache/DOMApplicationCache.idl: Switched to the standard
+        EventTarget API. As a part of this, I switched this class from using a
+        custom internal event name enumeration to using the standard EventNames.
+
+        * notifications/Notification.cpp:
+        (WebCore::Notification::eventTargetData):
+        (WebCore::Notification::ensureEventTargetData):
+        * notifications/Notification.h:
+        (WebCore::Notification::scriptExecutionContext):
+        * notifications/Notification.idl: Switched to the standard EventTarget API.
+
+        * page/DOMWindow.cpp:
+        (WebCore::PostMessageTimer::event):
+        (WebCore::windowsWithUnloadEventListeners):
+        (WebCore::windowsWithBeforeUnloadEventListeners):
+        (WebCore::allowsBeforeUnloadListeners):
+        (WebCore::DOMWindow::dispatchAllPendingBeforeUnloadEvents):
+        (WebCore::DOMWindow::pendingUnloadEventListeners):
+        (WebCore::DOMWindow::dispatchAllPendingUnloadEvents): Changed the "pending"
+        unload / beforeunload listener tracker just to track which windows had
+        such listeners, instead of actually keeping a copy of the listeners. Now,
+        this code can use the standard EventTarget API.
+
+        (WebCore::DOMWindow::~DOMWindow):
+        (WebCore::DOMWindow::postMessageTimerFired):
+        (WebCore::DOMWindow::addEventListener):
+        (WebCore::DOMWindow::removeEventListener):
+        (WebCore::DOMWindow::dispatchLoadEvent):
+        (WebCore::DOMWindow::dispatchEvent):
+        (WebCore::DOMWindow::removeAllEventListeners):
+        (WebCore::DOMWindow::captureEvents):
+        (WebCore::DOMWindow::releaseEvents):
+        (WebCore::DOMWindow::eventTargetData):
+        (WebCore::DOMWindow::ensureEventTargetData):
+        * page/DOMWindow.h:
+        * page/DOMWindow.idl: Use the standard EventTarget APIs.
+
+        * page/EventHandler.cpp:
+        (WebCore::EventHandler::canMouseDownStartSelect):
+        (WebCore::EventHandler::canMouseDragExtendSelect):
+        (WebCore::EventHandler::sendResizeEvent):
+        (WebCore::EventHandler::sendScrollEvent): Use dispatchEvent directly.
+
+        * page/EventSource.cpp:
+        (WebCore::EventSource::endRequest):
+        (WebCore::EventSource::didReceiveResponse):
+        (WebCore::EventSource::parseEventStreamLine):
+        (WebCore::EventSource::stop):
+        (WebCore::EventSource::createMessageEvent):
+        (WebCore::EventSource::eventTargetData):
+        (WebCore::EventSource::ensureEventTargetData):
+        * page/EventSource.h:
+        * page/EventSource.idl: Use the standard EventTarget APIs.
+
+        * page/FocusController.cpp:
+        (WebCore::dispatchEventsOnWindowAndFocusedNode):
+        (WebCore::FocusController::setFocusedFrame):
+        * page/Frame.cpp:
+        (WebCore::Frame::shouldClose):
+        * page/Frame.h:
+        * page/Page.cpp:
+        (WebCore::networkStateChanged):
+        * page/animation/AnimationController.cpp:
+        (WebCore::AnimationControllerPrivate::updateStyleIfNeededDispatcherFired):
+        * rendering/RenderListBox.cpp:
+        (WebCore::RenderListBox::valueChanged):
+        * rendering/RenderTextControl.cpp:
+        (WebCore::RenderTextControl::selectionChanged):
+        * rendering/RenderTextControlMultiLine.cpp:
+        (WebCore::RenderTextControlMultiLine::subtreeHasChanged): Use dispatchEvent.
+
+        * svg/SVGElement.cpp:
+        (WebCore::hasLoadListener): Rewritten for new EventTarget API.
+
+        * svg/SVGElementInstance.cpp:
+        (WebCore::dummyEventTargetData):
+        (WebCore::SVGElementInstance::addEventListener):
+        (WebCore::SVGElementInstance::removeEventListener):
+        (WebCore::SVGElementInstance::removeAllEventListeners):
+        (WebCore::SVGElementInstance::dispatchEvent):
+        (WebCore::SVGElementInstance::eventTargetData):
+        (WebCore::SVGElementInstance::ensureEventTargetData): Use the EventTarget API.
+
+        * svg/SVGElementInstance.h:
+        * svg/SVGImageLoader.cpp:
+        (WebCore::SVGImageLoader::dispatchLoadEvent):
+        * svg/SVGScriptElement.cpp:
+        (WebCore::SVGScriptElement::dispatchErrorEvent): Use dispatchEvent directly.
+
+        * svg/SVGUseElement.cpp:
+        (WebCore::SVGUseElement::transferEventListenersToShadowTree): Updated for
+        new EventTarget API.
+
+        * svg/animation/SVGSMILElement.cpp:
+        (WebCore::ConditionEventListener::handleEvent): No more isWindowEvent.
+
+        * websockets/WebSocket.cpp:
+        (WebCore::ProcessWebSocketEventTask::create):
+        (WebCore::ProcessWebSocketEventTask::performTask):
+        (WebCore::ProcessWebSocketEventTask::ProcessWebSocketEventTask):
+        (WebCore::WebSocket::didConnect):
+        (WebCore::WebSocket::didReceiveMessage):
+        (WebCore::WebSocket::didClose):
+        (WebCore::WebSocket::eventTargetData):
+        (WebCore::WebSocket::ensureEventTargetData):
+        * websockets/WebSocket.h:
+        * websockets/WebSocket.idl:
+        * workers/AbstractWorker.cpp:
+        (WebCore::AbstractWorker::eventTargetData):
+        (WebCore::AbstractWorker::ensureEventTargetData):
+        * workers/AbstractWorker.h:
+        * workers/AbstractWorker.idl:
+        * workers/DedicatedWorkerContext.cpp:
+        * workers/DedicatedWorkerContext.h:
+        * workers/DedicatedWorkerContext.idl:
+        * workers/DefaultSharedWorkerRepository.cpp:
+        (WebCore::SharedWorkerConnectTask::performTask):
+        (WebCore::SharedWorkerScriptLoader::load):
+        (WebCore::SharedWorkerScriptLoader::notifyFinished):
+        * workers/SharedWorker.idl:
+        * workers/SharedWorkerContext.cpp:
+        (WebCore::createConnectEvent):
+        * workers/SharedWorkerContext.h:
+        * workers/SharedWorkerContext.idl:
+        * workers/Worker.cpp:
+        (WebCore::Worker::notifyFinished):
+        * workers/Worker.h:
+        * workers/Worker.idl:
+        * workers/WorkerContext.cpp:
+        (WebCore::WorkerContext::eventTargetData):
+        (WebCore::WorkerContext::ensureEventTargetData):
+        * workers/WorkerContext.h:
+        * workers/WorkerContext.idl:
+        * workers/WorkerMessagingProxy.cpp:
+        (WebCore::MessageWorkerContextTask::performTask):
+        (WebCore::MessageWorkerTask::performTask):
+        (WebCore::WorkerExceptionTask::performTask):
+        * xml/XMLHttpRequest.cpp:
+        (WebCore::XMLHttpRequest::callReadyStateChangeListener):
+        (WebCore::XMLHttpRequest::createRequest):
+        (WebCore::XMLHttpRequest::abort):
+        (WebCore::XMLHttpRequest::networkError):
+        (WebCore::XMLHttpRequest::abortError):
+        (WebCore::XMLHttpRequest::didSendData):
+        (WebCore::XMLHttpRequest::didReceiveData):
+        (WebCore::XMLHttpRequest::eventTargetData):
+        (WebCore::XMLHttpRequest::ensureEventTargetData):
+        * xml/XMLHttpRequest.h:
+        * xml/XMLHttpRequest.idl:
+        * xml/XMLHttpRequestProgressEvent.h:
+        (WebCore::XMLHttpRequestProgressEvent::create):
+        * xml/XMLHttpRequestUpload.cpp:
+        (WebCore::XMLHttpRequestUpload::eventTargetData):
+        (WebCore::XMLHttpRequestUpload::ensureEventTargetData):
+        * xml/XMLHttpRequestUpload.h:
+        * xml/XMLHttpRequestUpload.idl: Use new EventTarget API.
+
 2009-09-23  Kent Tamura  <tkent at chromium.org>
 
         Reviewed by Darin Adler.
diff --git a/WebCore/WebCore.base.exp b/WebCore/WebCore.base.exp
index edfc208..a3bd728 100644
--- a/WebCore/WebCore.base.exp
+++ b/WebCore/WebCore.base.exp
@@ -494,7 +494,7 @@ __ZN7WebCore5Cache11setDisabledEb
 __ZN7WebCore5Cache13getStatisticsEv
 __ZN7WebCore5Cache13setCapacitiesEjjj
 __ZN7WebCore5Frame10findStringERKNS_6StringEbbbb
-__ZN7WebCore5Frame11shouldCloseEPN3WTF6VectorINS1_6RefPtrINS_23RegisteredEventListenerEEELm0EEE
+__ZN7WebCore5Frame11shouldCloseEv
 __ZN7WebCore5Frame13reapplyStylesEv
 __ZN7WebCore5Frame13setZoomFactorEfb
 __ZN7WebCore5Frame14frameForWidgetEPKNS_6WidgetE
@@ -656,7 +656,6 @@ __ZN7WebCore8Settings40setTextDirectionSubmenuInclusionBehaviorENS_37TextDirecti
 __ZN7WebCore8Settings41setNeedsKeyboardEventDisambiguationQuirksEb
 __ZN7WebCore8blankURLEv
 __ZN7WebCore8makeRGBAEiiii
-__ZN7WebCore9DOMWindow16hasEventListenerERKNS_12AtomicStringE
 __ZN7WebCore9DOMWindow30dispatchAllPendingUnloadEventsEv
 __ZN7WebCore9DOMWindow36dispatchAllPendingBeforeUnloadEventsEv
 __ZN7WebCore9FloatRectC1ERK7_NSRect
diff --git a/WebCore/WebCore.xcodeproj/project.pbxproj b/WebCore/WebCore.xcodeproj/project.pbxproj
index d70de2b..38e3c1d 100644
--- a/WebCore/WebCore.xcodeproj/project.pbxproj
+++ b/WebCore/WebCore.xcodeproj/project.pbxproj
@@ -680,7 +680,6 @@
 		412A68470F6B03DD000EA66E /* ScriptObjectQuarantine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 412A68460F6B03DD000EA66E /* ScriptObjectQuarantine.cpp */; };
 		415B7C570FF598E6006770F7 /* JSAbstractWorkerCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 415B7C540FF598E6006770F7 /* JSAbstractWorkerCustom.cpp */; };
 		415B7C580FF598E6006770F7 /* JSSharedWorkerConstructor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 415B7C550FF598E6006770F7 /* JSSharedWorkerConstructor.cpp */; };
-		415B7C590FF598E6006770F7 /* JSSharedWorkerCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 415B7C560FF598E6006770F7 /* JSSharedWorkerCustom.cpp */; };
 		415B7C630FF5A767006770F7 /* JSSharedWorkerConstructor.h in Headers */ = {isa = PBXBuildFile; fileRef = 415B7C620FF5A767006770F7 /* JSSharedWorkerConstructor.h */; };
 		4162A450101145AE00DFF3ED /* DedicatedWorkerContext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4162A44D101145AE00DFF3ED /* DedicatedWorkerContext.cpp */; };
 		4162A451101145AE00DFF3ED /* DedicatedWorkerContext.h in Headers */ = {isa = PBXBuildFile; fileRef = 4162A44E101145AE00DFF3ED /* DedicatedWorkerContext.h */; };
@@ -714,7 +713,6 @@
 		41D168EA10226E89009BC827 /* SharedWorkerRepository.h in Headers */ = {isa = PBXBuildFile; fileRef = 41D168E210226E89009BC827 /* SharedWorkerRepository.h */; };
 		41D168ED10226E89009BC827 /* SharedWorkerThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 41D168E510226E89009BC827 /* SharedWorkerThread.cpp */; };
 		41D168EE10226E89009BC827 /* SharedWorkerThread.h in Headers */ = {isa = PBXBuildFile; fileRef = 41D168E610226E89009BC827 /* SharedWorkerThread.h */; };
-		41D168F010226EC4009BC827 /* JSSharedWorkerContextCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 41D168EF10226EC4009BC827 /* JSSharedWorkerContextCustom.cpp */; };
 		41D1690510238B66009BC827 /* JSSharedWorkerContext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 41D1690310238B66009BC827 /* JSSharedWorkerContext.cpp */; };
 		41D1690610238B66009BC827 /* JSSharedWorkerContext.h in Headers */ = {isa = PBXBuildFile; fileRef = 41D1690410238B66009BC827 /* JSSharedWorkerContext.h */; };
 		41E1B1D00FF5986900576B3B /* AbstractWorker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 41E1B1CA0FF5986900576B3B /* AbstractWorker.cpp */; };
@@ -5840,7 +5838,6 @@
 		412A68460F6B03DD000EA66E /* ScriptObjectQuarantine.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScriptObjectQuarantine.cpp; sourceTree = "<group>"; };
 		415B7C540FF598E6006770F7 /* JSAbstractWorkerCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSAbstractWorkerCustom.cpp; sourceTree = "<group>"; };
 		415B7C550FF598E6006770F7 /* JSSharedWorkerConstructor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSSharedWorkerConstructor.cpp; sourceTree = "<group>"; };
-		415B7C560FF598E6006770F7 /* JSSharedWorkerCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSSharedWorkerCustom.cpp; sourceTree = "<group>"; };
 		415B7C620FF5A767006770F7 /* JSSharedWorkerConstructor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSSharedWorkerConstructor.h; sourceTree = "<group>"; };
 		4162A44D101145AE00DFF3ED /* DedicatedWorkerContext.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DedicatedWorkerContext.cpp; path = workers/DedicatedWorkerContext.cpp; sourceTree = "<group>"; };
 		4162A44E101145AE00DFF3ED /* DedicatedWorkerContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DedicatedWorkerContext.h; path = workers/DedicatedWorkerContext.h; sourceTree = "<group>"; };
@@ -5876,7 +5873,6 @@
 		41D168E210226E89009BC827 /* SharedWorkerRepository.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SharedWorkerRepository.h; path = workers/SharedWorkerRepository.h; sourceTree = "<group>"; };
 		41D168E510226E89009BC827 /* SharedWorkerThread.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SharedWorkerThread.cpp; path = workers/SharedWorkerThread.cpp; sourceTree = "<group>"; };
 		41D168E610226E89009BC827 /* SharedWorkerThread.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SharedWorkerThread.h; path = workers/SharedWorkerThread.h; sourceTree = "<group>"; };
-		41D168EF10226EC4009BC827 /* JSSharedWorkerContextCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSSharedWorkerContextCustom.cpp; sourceTree = "<group>"; };
 		41D1690310238B66009BC827 /* JSSharedWorkerContext.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSSharedWorkerContext.cpp; sourceTree = "<group>"; };
 		41D1690410238B66009BC827 /* JSSharedWorkerContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSSharedWorkerContext.h; sourceTree = "<group>"; };
 		41E1B1CA0FF5986900576B3B /* AbstractWorker.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AbstractWorker.cpp; path = workers/AbstractWorker.cpp; sourceTree = "<group>"; };
@@ -14137,6 +14133,8 @@
 				93B70D5009EB0C7C009D8468 /* JSPluginElementFunctions.h */,
 				C09158880DB4209200E55AF4 /* JSQuarantinedObjectWrapper.cpp */,
 				C09158890DB4209200E55AF4 /* JSQuarantinedObjectWrapper.h */,
+				415B7C550FF598E6006770F7 /* JSSharedWorkerConstructor.cpp */,
+				415B7C620FF5A767006770F7 /* JSSharedWorkerConstructor.h */,
 				B21127A50B3186770009BE53 /* JSSVGPODTypeWrapper.h */,
 				E1C36D320EB0A094007410BC /* JSWorkerContextBase.cpp */,
 				E1C36D330EB0A094007410BC /* JSWorkerContextBase.h */,
@@ -14245,6 +14243,28 @@
 				9392262E10321084006E7D5D /* JSCSSRuleListCustom.cpp */,
 				BC5825F20C0B89380053F1B5 /* JSCSSStyleDeclarationCustom.cpp */,
 				BC20FB7E0C0E8E6C00D1447F /* JSCSSValueCustom.cpp */,
+				FE80D7A20E9C1ED2000D6F75 /* JSCustomPositionCallback.cpp */,
+				FE80D7A30E9C1ED2000D6F75 /* JSCustomPositionCallback.h */,
+				FE80D7A40E9C1ED2000D6F75 /* JSCustomPositionErrorCallback.cpp */,
+				FE80D7A50E9C1ED2000D6F75 /* JSCustomPositionErrorCallback.h */,
+				51EC925B0CE90DD400F90308 /* JSCustomSQLStatementCallback.cpp */,
+				51EC925C0CE90DD400F90308 /* JSCustomSQLStatementCallback.h */,
+				51EC925D0CE90DD400F90308 /* JSCustomSQLStatementErrorCallback.cpp */,
+				51EC925E0CE90DD400F90308 /* JSCustomSQLStatementErrorCallback.h */,
+				51EC925F0CE90DD400F90308 /* JSCustomSQLTransactionCallback.cpp */,
+				51EC92600CE90DD400F90308 /* JSCustomSQLTransactionCallback.h */,
+				51EC92610CE90DD400F90308 /* JSCustomSQLTransactionErrorCallback.cpp */,
+				51EC92620CE90DD400F90308 /* JSCustomSQLTransactionErrorCallback.h */,
+				1A3417C80CECFF250049CBDE /* JSCustomVoidCallback.cpp */,
+				1A3417C70CECFF250049CBDE /* JSCustomVoidCallback.h */,
+				93BA59B10F2AA5FE008E8E99 /* JSCDATASectionCustom.cpp */,
+				BCA83E510D7CE205003421A8 /* JSClipboardCustom.cpp */,
+				C0DFC86F0DB6841A003EAE7C /* JSConsoleCustom.cpp */,
+				FE700DD00F92D81A008E2BFE /* JSCoordinatesCustom.cpp */,
+				BC46C1ED0C0DDBDF0020CFC3 /* JSCSSRuleCustom.cpp */,
+				9392262E10321084006E7D5D /* JSCSSRuleListCustom.cpp */,
+				BC5825F20C0B89380053F1B5 /* JSCSSStyleDeclarationCustom.cpp */,
+				BC20FB7E0C0E8E6C00D1447F /* JSCSSValueCustom.cpp */,
 				BCCE58AB1061E8CF008FB35A /* JSDatabaseCustom.cpp */,
 				BC77D1510FF19C730070887B /* JSDataGridColumnListCustom.cpp */,
 				4162A453101145E300DFF3ED /* JSDedicatedWorkerContextCustom.cpp */,
@@ -14292,8 +14312,6 @@
 				BCD9C2610C17AA67005C90A2 /* JSNodeListCustom.cpp */,
 				A9C6E64A0D7465E7006442E9 /* JSPluginArrayCustom.cpp */,
 				A9C6E64B0D7465E7006442E9 /* JSPluginCustom.cpp */,
-				41D168EF10226EC4009BC827 /* JSSharedWorkerContextCustom.cpp */,
-				415B7C560FF598E6006770F7 /* JSSharedWorkerCustom.cpp */,
 				51DCE8010CAC9F1C00488358 /* JSSQLResultSetRowListCustom.cpp */,
 				1AD2316D0CD269E700C1F194 /* JSSQLTransactionCustom.cpp */,
 				51D0C5150DAA90B7003B3831 /* JSStorageCustom.cpp */,
@@ -19031,8 +19049,6 @@
 				41D07A7E0FF935CA0095EDCE /* JSSharedWorker.cpp in Sources */,
 				415B7C580FF598E6006770F7 /* JSSharedWorkerConstructor.cpp in Sources */,
 				41D1690510238B66009BC827 /* JSSharedWorkerContext.cpp in Sources */,
-				41D168F010226EC4009BC827 /* JSSharedWorkerContextCustom.cpp in Sources */,
-				415B7C590FF598E6006770F7 /* JSSharedWorkerCustom.cpp in Sources */,
 				514C76370CE9225E007EF3CD /* JSSQLError.cpp in Sources */,
 				1AE82FEC0CAB07EE002237AE /* JSSQLResultSet.cpp in Sources */,
 				1AFE11990CBFFCC4003017FA /* JSSQLResultSetRowList.cpp in Sources */,
diff --git a/WebCore/bindings/js/JSAbstractWorkerCustom.cpp b/WebCore/bindings/js/JSAbstractWorkerCustom.cpp
index 475b374..aac1c63 100644
--- a/WebCore/bindings/js/JSAbstractWorkerCustom.cpp
+++ b/WebCore/bindings/js/JSAbstractWorkerCustom.cpp
@@ -44,21 +44,6 @@ using namespace JSC;
 
 namespace WebCore {
 
-void JSAbstractWorker::markChildren(MarkStack& markStack)
-{
-    Base::markChildren(markStack);
-
-    markIfNotNull(markStack, m_impl->onerror());
-
-    typedef AbstractWorker::EventListenersMap EventListenersMap;
-    typedef AbstractWorker::ListenerVector ListenerVector;
-    EventListenersMap& eventListeners = m_impl->eventListeners();
-    for (EventListenersMap::iterator mapIter = eventListeners.begin(); mapIter != eventListeners.end(); ++mapIter) {
-        for (ListenerVector::iterator vecIter = mapIter->second.begin(); vecIter != mapIter->second.end(); ++vecIter)
-            (*vecIter)->markJSFunction(markStack);
-    }
-}
-
 JSValue JSAbstractWorker::addEventListener(ExecState* exec, const ArgList& args)
 {
     JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(impl()->scriptExecutionContext());
diff --git a/WebCore/bindings/js/JSDOMApplicationCacheCustom.cpp b/WebCore/bindings/js/JSDOMApplicationCacheCustom.cpp
index b833e71..5855026 100644
--- a/WebCore/bindings/js/JSDOMApplicationCacheCustom.cpp
+++ b/WebCore/bindings/js/JSDOMApplicationCacheCustom.cpp
@@ -42,28 +42,6 @@ using namespace JSC;
 
 namespace WebCore {
 
-void JSDOMApplicationCache::markChildren(MarkStack& markStack)
-{
-    Base::markChildren(markStack);
-
-    markIfNotNull(markStack, m_impl->onchecking());
-    markIfNotNull(markStack, m_impl->onerror());
-    markIfNotNull(markStack, m_impl->onnoupdate());
-    markIfNotNull(markStack, m_impl->ondownloading());
-    markIfNotNull(markStack, m_impl->onprogress());
-    markIfNotNull(markStack, m_impl->onupdateready());
-    markIfNotNull(markStack, m_impl->oncached());
-    markIfNotNull(markStack, m_impl->onobsolete());
-
-    typedef DOMApplicationCache::EventListenersMap EventListenersMap;
-    typedef DOMApplicationCache::ListenerVector ListenerVector;
-    EventListenersMap& eventListeners = m_impl->eventListeners();
-    for (EventListenersMap::iterator mapIter = eventListeners.begin(); mapIter != eventListeners.end(); ++mapIter) {
-        for (ListenerVector::iterator vecIter = mapIter->second.begin(); vecIter != mapIter->second.end(); ++vecIter)
-            (*vecIter)->markJSFunction(markStack);
-    }
-}
-
 #if ENABLE(APPLICATION_CACHE_DYNAMIC_ENTRIES)
 
 JSValue JSDOMApplicationCache::hasItem(ExecState* exec, const ArgList& args)
diff --git a/WebCore/bindings/js/JSDOMBinding.cpp b/WebCore/bindings/js/JSDOMBinding.cpp
index 6550adb..1899797 100644
--- a/WebCore/bindings/js/JSDOMBinding.cpp
+++ b/WebCore/bindings/js/JSDOMBinding.cpp
@@ -275,7 +275,7 @@ static inline bool isObservableThroughDOM(JSNode* jsNode)
 
         // If a node is in the document, and has event listeners, its wrapper is
         // observable because its wrapper is responsible for marking those event listeners.
-        if (node->eventListeners().size())
+        if (node->hasEventListeners())
             return true; // Technically, we may overzealously mark a wrapper for a node that has only non-JS event listeners. Oh well.
 
         // If a node owns another object with a wrapper with custom properties,
@@ -323,6 +323,11 @@ static inline bool isObservableThroughDOM(JSNode* jsNode)
 #endif
     }
 
+    // If a node is firing event listeners, its wrapper is observable because
+    // its wrapper is responsible for marking those event listeners.
+    if (node->isFiringEventListeners())
+        return true;
+
     return false;
 }
 
diff --git a/WebCore/bindings/js/JSDOMWindowCustom.cpp b/WebCore/bindings/js/JSDOMWindowCustom.cpp
index 7217fc8..08c7144 100644
--- a/WebCore/bindings/js/JSDOMWindowCustom.cpp
+++ b/WebCore/bindings/js/JSDOMWindowCustom.cpp
@@ -94,7 +94,7 @@ void JSDOMWindow::markChildren(MarkStack& markStack)
 {
     Base::markChildren(markStack);
 
-    markEventListeners(markStack, impl()->eventListeners());
+    impl()->markEventListeners(markStack);
 
     JSGlobalData& globalData = *Heap::heap(this)->globalData();
 
diff --git a/WebCore/bindings/js/JSDedicatedWorkerContextCustom.cpp b/WebCore/bindings/js/JSDedicatedWorkerContextCustom.cpp
index a633a42..fbee5ef 100644
--- a/WebCore/bindings/js/JSDedicatedWorkerContextCustom.cpp
+++ b/WebCore/bindings/js/JSDedicatedWorkerContextCustom.cpp
@@ -42,13 +42,6 @@ using namespace JSC;
 
 namespace WebCore {
 
-void JSDedicatedWorkerContext::markChildren(MarkStack& markStack)
-{
-    Base::markChildren(markStack);
-
-    markIfNotNull(markStack, impl()->onmessage());
-}
-
 JSC::JSValue JSDedicatedWorkerContext::postMessage(JSC::ExecState* exec, const JSC::ArgList& args)
 {
     return handlePostMessage(exec, args, impl());
diff --git a/WebCore/bindings/js/JSEventListener.cpp b/WebCore/bindings/js/JSEventListener.cpp
index d391073..48ae014 100644
--- a/WebCore/bindings/js/JSEventListener.cpp
+++ b/WebCore/bindings/js/JSEventListener.cpp
@@ -56,7 +56,7 @@ void JSEventListener::markJSFunction(MarkStack& markStack)
     markStack.append(m_globalObject);
 }
 
-void JSEventListener::handleEvent(Event* event, bool isWindowEvent)
+void JSEventListener::handleEvent(Event* event)
 {
     JSLock lock(SilenceAssertionsOnly);
 
@@ -106,19 +106,10 @@ void JSEventListener::handleEvent(Event* event, bool isWindowEvent)
         JSGlobalData* globalData = globalObject->globalData();
         DynamicGlobalObjectScope globalObjectScope(exec, globalData->dynamicGlobalObject ? globalData->dynamicGlobalObject : globalObject);
 
-        JSValue retval;
-        if (handleEventFunction) {
-            globalData->timeoutChecker.start();
-            retval = call(exec, handleEventFunction, callType, callData, jsFunction, args);
-        } else {
-            JSValue thisValue;
-            if (isWindowEvent)
-                thisValue = globalObject->toThisObject(exec);
-            else
-                thisValue = toJS(exec, globalObject, event->currentTarget());
-            globalData->timeoutChecker.start();
-            retval = call(exec, jsFunction, callType, callData, thisValue, args);
-        }
+        globalData->timeoutChecker.start();
+        JSValue retval = handleEventFunction
+            ? call(exec, handleEventFunction, callType, callData, jsFunction, args)
+            : call(exec, jsFunction, callType, callData, toJS(exec, globalObject, event->currentTarget()), args);
         globalData->timeoutChecker.stop();
 
         globalObject->setCurrentEvent(savedEvent);
diff --git a/WebCore/bindings/js/JSEventListener.h b/WebCore/bindings/js/JSEventListener.h
index 92f0c41..91ceff7 100644
--- a/WebCore/bindings/js/JSEventListener.h
+++ b/WebCore/bindings/js/JSEventListener.h
@@ -53,7 +53,7 @@ namespace WebCore {
 
     private:
         virtual void markJSFunction(JSC::MarkStack&);
-        virtual void handleEvent(Event*, bool isWindowEvent);
+        virtual void handleEvent(Event*);
         virtual bool reportError(const String& message, const String& url, int lineNumber);
         virtual bool virtualisAttribute() const;
         void clearJSFunctionInline();
diff --git a/WebCore/bindings/js/JSEventSourceCustom.cpp b/WebCore/bindings/js/JSEventSourceCustom.cpp
index deebcb9..d757ef6 100644
--- a/WebCore/bindings/js/JSEventSourceCustom.cpp
+++ b/WebCore/bindings/js/JSEventSourceCustom.cpp
@@ -43,23 +43,6 @@ using namespace JSC;
 
 namespace WebCore {
 
-void JSEventSource::markChildren(MarkStack& markStack)
-{
-    DOMObject::markChildren(markStack);
-
-    markIfNotNull(markStack, m_impl->onopen());
-    markIfNotNull(markStack, m_impl->onmessage());
-    markIfNotNull(markStack, m_impl->onerror());
-
-    typedef EventSource::EventListenersMap EventListenersMap;
-    typedef EventSource::ListenerVector ListenerVector;
-    EventListenersMap& eventListeners = m_impl->eventListeners();
-    for (EventListenersMap::iterator mapIter = eventListeners.begin(); mapIter != eventListeners.end(); ++mapIter) {
-        for (ListenerVector::iterator vecIter = mapIter->second.begin(); vecIter != mapIter->second.end(); ++vecIter)
-            (*vecIter)->markJSFunction(markStack);
-    }
-}
-
 JSValue JSEventSource::addEventListener(ExecState* exec, const ArgList& args)
 {
     JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(impl()->scriptExecutionContext());
diff --git a/WebCore/bindings/js/JSMessagePortCustom.cpp b/WebCore/bindings/js/JSMessagePortCustom.cpp
index 8202d1a..2084905 100644
--- a/WebCore/bindings/js/JSMessagePortCustom.cpp
+++ b/WebCore/bindings/js/JSMessagePortCustom.cpp
@@ -45,8 +45,6 @@ void JSMessagePort::markChildren(MarkStack& markStack)
 {
     Base::markChildren(markStack);
 
-    markIfNotNull(markStack, m_impl->onmessage());
-
     // If we have a locally entangled port, we can directly mark it as reachable. Ports that are remotely entangled are marked in-use by markActiveObjectsForContext().
     if (MessagePort* entangledPort = m_impl->locallyEntangledPort()) {
         DOMObject* wrapper = getCachedDOMObjectWrapper(*Heap::heap(this)->globalData(), entangledPort);
@@ -54,13 +52,7 @@ void JSMessagePort::markChildren(MarkStack& markStack)
             markStack.append(wrapper);
     }
 
-    typedef MessagePort::EventListenersMap EventListenersMap;
-    typedef MessagePort::ListenerVector ListenerVector;
-    EventListenersMap& eventListeners = m_impl->eventListeners();
-    for (EventListenersMap::iterator mapIter = eventListeners.begin(); mapIter != eventListeners.end(); ++mapIter) {
-        for (ListenerVector::iterator vecIter = mapIter->second.begin(); vecIter != mapIter->second.end(); ++vecIter) 
-            (*vecIter)->markJSFunction(markStack);
-    }
+    m_impl->markEventListeners(markStack);
 }
 
 JSValue JSMessagePort::addEventListener(ExecState* exec, const ArgList& args)
diff --git a/WebCore/bindings/js/JSNodeCustom.cpp b/WebCore/bindings/js/JSNodeCustom.cpp
index e88a9ec..025a8fa 100644
--- a/WebCore/bindings/js/JSNodeCustom.cpp
+++ b/WebCore/bindings/js/JSNodeCustom.cpp
@@ -150,10 +150,10 @@ void JSNode::pushEventHandlerScope(ExecState*, ScopeChain&) const
 
 void JSNode::markChildren(MarkStack& markStack)
 {
-    Node* node = m_impl.get();
-
     Base::markChildren(markStack);
-    markEventListeners(markStack, node->eventListeners());
+
+    Node* node = m_impl.get();
+    node->markEventListeners(markStack);
 
     // Nodes in the document are kept alive by JSDocument::mark, so, if we're in
     // the document, we need to mark the document, but we don't need to explicitly
diff --git a/WebCore/bindings/js/JSSharedWorkerContextCustom.cpp b/WebCore/bindings/js/JSSharedWorkerContextCustom.cpp
deleted file mode 100644
index dca3536..0000000
--- a/WebCore/bindings/js/JSSharedWorkerContextCustom.cpp
+++ /dev/null
@@ -1,50 +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(SHARED_WORKERS)
-
-#include "JSSharedWorkerContext.h"
-
-using namespace JSC;
-
-namespace WebCore {
-
-void JSSharedWorkerContext::markChildren(MarkStack& markStack)
-{
-    Base::markChildren(markStack);
-
-    markIfNotNull(markStack, impl()->onconnect());
-}
-
-} // namespace WebCore
-
-#endif // ENABLE(SHARED_WORKERS)
diff --git a/WebCore/bindings/js/JSWebSocketCustom.cpp b/WebCore/bindings/js/JSWebSocketCustom.cpp
index 401b33d..d305502 100644
--- a/WebCore/bindings/js/JSWebSocketCustom.cpp
+++ b/WebCore/bindings/js/JSWebSocketCustom.cpp
@@ -44,14 +44,6 @@ using namespace JSC;
 
 namespace WebCore {
 
-void JSWebSocket::markChildren(MarkStack& markStack)
-{
-    Base::markChildren(markStack);
-    if (m_impl->readyState() != WebSocket::CLOSED)
-        markIfNotNull(markStack, m_impl->onmessage());
-    // FIXME: mark if EventListeners is registered.
-}
-
 // Custom functions
 JSValue JSWebSocket::send(ExecState* exec, const ArgList& args)
 {
diff --git a/WebCore/bindings/js/JSWorkerContextCustom.cpp b/WebCore/bindings/js/JSWorkerContextCustom.cpp
index 9e54fa0..1b78264 100644
--- a/WebCore/bindings/js/JSWorkerContextCustom.cpp
+++ b/WebCore/bindings/js/JSWorkerContextCustom.cpp
@@ -62,15 +62,7 @@ void JSWorkerContext::markChildren(MarkStack& markStack)
     markDOMObjectWrapper(markStack, globalData, impl()->optionalLocation());
     markDOMObjectWrapper(markStack, globalData, impl()->optionalNavigator());
 
-    markIfNotNull(markStack, impl()->onerror());
-
-    typedef WorkerContext::EventListenersMap EventListenersMap;
-    typedef WorkerContext::ListenerVector ListenerVector;
-    EventListenersMap& eventListeners = impl()->eventListeners();
-    for (EventListenersMap::iterator mapIter = eventListeners.begin(); mapIter != eventListeners.end(); ++mapIter) {
-        for (ListenerVector::iterator vecIter = mapIter->second.begin(); vecIter != mapIter->second.end(); ++vecIter)
-            (*vecIter)->markJSFunction(markStack);
-    }
+    impl()->markEventListeners(markStack);
 }
 
 bool JSWorkerContext::getOwnPropertySlotDelegate(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
diff --git a/WebCore/bindings/js/JSWorkerCustom.cpp b/WebCore/bindings/js/JSWorkerCustom.cpp
index a42a043..09b881a 100644
--- a/WebCore/bindings/js/JSWorkerCustom.cpp
+++ b/WebCore/bindings/js/JSWorkerCustom.cpp
@@ -37,13 +37,6 @@ using namespace JSC;
 
 namespace WebCore {
 
-void JSWorker::markChildren(MarkStack& markStack)
-{
-    Base::markChildren(markStack);
-
-    markIfNotNull(markStack, static_cast<Worker*>(impl())->onmessage());
-}
-
 JSC::JSValue JSWorker::postMessage(JSC::ExecState* exec, const JSC::ArgList& args)
 {
     return handlePostMessage(exec, args, impl());
diff --git a/WebCore/bindings/js/JSXMLHttpRequestCustom.cpp b/WebCore/bindings/js/JSXMLHttpRequestCustom.cpp
index c69f727..6d0ce57 100644
--- a/WebCore/bindings/js/JSXMLHttpRequestCustom.cpp
+++ b/WebCore/bindings/js/JSXMLHttpRequestCustom.cpp
@@ -59,20 +59,7 @@ void JSXMLHttpRequest::markChildren(MarkStack& markStack)
             markStack.append(wrapper);
     }
 
-    markIfNotNull(markStack, m_impl->onreadystatechange());
-    markIfNotNull(markStack, m_impl->onabort());
-    markIfNotNull(markStack, m_impl->onerror());
-    markIfNotNull(markStack, m_impl->onload());
-    markIfNotNull(markStack, m_impl->onloadstart());
-    markIfNotNull(markStack, m_impl->onprogress());
-    
-    typedef XMLHttpRequest::EventListenersMap EventListenersMap;
-    typedef XMLHttpRequest::ListenerVector ListenerVector;
-    EventListenersMap& eventListeners = m_impl->eventListeners();
-    for (EventListenersMap::iterator mapIter = eventListeners.begin(); mapIter != eventListeners.end(); ++mapIter) {
-        for (ListenerVector::iterator vecIter = mapIter->second.begin(); vecIter != mapIter->second.end(); ++vecIter)
-            (*vecIter)->markJSFunction(markStack);
-    }
+    m_impl->markEventListeners(markStack);
 }
 
 // Custom functions
diff --git a/WebCore/bindings/js/JSXMLHttpRequestUploadCustom.cpp b/WebCore/bindings/js/JSXMLHttpRequestUploadCustom.cpp
index 2f17542..c0f0c39 100644
--- a/WebCore/bindings/js/JSXMLHttpRequestUploadCustom.cpp
+++ b/WebCore/bindings/js/JSXMLHttpRequestUploadCustom.cpp
@@ -51,19 +51,7 @@ void JSXMLHttpRequestUpload::markChildren(MarkStack& markStack)
             markStack.append(wrapper);
     }
 
-    markIfNotNull(markStack, m_impl->onabort());
-    markIfNotNull(markStack, m_impl->onerror());
-    markIfNotNull(markStack, m_impl->onload());
-    markIfNotNull(markStack, m_impl->onloadstart());
-    markIfNotNull(markStack, m_impl->onprogress());
-    
-    typedef XMLHttpRequestUpload::EventListenersMap EventListenersMap;
-    typedef XMLHttpRequestUpload::ListenerVector ListenerVector;
-    EventListenersMap& eventListeners = m_impl->eventListeners();
-    for (EventListenersMap::iterator mapIter = eventListeners.begin(); mapIter != eventListeners.end(); ++mapIter) {
-        for (ListenerVector::iterator vecIter = mapIter->second.begin(); vecIter != mapIter->second.end(); ++vecIter)
-            (*vecIter)->markJSFunction(markStack);
-    }
+    m_impl->markEventListeners(markStack);
 }
 
 JSValue JSXMLHttpRequestUpload::addEventListener(ExecState* exec, const ArgList& args)
diff --git a/WebCore/bindings/objc/ObjCEventListener.h b/WebCore/bindings/objc/ObjCEventListener.h
index d0d883d..f5d8af8 100644
--- a/WebCore/bindings/objc/ObjCEventListener.h
+++ b/WebCore/bindings/objc/ObjCEventListener.h
@@ -54,7 +54,7 @@ namespace WebCore {
         ObjCEventListener(id <DOMEventListener>);
         virtual ~ObjCEventListener();
 
-        virtual void handleEvent(Event*, bool isWindowEvent);
+        virtual void handleEvent(Event*);
 
         id <DOMEventListener> m_listener;
     };
diff --git a/WebCore/bindings/objc/ObjCEventListener.mm b/WebCore/bindings/objc/ObjCEventListener.mm
index 4a23980..81b82f1 100644
--- a/WebCore/bindings/objc/ObjCEventListener.mm
+++ b/WebCore/bindings/objc/ObjCEventListener.mm
@@ -73,7 +73,7 @@ ObjCEventListener::~ObjCEventListener()
     [m_listener release];
 }
 
-void ObjCEventListener::handleEvent(Event* event, bool)
+void ObjCEventListener::handleEvent(Event* event)
 {
     [m_listener handleEvent:kit(event)];
 }
diff --git a/WebCore/bindings/scripts/CodeGeneratorJS.pm b/WebCore/bindings/scripts/CodeGeneratorJS.pm
index 56ae6e2..3523b43 100644
--- a/WebCore/bindings/scripts/CodeGeneratorJS.pm
+++ b/WebCore/bindings/scripts/CodeGeneratorJS.pm
@@ -476,7 +476,9 @@ sub GenerateHeader
     my $parentClassName = GetParentClassName($dataNode);
     my $conditional = $dataNode->extendedAttributes->{"Conditional"};
     my $needsSVGContext = IsSVGTypeNeedingContextParameter($interfaceName);
-
+    my $eventTarget = $dataNode->extendedAttributes->{"EventTarget"};
+    my $needsMarkChildren = $dataNode->extendedAttributes->{"CustomMarkFunction"} || $dataNode->extendedAttributes->{"EventTarget"};
+    
     # - Add default header template
     @headerContentHeader = split("\r", $headerTemplate);
 
@@ -548,7 +550,7 @@ sub GenerateHeader
     }
 
     # Destructor
-    push(@headerContent, "    virtual ~$className();\n") if (!$hasParent or $interfaceName eq "Document" or $interfaceName eq "DOMWindow");
+    push(@headerContent, "    virtual ~$className();\n") if (!$hasParent or $eventTarget or $interfaceName eq "Document" or $interfaceName eq "DOMWindow");
 
     # Prototype
     push(@headerContent, "    static JSC::JSObject* createPrototype(JSC::ExecState*, JSC::JSGlobalObject*);\n") unless ($dataNode->extendedAttributes->{"ExtendsDOMGlobalObject"});
@@ -613,8 +615,8 @@ sub GenerateHeader
             "    }\n\n");
     }
 
-    # Custom mark function
-    push(@headerContent, "    virtual void markChildren(JSC::MarkStack&);\n\n") if $dataNode->extendedAttributes->{"CustomMarkFunction"};
+    # markChildren function
+    push(@headerContent, "    virtual void markChildren(JSC::MarkStack&);\n\n") if $needsMarkChildren;
 
     # Custom pushEventHandlerScope function
     push(@headerContent, "    virtual void pushEventHandlerScope(JSC::ExecState*, JSC::ScopeChain&) const;\n\n") if $dataNode->extendedAttributes->{"CustomPushEventHandlerScope"};
@@ -789,7 +791,7 @@ sub GenerateHeader
         push(@headerContent,
             "    static PassRefPtr<JSC::Structure> createStructure(JSC::JSValue prototype)\n" .
             "    {\n" .
-            "        return JSC::Structure::create(prototype, JSC::TypeInfo(JSC::ObjectType" . ($dataNode->extendedAttributes->{"CustomMarkFunction"} ? "" : ", JSC::HasDefaultMark") . "));\n" .
+            "        return JSC::Structure::create(prototype, JSC::TypeInfo(JSC::ObjectType" . ($needsMarkChildren ? "" : ", JSC::HasDefaultMark") . "));\n" .
             "    }\n");
     } elsif ($dataNode->extendedAttributes->{"CustomMarkFunction"}) {
         push(@headerContent,
@@ -868,6 +870,8 @@ sub GenerateImplementation
     my $parentClassName = GetParentClassName($dataNode);
     my $conditional = $dataNode->extendedAttributes->{"Conditional"};
     my $visibleClassName = GetVisibleClassName($interfaceName);
+    my $eventTarget = $dataNode->extendedAttributes->{"EventTarget"};
+    my $needsMarkChildren = $dataNode->extendedAttributes->{"CustomMarkFunction"} || $dataNode->extendedAttributes->{"EventTarget"};
 
     # - Add default header template
     @implContentHeader = split("\r", $headerTemplate);
@@ -1153,17 +1157,17 @@ sub GenerateImplementation
     push(@implContent, "}\n\n");
 
     # Destructor
-    if (!$hasParent || $interfaceName eq "DOMWindow") {
+    if (!$hasParent || $eventTarget) {
         push(@implContent, "${className}::~$className()\n");
         push(@implContent, "{\n");
 
+        if ($eventTarget) {
+            $implIncludes{"RegisteredEventListener.h"} = 1;
+            push(@implContent, "    impl()->invalidateEventListeners();\n");
+        }
+
         if ($interfaceName eq "Node") {
-             $implIncludes{"RegisteredEventListener.h"} = 1;
-             push(@implContent, "    invalidateEventListeners(m_impl->eventListeners());\n");
-             push(@implContent, "    forgetDOMNode(m_impl->document(), m_impl.get());\n");
-        } elsif ($interfaceName eq "DOMWindow") {
-             $implIncludes{"RegisteredEventListener.h"} = 1;
-             push(@implContent, "    invalidateEventListeners(impl()->eventListeners());\n");
+             push(@implContent, "    forgetDOMNode(impl()->document(), impl());\n");
         } else {
             if ($podType) {
                 my $animatedType = $implClassName;
@@ -1174,7 +1178,7 @@ sub GenerateImplementation
                     push(@implContent, "    JSSVGDynamicPODTypeWrapperCache<$podType, $animatedType>::forgetWrapper(m_impl.get());\n");
                 }
             }
-            push(@implContent, "    forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get());\n");
+            push(@implContent, "    forgetDOMObject(*Heap::heap(this)->globalData(), impl());\n");
         }
 
         push(@implContent, "}\n\n");
@@ -1187,6 +1191,14 @@ sub GenerateImplementation
         push(@implContent, "{\n    forgetDOMObject(*Heap::heap(this)->globalData(), static_cast<${implClassName}*>(impl()));\n}\n\n");
     }
 
+    if ($needsMarkChildren && !$dataNode->extendedAttributes->{"CustomMarkFunction"}) {
+        push(@implContent, "void ${className}::markChildren(MarkStack& markStack)\n");
+        push(@implContent, "{\n");
+        push(@implContent, "    Base::markChildren(markStack);\n");
+        push(@implContent, "    impl()->markEventListeners(markStack);\n");
+        push(@implContent, "}\n\n");
+    }
+
     if (!$dataNode->extendedAttributes->{"ExtendsDOMGlobalObject"}) {
         push(@implContent, "JSObject* ${className}::createPrototype(ExecState* exec, JSGlobalObject* globalObject)\n");
         push(@implContent, "{\n");
diff --git a/WebCore/dom/CharacterData.cpp b/WebCore/dom/CharacterData.cpp
index 902b7ff..3c3dc37 100644
--- a/WebCore/dom/CharacterData.cpp
+++ b/WebCore/dom/CharacterData.cpp
@@ -187,10 +187,8 @@ void CharacterData::dispatchModifiedEvent(StringImpl* prevValue)
 {
     if (parentNode())
         parentNode()->childrenChanged();
-    if (document()->hasListenerType(Document::DOMCHARACTERDATAMODIFIED_LISTENER)) {
-        ExceptionCode ec;
-        dispatchMutationEvent(eventNames().DOMCharacterDataModifiedEvent, true, 0, prevValue, m_data, ec); 
-    }
+    if (document()->hasListenerType(Document::DOMCHARACTERDATAMODIFIED_LISTENER))
+        dispatchEvent(MutationEvent::create(eventNames().DOMCharacterDataModifiedEvent, true, 0, prevValue, m_data));
     dispatchSubtreeModifiedEvent();
 }
 
diff --git a/WebCore/dom/ContainerNode.cpp b/WebCore/dom/ContainerNode.cpp
index 1ec4eb3..7274b5d 100644
--- a/WebCore/dom/ContainerNode.cpp
+++ b/WebCore/dom/ContainerNode.cpp
@@ -41,8 +41,8 @@
 
 namespace WebCore {
 
-static void dispatchChildInsertionEvents(Node*, ExceptionCode&);
-static void dispatchChildRemovalEvents(Node*, ExceptionCode&);
+static void dispatchChildInsertionEvents(Node*);
+static void dispatchChildRemovalEvents(Node*);
 
 typedef Vector<std::pair<NodeCallback, RefPtr<Node> > > NodeCallbackQueue;
 static NodeCallbackQueue* s_postAttachCallbackQueue;
@@ -144,7 +144,7 @@ bool ContainerNode::insertBefore(PassRefPtr<Node> newChild, Node* refChild, Exce
 
         // Dispatch the mutation events.
         childrenChanged(false, refChildPreviousSibling.get(), next.get(), 1);
-        dispatchChildInsertionEvents(child.get(), ec);
+        dispatchChildInsertionEvents(child.get());
                 
         // Add child to the rendering tree.
         if (attached() && !child->attached() && child->parent() == this) {
@@ -255,7 +255,7 @@ bool ContainerNode::replaceChild(PassRefPtr<Node> newChild, Node* oldChild, Exce
         allowEventDispatch();
 
         // Dispatch the mutation events
-        dispatchChildInsertionEvents(child.get(), ec);
+        dispatchChildInsertionEvents(child.get());
                 
         // Add child to the rendering tree
         if (attached() && !child->attached() && child->parent() == this) {
@@ -287,7 +287,7 @@ static ExceptionCode willRemoveChild(Node *child)
     ExceptionCode ec = 0;
 
     // fire removed from document mutation events.
-    dispatchChildRemovalEvents(child, ec);
+    dispatchChildRemovalEvents(child);
     if (ec)
         return ec;
 
@@ -480,7 +480,7 @@ bool ContainerNode::appendChild(PassRefPtr<Node> newChild, ExceptionCode& ec, bo
 
         // Dispatch the mutation events
         childrenChanged(false, prev.get(), 0, 1);
-        dispatchChildInsertionEvents(child.get(), ec);
+        dispatchChildInsertionEvents(child.get());
 
         // Add child to the rendering tree
         if (attached() && !child->attached() && child->parent() == this) {
@@ -864,7 +864,7 @@ Node *ContainerNode::childNode(unsigned index) const
     return n;
 }
 
-static void dispatchChildInsertionEvents(Node* child, ExceptionCode& ec)
+static void dispatchChildInsertionEvents(Node* child)
 {
     ASSERT(!eventDispatchForbidden());
 
@@ -878,25 +878,17 @@ static void dispatchChildInsertionEvents(Node* child, ExceptionCode& ec)
 
     document->incDOMTreeVersion();
 
-    if (c->parentNode() && document->hasListenerType(Document::DOMNODEINSERTED_LISTENER)) {
-        ec = 0;
-        c->dispatchMutationEvent(eventNames().DOMNodeInsertedEvent, true, c->parentNode(), String(), String(), ec); 
-        if (ec)
-            return;
-    }
+    if (c->parentNode() && document->hasListenerType(Document::DOMNODEINSERTED_LISTENER))
+        c->dispatchEvent(MutationEvent::create(eventNames().DOMNodeInsertedEvent, true, c->parentNode()));
 
     // dispatch the DOMNodeInsertedIntoDocument event to all descendants
     if (c->inDocument() && document->hasListenerType(Document::DOMNODEINSERTEDINTODOCUMENT_LISTENER)) {
-        for (; c; c = c->traverseNextNode(child)) {
-            ec = 0;
-            c->dispatchMutationEvent(eventNames().DOMNodeInsertedIntoDocumentEvent, false, 0, String(), String(), ec); 
-            if (ec)
-                return;
-        }
+        for (; c; c = c->traverseNextNode(child))
+            c->dispatchEvent(MutationEvent::create(eventNames().DOMNodeInsertedIntoDocumentEvent, false));
     }
 }
 
-static void dispatchChildRemovalEvents(Node* child, ExceptionCode& ec)
+static void dispatchChildRemovalEvents(Node* child)
 {
     RefPtr<Node> c = child;
     RefPtr<Document> document = child->document();
@@ -907,21 +899,14 @@ static void dispatchChildRemovalEvents(Node* child, ExceptionCode& ec)
     document->incDOMTreeVersion();
 
     // dispatch pre-removal mutation events
-    if (c->parentNode() && document->hasListenerType(Document::DOMNODEREMOVED_LISTENER)) {
-        ec = 0;
-        c->dispatchMutationEvent(eventNames().DOMNodeRemovedEvent, true, c->parentNode(), String(), String(), ec); 
-        if (ec)
-            return;
-    }
+    if (c->parentNode() && document->hasListenerType(Document::DOMNODEREMOVED_LISTENER))
+        c->dispatchEvent(MutationEvent::create(eventNames().DOMNodeRemovedEvent, true, c->parentNode()));
 
     // dispatch the DOMNodeRemovedFromDocument event to all descendants
-    if (c->inDocument() && document->hasListenerType(Document::DOMNODEREMOVEDFROMDOCUMENT_LISTENER))
-        for (; c; c = c->traverseNextNode(child)) {
-            ec = 0;
-            c->dispatchMutationEvent(eventNames().DOMNodeRemovedFromDocumentEvent, false, 0, String(), String(), ec); 
-            if (ec)
-                return;
-        }
+    if (c->inDocument() && document->hasListenerType(Document::DOMNODEREMOVEDFROMDOCUMENT_LISTENER)) {
+        for (; c; c = c->traverseNextNode(child))
+            c->dispatchEvent(MutationEvent::create(eventNames().DOMNodeRemovedFromDocumentEvent, false));
+    }
 }
 
-}
+} // namespace WebCore
diff --git a/WebCore/dom/Document.cpp b/WebCore/dom/Document.cpp
index 57e22e1..5422bf0 100644
--- a/WebCore/dom/Document.cpp
+++ b/WebCore/dom/Document.cpp
@@ -1470,9 +1470,11 @@ void Document::detach()
 
 void Document::removeAllEventListeners()
 {
+    EventTarget::removeAllEventListeners();
+
     if (DOMWindow* domWindow = this->domWindow())
         domWindow->removeAllEventListeners();
-    for (Node* node = this; node; node = node->traverseNextNode())
+    for (Node* node = firstChild(); node; node = node->traverseNextNode())
         node->removeAllEventListeners();
 }
 
@@ -1715,8 +1717,8 @@ void Document::implicitClose()
         f->animation()->resumeAnimations(this);
 
     ImageLoader::dispatchPendingLoadEvents();
-    dispatchLoadEvent();
-    dispatchPageTransitionEvent(EventNames().pageshowEvent, false);
+    dispatchWindowLoadEvent();
+    dispatchWindowEvent(PageTransitionEvent::create(eventNames().pageshowEvent, false), this);
     if (f)
         f->loader()->handledOnloadEvents();
 #ifdef INSTRUMENT_LAYOUT_SCHEDULING
@@ -2646,7 +2648,7 @@ bool Document::setFocusedNode(PassRefPtr<Node> newFocusedNode)
         // Dispatch a change event for text fields or textareas that have been edited
         RenderObject* r = oldFocusedNode->renderer();
         if (r && r->isTextControl() && toRenderTextControl(r)->isEdited()) {
-            oldFocusedNode->dispatchEvent(eventNames().changeEvent, true, false);
+            oldFocusedNode->dispatchEvent(Event::create(eventNames().changeEvent, true, false));
             r = oldFocusedNode->renderer();
             if (r && r->isTextControl())
                 toRenderTextControl(r)->setEdited(false);
@@ -2873,26 +2875,16 @@ EventListener* Document::getWindowAttributeEventListener(const AtomicString& eve
     return domWindow->getAttributeEventListener(eventType);
 }
 
-void Document::dispatchWindowEvent(PassRefPtr<Event> event)
+void Document::dispatchWindowEvent(PassRefPtr<Event> event,  PassRefPtr<EventTarget> target)
 {
     ASSERT(!eventDispatchForbidden());
     DOMWindow* domWindow = this->domWindow();
     if (!domWindow)
         return;
-    ExceptionCode ec;
-    domWindow->dispatchEvent(event, ec);
+    domWindow->dispatchEvent(event, target);
 }
 
-void Document::dispatchWindowEvent(const AtomicString& eventType, bool canBubbleArg, bool cancelableArg)
-{
-    ASSERT(!eventDispatchForbidden());
-    DOMWindow* domWindow = this->domWindow();
-    if (!domWindow)
-        return;
-    domWindow->dispatchEvent(eventType, canBubbleArg, cancelableArg);
-}
-
-void Document::dispatchLoadEvent()
+void Document::dispatchWindowLoadEvent()
 {
     ASSERT(!eventDispatchForbidden());
     DOMWindow* domWindow = this->domWindow();
@@ -2901,15 +2893,6 @@ void Document::dispatchLoadEvent()
     domWindow->dispatchLoadEvent();
 }
 
-void Document::dispatchPageTransitionEvent(const AtomicString& eventType, bool persisted)
-{
-    ASSERT(!eventDispatchForbidden());
-    DOMWindow* domWindow = this->domWindow();
-    if (!domWindow)
-        return;
-    domWindow->dispatchPageTransitionEvent(eventType, persisted);
-}
-
 PassRefPtr<Event> Document::createEvent(const String& eventType, ExceptionCode& ec)
 {
     if (eventType == "Event" || eventType == "Events" || eventType == "HTMLEvents")
@@ -4029,10 +4012,7 @@ CollectionCache* Document::nameCollectionInfo(CollectionType type, const AtomicS
 void Document::finishedParsing()
 {
     setParsing(false);
-
-    ExceptionCode ec = 0;
-    dispatchEvent(Event::create(eventNames().DOMContentLoadedEvent, true, false), ec);
-
+    dispatchEvent(Event::create(eventNames().DOMContentLoadedEvent, true, false));
     if (Frame* f = frame())
         f->loader()->finishedParsing();
 }
diff --git a/WebCore/dom/Document.h b/WebCore/dom/Document.h
index bb247f3..454304b 100644
--- a/WebCore/dom/Document.h
+++ b/WebCore/dom/Document.h
@@ -200,6 +200,49 @@ public:
 
     // DOM methods & attributes for Document
 
+    DEFINE_ATTRIBUTE_EVENT_LISTENER(abort);
+    DEFINE_ATTRIBUTE_EVENT_LISTENER(change);
+    DEFINE_ATTRIBUTE_EVENT_LISTENER(click);
+    DEFINE_ATTRIBUTE_EVENT_LISTENER(contextmenu);
+    DEFINE_ATTRIBUTE_EVENT_LISTENER(dblclick);
+    DEFINE_ATTRIBUTE_EVENT_LISTENER(dragenter);
+    DEFINE_ATTRIBUTE_EVENT_LISTENER(dragover);
+    DEFINE_ATTRIBUTE_EVENT_LISTENER(dragleave);
+    DEFINE_ATTRIBUTE_EVENT_LISTENER(drop);
+    DEFINE_ATTRIBUTE_EVENT_LISTENER(dragstart);
+    DEFINE_ATTRIBUTE_EVENT_LISTENER(drag);
+    DEFINE_ATTRIBUTE_EVENT_LISTENER(dragend);
+    DEFINE_ATTRIBUTE_EVENT_LISTENER(input);
+    DEFINE_ATTRIBUTE_EVENT_LISTENER(invalid);
+    DEFINE_ATTRIBUTE_EVENT_LISTENER(keydown);
+    DEFINE_ATTRIBUTE_EVENT_LISTENER(keypress);
+    DEFINE_ATTRIBUTE_EVENT_LISTENER(keyup);
+    DEFINE_ATTRIBUTE_EVENT_LISTENER(mousedown);
+    DEFINE_ATTRIBUTE_EVENT_LISTENER(mousemove);
+    DEFINE_ATTRIBUTE_EVENT_LISTENER(mouseout);
+    DEFINE_ATTRIBUTE_EVENT_LISTENER(mouseover);
+    DEFINE_ATTRIBUTE_EVENT_LISTENER(mouseup);
+    DEFINE_ATTRIBUTE_EVENT_LISTENER(mousewheel);
+    DEFINE_ATTRIBUTE_EVENT_LISTENER(scroll);
+    DEFINE_ATTRIBUTE_EVENT_LISTENER(select);
+    DEFINE_ATTRIBUTE_EVENT_LISTENER(submit);
+
+    DEFINE_ATTRIBUTE_EVENT_LISTENER(blur);
+    DEFINE_ATTRIBUTE_EVENT_LISTENER(error);
+    DEFINE_ATTRIBUTE_EVENT_LISTENER(focus);
+    DEFINE_ATTRIBUTE_EVENT_LISTENER(load);
+
+    // WebKit extensions
+    DEFINE_ATTRIBUTE_EVENT_LISTENER(beforecut);
+    DEFINE_ATTRIBUTE_EVENT_LISTENER(cut);
+    DEFINE_ATTRIBUTE_EVENT_LISTENER(beforecopy);
+    DEFINE_ATTRIBUTE_EVENT_LISTENER(copy);
+    DEFINE_ATTRIBUTE_EVENT_LISTENER(beforepaste);
+    DEFINE_ATTRIBUTE_EVENT_LISTENER(paste);
+    DEFINE_ATTRIBUTE_EVENT_LISTENER(reset);
+    DEFINE_ATTRIBUTE_EVENT_LISTENER(search);
+    DEFINE_ATTRIBUTE_EVENT_LISTENER(selectstart);
+
     DocumentType* doctype() const { return m_docType.get(); }
 
     DOMImplementation* implementation() const;
@@ -547,10 +590,8 @@ public:
     // Helper functions for forwarding DOMWindow event related tasks to the DOMWindow if it exists.
     void setWindowAttributeEventListener(const AtomicString& eventType, PassRefPtr<EventListener>);
     EventListener* getWindowAttributeEventListener(const AtomicString& eventType);
-    void dispatchWindowEvent(PassRefPtr<Event>);
-    void dispatchWindowEvent(const AtomicString& eventType, bool canBubbleArg, bool cancelableArg);
-    void dispatchLoadEvent();
-    void dispatchPageTransitionEvent(const AtomicString& eventType, bool persisted);
+    void dispatchWindowEvent(PassRefPtr<Event>, PassRefPtr<EventTarget> = 0);
+    void dispatchWindowLoadEvent();
 
     PassRefPtr<Event> createEvent(const String& eventType, ExceptionCode&);
 
@@ -812,7 +853,7 @@ public:
     void setDashboardRegions(const Vector<DashboardRegionValue>&);
 #endif
 
-    void removeAllEventListeners();
+    virtual void removeAllEventListeners();
 
     CheckedRadioButtons& checkedRadioButtons() { return m_checkedRadioButtons; }
     
diff --git a/WebCore/dom/Element.h b/WebCore/dom/Element.h
index e7a910c..4ecf932 100644
--- a/WebCore/dom/Element.h
+++ b/WebCore/dom/Element.h
@@ -44,6 +44,51 @@ public:
     static PassRefPtr<Element> create(const QualifiedName&, Document*);
     virtual ~Element();
 
+    DEFINE_ATTRIBUTE_EVENT_LISTENER(abort);
+    DEFINE_ATTRIBUTE_EVENT_LISTENER(change);
+    DEFINE_ATTRIBUTE_EVENT_LISTENER(click);
+    DEFINE_ATTRIBUTE_EVENT_LISTENER(contextmenu);
+    DEFINE_ATTRIBUTE_EVENT_LISTENER(dblclick);
+    DEFINE_ATTRIBUTE_EVENT_LISTENER(dragenter);
+    DEFINE_ATTRIBUTE_EVENT_LISTENER(dragover);
+    DEFINE_ATTRIBUTE_EVENT_LISTENER(dragleave);
+    DEFINE_ATTRIBUTE_EVENT_LISTENER(drop);
+    DEFINE_ATTRIBUTE_EVENT_LISTENER(dragstart);
+    DEFINE_ATTRIBUTE_EVENT_LISTENER(drag);
+    DEFINE_ATTRIBUTE_EVENT_LISTENER(dragend);
+    DEFINE_ATTRIBUTE_EVENT_LISTENER(input);
+    DEFINE_ATTRIBUTE_EVENT_LISTENER(invalid);
+    DEFINE_ATTRIBUTE_EVENT_LISTENER(keydown);
+    DEFINE_ATTRIBUTE_EVENT_LISTENER(keypress);
+    DEFINE_ATTRIBUTE_EVENT_LISTENER(keyup);
+    DEFINE_ATTRIBUTE_EVENT_LISTENER(mousedown);
+    DEFINE_ATTRIBUTE_EVENT_LISTENER(mousemove);
+    DEFINE_ATTRIBUTE_EVENT_LISTENER(mouseout);
+    DEFINE_ATTRIBUTE_EVENT_LISTENER(mouseover);
+    DEFINE_ATTRIBUTE_EVENT_LISTENER(mouseup);
+    DEFINE_ATTRIBUTE_EVENT_LISTENER(mousewheel);
+    DEFINE_ATTRIBUTE_EVENT_LISTENER(scroll);
+    DEFINE_ATTRIBUTE_EVENT_LISTENER(select);
+    DEFINE_ATTRIBUTE_EVENT_LISTENER(submit);
+
+    // These 4 attribute event handler attributes are overrided by HTMLBodyElement
+    // and HTMLFrameSetElement to forward to the DOMWindow.
+    DEFINE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(blur);
+    DEFINE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(error);
+    DEFINE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(focus);
+    DEFINE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(load);
+
+    // WebKit extensions
+    DEFINE_ATTRIBUTE_EVENT_LISTENER(beforecut);
+    DEFINE_ATTRIBUTE_EVENT_LISTENER(cut);
+    DEFINE_ATTRIBUTE_EVENT_LISTENER(beforecopy);
+    DEFINE_ATTRIBUTE_EVENT_LISTENER(copy);
+    DEFINE_ATTRIBUTE_EVENT_LISTENER(beforepaste);
+    DEFINE_ATTRIBUTE_EVENT_LISTENER(paste);
+    DEFINE_ATTRIBUTE_EVENT_LISTENER(reset);
+    DEFINE_ATTRIBUTE_EVENT_LISTENER(search);
+    DEFINE_ATTRIBUTE_EVENT_LISTENER(selectstart);
+
     const AtomicString& getIDAttribute() const;
     bool hasAttribute(const QualifiedName&) const;
     const AtomicString& getAttribute(const QualifiedName&) const;
diff --git a/WebCore/dom/EventListener.h b/WebCore/dom/EventListener.h
index 7d3ac98..6862f06 100644
--- a/WebCore/dom/EventListener.h
+++ b/WebCore/dom/EventListener.h
@@ -44,7 +44,7 @@ namespace WebCore {
                     
         virtual ~EventListener() { }
         virtual bool operator==(const EventListener&) = 0;
-        virtual void handleEvent(Event*, bool isWindowEvent = false) = 0;
+        virtual void handleEvent(Event*) = 0;
         // Return true to indicate that the error is handled.
         virtual bool reportError(const String& /*message*/, const String& /*url*/, int /*lineNumber*/) { return false; }
         virtual bool wasCreatedFromMarkup() const { return false; }
@@ -69,10 +69,6 @@ namespace WebCore {
         Type m_type;
     };
 
-#if USE(JSC)
-    inline void markIfNotNull(JSC::MarkStack& markStack, EventListener* listener) { if (listener) listener->markJSFunction(markStack); }
-#endif
-
 }
 
 #endif
diff --git a/WebCore/dom/EventNames.h b/WebCore/dom/EventNames.h
index 0581c95..0eb98ec 100644
--- a/WebCore/dom/EventNames.h
+++ b/WebCore/dom/EventNames.h
@@ -45,6 +45,7 @@ namespace WebCore {
     macro(copy) \
     macro(cut) \
     macro(dblclick) \
+    macro(display) \
     macro(downloading) \
     macro(drag) \
     macro(dragend) \
diff --git a/WebCore/dom/EventTarget.cpp b/WebCore/dom/EventTarget.cpp
index 652644f..d3b3f55 100644
--- a/WebCore/dom/EventTarget.cpp
+++ b/WebCore/dom/EventTarget.cpp
@@ -34,11 +34,39 @@
 #include "config.h"
 #include "EventTarget.h"
 
+#include "Event.h"
+#include "EventException.h"
+#include <wtf/StdLibExtras.h>
+
+using namespace WTF;
+
 namespace WebCore {
 
 #ifndef NDEBUG
 static int gEventDispatchForbidden = 0;
-#endif
+
+void forbidEventDispatch()
+{
+    if (!isMainThread())
+        return;
+    ++gEventDispatchForbidden;
+}
+
+void allowEventDispatch()
+{
+    if (!isMainThread())
+        return;
+    if (gEventDispatchForbidden > 0)
+        --gEventDispatchForbidden;
+}
+
+bool eventDispatchForbidden()
+{
+    if (!isMainThread())
+        return false;
+    return gEventDispatchForbidden > 0;
+}
+#endif // NDEBUG
 
 EventTarget::~EventTarget()
 {
@@ -125,22 +153,153 @@ Notification* EventTarget::toNotification()
 }
 #endif
 
-#ifndef NDEBUG
-void forbidEventDispatch()
+bool EventTarget::addEventListener(const AtomicString& eventType, PassRefPtr<EventListener> listener, bool useCapture)
 {
-    ++gEventDispatchForbidden;
+    EventTargetData* d = ensureEventTargetData();
+
+    pair<EventListenerMap::iterator, bool> result = d->eventListenerMap.add(eventType, EventListenerVector());
+    EventListenerVector& entry = result.first->second;
+
+    RegisteredEventListener registeredListener(listener, useCapture);
+    if (!result.second) { // pre-existing entry
+        if (entry.find(registeredListener) != notFound) // duplicate listener
+            return false;
+    }
+
+    entry.append(registeredListener);
+    return true;
 }
 
-void allowEventDispatch()
+bool EventTarget::removeEventListener(const AtomicString& eventType, EventListener* listener, bool useCapture)
 {
-    if (gEventDispatchForbidden > 0)
-        --gEventDispatchForbidden;
+    EventTargetData* d = eventTargetData();
+    if (!d)
+        return false;
+
+    EventListenerMap::iterator result = d->eventListenerMap.find(eventType);
+    if (result == d->eventListenerMap.end())
+        return false;
+    EventListenerVector& entry = result->second;
+
+    RegisteredEventListener registeredListener(listener, useCapture);
+    size_t index = entry.find(registeredListener);
+    if (index == notFound)
+        return false;
+
+    entry.remove(index);
+    if (!entry.size())
+        d->eventListenerMap.remove(result);
+
+    // Notify firing events planning to invoke the listener at 'index' that
+    // they have one less listener to invoke.
+    for (size_t i = 0; i < d->firingEventEndIterators.size(); ++i) {
+        if (eventType == *d->firingEventEndIterators[i].eventType && index < *d->firingEventEndIterators[i].value)
+            --*d->firingEventEndIterators[i].value;
+    }
+
+    return true;
 }
 
-bool eventDispatchForbidden()
+bool EventTarget::setAttributeEventListener(const AtomicString& eventType, PassRefPtr<EventListener> listener)
 {
-    return gEventDispatchForbidden > 0;
+    clearAttributeEventListener(eventType);
+    if (!listener)
+        return false;
+    return addEventListener(eventType, listener, false);
+}
+
+EventListener* EventTarget::getAttributeEventListener(const AtomicString& eventType)
+{
+    const EventListenerVector& entry = getEventListeners(eventType);
+    for (size_t i = 0; i < entry.size(); ++i) {
+        if (entry[i].listener->isAttribute())
+            return entry[i].listener.get();
+    }
+    return 0;
+}
+
+bool EventTarget::clearAttributeEventListener(const AtomicString& eventType)
+{
+    EventListener* listener = getAttributeEventListener(eventType);
+    if (!listener)
+        return false;
+    return removeEventListener(eventType, listener, false);
+}
+
+bool EventTarget::dispatchEvent(PassRefPtr<Event> event, ExceptionCode& ec)
+{
+    if (!event || event->type().isEmpty()) {
+        ec = EventException::UNSPECIFIED_EVENT_TYPE_ERR;
+        return false;
+    }
+    return dispatchEvent(event);
+}
+
+bool EventTarget::dispatchEvent(PassRefPtr<Event> event)
+{
+    event->setTarget(this);
+    event->setCurrentTarget(this);
+    event->setEventPhase(Event::AT_TARGET);
+    return fireEventListeners(event.get());
+}
+
+bool EventTarget::fireEventListeners(Event* event)
+{
+    ASSERT(!eventDispatchForbidden());
+    ASSERT(event && !event->type().isEmpty());
+
+    EventTargetData* d = eventTargetData();
+    if (!d)
+        return true;
+
+    EventListenerMap::iterator result = d->eventListenerMap.find(event->type());
+    if (result == d->eventListenerMap.end())
+        return false;
+    EventListenerVector& entry = result->second;
+
+    RefPtr<EventTarget> protect = this;
+
+    size_t end = entry.size();
+    d->firingEventEndIterators.append(FiringEventEndIterator(&event->type(), &end));
+    for (size_t i = 0; i < end; ++i) {
+        RegisteredEventListener& registeredListener = entry[i];
+        if (event->eventPhase() == Event::CAPTURING_PHASE && !registeredListener.useCapture)
+            continue;
+        if (event->eventPhase() == Event::BUBBLING_PHASE && registeredListener.useCapture)
+            continue;
+        // To match Mozilla, the AT_TARGET phase fires both capturing and bubbling
+        // event listeners, even though that violates some versions of the DOM spec.
+        registeredListener.listener->handleEvent(event);
+    }
+    d->firingEventEndIterators.removeLast();
+
+    return !event->defaultPrevented();
+}
+
+const EventListenerVector& EventTarget::getEventListeners(const AtomicString& eventType)
+{
+    DEFINE_STATIC_LOCAL(EventListenerVector, emptyVector, ());
+
+    EventTargetData* d = eventTargetData();
+    if (!d)
+        return emptyVector;
+    EventListenerMap::iterator it = d->eventListenerMap.find(eventType);
+    if (it == d->eventListenerMap.end())
+        return emptyVector;
+    return it->second;
+}
+
+void EventTarget::removeAllEventListeners()
+{
+    EventTargetData* d = eventTargetData();
+    if (!d)
+        return;
+    d->eventListenerMap.clear();
+
+    // Notify firing events planning to invoke the listener at 'index' that
+    // they have one less listener to invoke.
+    for (size_t i = 0; i < d->firingEventEndIterators.size(); ++i)
+        *d->firingEventEndIterators[i].value = 0;
 }
-#endif // NDEBUG
 
-} // end namespace
+} // namespace WebCore
diff --git a/WebCore/dom/EventTarget.h b/WebCore/dom/EventTarget.h
index 6bcc3fb..4499328 100644
--- a/WebCore/dom/EventTarget.h
+++ b/WebCore/dom/EventTarget.h
@@ -32,6 +32,9 @@
 #ifndef EventTarget_h
 #define EventTarget_h
 
+#include "AtomicStringHash.h"
+#include "EventNames.h"
+#include "RegisteredEventListener.h"
 #include <wtf/Forward.h>
 
 namespace WebCore {
@@ -58,8 +61,31 @@ namespace WebCore {
 
     typedef int ExceptionCode;
 
+    struct FiringEventEndIterator {
+        FiringEventEndIterator(const AtomicString* eventType, size_t* value)
+            : eventType(eventType)
+            , value(value)
+        {
+        }
+        
+        const AtomicString* eventType;
+        size_t* value;
+    };
+    typedef Vector<FiringEventEndIterator, 1> FiringEventEndIteratorVector;
+
+    typedef Vector<RegisteredEventListener, 1> EventListenerVector;
+    typedef HashMap<AtomicString, EventListenerVector> EventListenerMap;
+
+    struct EventTargetData {
+        EventListenerMap eventListenerMap;
+        FiringEventEndIteratorVector firingEventEndIterators;
+    };
+
     class EventTarget {
     public:
+        void ref() { refEventTarget(); }
+        void deref() { derefEventTarget(); }
+
         virtual EventSource* toEventSource();
         virtual MessagePort* toMessagePort();
         virtual Node* toNode();
@@ -90,36 +116,119 @@ namespace WebCore {
 
         virtual ScriptExecutionContext* scriptExecutionContext() const = 0;
 
-        virtual void addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture) = 0;
-        virtual void removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture) = 0;
-        virtual bool dispatchEvent(PassRefPtr<Event>, ExceptionCode&) = 0;
+        virtual bool addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture);
+        virtual bool removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture);
+        virtual void removeAllEventListeners();
+        virtual bool dispatchEvent(PassRefPtr<Event>);
+        bool dispatchEvent(PassRefPtr<Event>, ExceptionCode&); // DOM API
 
-        void ref() { refEventTarget(); }
-        void deref() { derefEventTarget(); }
+        // Used for legacy "onEvent" attribute APIs.
+        bool setAttributeEventListener(const AtomicString& eventType, PassRefPtr<EventListener>);
+        bool clearAttributeEventListener(const AtomicString& eventType);
+        EventListener* getAttributeEventListener(const AtomicString& eventType);
+
+        bool hasEventListeners();
+        bool hasEventListeners(const AtomicString& eventType);
+        const EventListenerVector& getEventListeners(const AtomicString& eventType);
 
-        // Handlers to do/undo actions on the target node before an event is dispatched to it and after the event
-        // has been dispatched.  The data pointer is handed back by the preDispatch and passed to postDispatch.
-        virtual void* preDispatchEventHandler(Event*) { return 0; }
-        virtual void postDispatchEventHandler(Event*, void* /*dataFromPreDispatch*/) { }
+        bool fireEventListeners(Event*);
+        bool isFiringEventListeners();
+
+#if USE(JSC)
+        void markEventListeners(JSC::MarkStack&);
+        void invalidateEventListeners();
+#endif
 
     protected:
         virtual ~EventTarget();
+        
+        virtual EventTargetData* eventTargetData() = 0;
+        virtual EventTargetData* ensureEventTargetData() = 0;
 
     private:
         virtual void refEventTarget() = 0;
         virtual void derefEventTarget() = 0;
     };
 
-    void forbidEventDispatch();
-    void allowEventDispatch();
+    #define DEFINE_ATTRIBUTE_EVENT_LISTENER(attribute) \
+        EventListener* on##attribute() { return getAttributeEventListener(eventNames().attribute##Event); } \
+        void setOn##attribute(PassRefPtr<EventListener> listener) { setAttributeEventListener(eventNames().attribute##Event, listener); } \
+
+    #define DEFINE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(attribute) \
+        virtual EventListener* on##attribute() { return getAttributeEventListener(eventNames().attribute##Event); } \
+        virtual void setOn##attribute(PassRefPtr<EventListener> listener) { setAttributeEventListener(eventNames().attribute##Event, listener); } \
+
+    #define DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(attribute) \
+        EventListener* on##attribute() { return document()->getWindowAttributeEventListener(eventNames().attribute##Event); } \
+        void setOn##attribute(PassRefPtr<EventListener> listener) { document()->setWindowAttributeEventListener(eventNames().attribute##Event, listener); } \
+
+    #define DEFINE_MAPPED_ATTRIBUTE_EVENT_LISTENER(attribute, eventName) \
+        EventListener* on##attribute() { return getAttributeEventListener(eventNames().eventName##Event); } \
+        void setOn##attribute(PassRefPtr<EventListener> listener) { setAttributeEventListener(eventNames().eventName##Event, listener); } \
+
+    #define DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(recipient, attribute) \
+        EventListener* on##attribute() { return recipient ? recipient->getAttributeEventListener(eventNames().attribute##Event) : 0; } \
+        void setOn##attribute(PassRefPtr<EventListener> listener) { if (recipient) recipient->setAttributeEventListener(eventNames().attribute##Event, listener); } \
 
 #ifndef NDEBUG
+    void forbidEventDispatch();
+    void allowEventDispatch();
     bool eventDispatchForbidden();
 #else
     inline void forbidEventDispatch() { }
     inline void allowEventDispatch() { }
 #endif
 
-}
+#if USE(JSC)
+    inline void EventTarget::markEventListeners(JSC::MarkStack& markStack)
+    {
+        EventTargetData* d = eventTargetData();
+        if (!d)
+            return;
+
+        EventListenerMap::iterator end = d->eventListenerMap.end();
+        for (EventListenerMap::iterator it = d->eventListenerMap.begin(); it != end; ++it) {
+            EventListenerVector& entry = it->second;
+            for (size_t i = 0; i < entry.size(); ++i)
+                entry[i].listener->markJSFunction(markStack);
+        }
+    }
+
+    inline void EventTarget::invalidateEventListeners()
+    {
+        EventTargetData* d = eventTargetData();
+        if (!d)
+            return;
+
+        d->eventListenerMap.clear();
+    }
+
+    inline bool EventTarget::isFiringEventListeners()
+    {
+        EventTargetData* d = eventTargetData();
+        if (!d)
+            return false;
+        return d->firingEventEndIterators.size() != 0;
+    }
+
+    inline bool EventTarget::hasEventListeners()
+    {
+        EventTargetData* d = eventTargetData();
+        if (!d)
+            return false;
+        return !d->eventListenerMap.isEmpty();
+    }
+
+    inline bool EventTarget::hasEventListeners(const AtomicString& eventType)
+    {
+        EventTargetData* d = eventTargetData();
+        if (!d)
+            return false;
+        return d->eventListenerMap.contains(eventType);
+    }
 
 #endif
+
+} // namespace WebCore
+
+#endif // EventTarget_h
diff --git a/WebCore/dom/InputElement.cpp b/WebCore/dom/InputElement.cpp
index 875d9f2..96e31f4 100644
--- a/WebCore/dom/InputElement.cpp
+++ b/WebCore/dom/InputElement.cpp
@@ -153,8 +153,7 @@ void InputElement::setValueFromRenderer(InputElementData& data, InputElement* in
 
     element->setFormControlValueMatchesRenderer(true);
 
-    // Fire the "input" DOM event
-    element->dispatchEvent(eventNames().inputEvent, true, false);
+    element->dispatchEvent(Event::create(eventNames().inputEvent, true, false));
     notifyFormStateChanged(element);
 }
 
diff --git a/WebCore/dom/MessageEvent.h b/WebCore/dom/MessageEvent.h
index 7d94689..555ed47 100644
--- a/WebCore/dom/MessageEvent.h
+++ b/WebCore/dom/MessageEvent.h
@@ -42,7 +42,7 @@ namespace WebCore {
         {
             return adoptRef(new MessageEvent);
         }
-        static PassRefPtr<MessageEvent> create(const String& data, const String& origin, const String& lastEventId, PassRefPtr<DOMWindow> source, PassOwnPtr<MessagePortArray> ports)
+        static PassRefPtr<MessageEvent> create(PassOwnPtr<MessagePortArray> ports, const String& data = "", const String& origin = "", const String& lastEventId = "", PassRefPtr<DOMWindow> source = 0)
         {
             return adoptRef(new MessageEvent(data, origin, lastEventId, source, ports));
         }
diff --git a/WebCore/dom/MessagePort.cpp b/WebCore/dom/MessagePort.cpp
index bfd7932..50a0106 100644
--- a/WebCore/dom/MessagePort.cpp
+++ b/WebCore/dom/MessagePort.cpp
@@ -169,13 +169,7 @@ void MessagePort::dispatchMessages()
     OwnPtr<MessagePortChannel::EventData> eventData;
     while (m_entangledChannel && m_entangledChannel->tryGetMessageFromRemote(eventData)) {
         OwnPtr<MessagePortArray> ports = MessagePort::entanglePorts(*m_scriptExecutionContext, eventData->channels());
-        RefPtr<Event> evt = MessageEvent::create(eventData->message(), "", "", 0, ports.release());
-
-        if (m_onMessageListener) {
-            evt->setTarget(this);
-            evt->setCurrentTarget(this);
-            m_onMessageListener->handleEvent(evt.get(), false);
-        }
+        RefPtr<Event> evt = MessageEvent::create(ports.release(), eventData->message());
 
         ExceptionCode ec = 0;
         dispatchEvent(evt.release(), ec);
@@ -183,63 +177,6 @@ void MessagePort::dispatchMessages()
     }
 }
 
-void MessagePort::addEventListener(const AtomicString& eventType, PassRefPtr<EventListener> eventListener, bool)
-{
-    EventListenersMap::iterator iter = m_eventListeners.find(eventType);
-    if (iter == m_eventListeners.end()) {
-        ListenerVector listeners;
-        listeners.append(eventListener);
-        m_eventListeners.add(eventType, listeners);
-    } else {
-        ListenerVector& listeners = iter->second;
-        for (ListenerVector::iterator listenerIter = listeners.begin(); listenerIter != listeners.end(); ++listenerIter) {
-            if (**listenerIter == *eventListener)
-                return;
-        }
-        
-        listeners.append(eventListener);
-        m_eventListeners.add(eventType, listeners);
-    }    
-}
-
-void MessagePort::removeEventListener(const AtomicString& eventType, EventListener* eventListener, bool)
-{
-    EventListenersMap::iterator iter = m_eventListeners.find(eventType);
-    if (iter == m_eventListeners.end())
-        return;
-    
-    ListenerVector& listeners = iter->second;
-    for (ListenerVector::const_iterator listenerIter = listeners.begin(); listenerIter != listeners.end(); ++listenerIter) {
-        if (**listenerIter == *eventListener) {
-            listeners.remove(listenerIter - listeners.begin());
-            return;
-        }
-    }
-}
-
-bool MessagePort::dispatchEvent(PassRefPtr<Event> event, ExceptionCode& ec)
-{
-    if (!event || event->type().isEmpty()) {
-        ec = EventException::UNSPECIFIED_EVENT_TYPE_ERR;
-        return true;
-    }
-    
-    ListenerVector listenersCopy = m_eventListeners.get(event->type());
-    for (ListenerVector::const_iterator listenerIter = listenersCopy.begin(); listenerIter != listenersCopy.end(); ++listenerIter) {
-        event->setTarget(this);
-        event->setCurrentTarget(this);
-        listenerIter->get()->handleEvent(event.get(), false);
-    }
-    
-    return !event->defaultPrevented();
-}
-
-void MessagePort::setOnmessage(PassRefPtr<EventListener> eventListener)
-{
-    m_onMessageListener = eventListener;
-    start();
-}
-
 bool MessagePort::hasPendingActivity()
 {
     // The spec says that entangled message ports should always be treated as if they have a strong reference.
@@ -294,4 +231,14 @@ PassOwnPtr<MessagePortArray> MessagePort::entanglePorts(ScriptExecutionContext&
     return portArray;
 }
 
+EventTargetData* MessagePort::eventTargetData()
+{
+    return &m_eventTargetData;
+}
+
+EventTargetData* MessagePort::ensureEventTargetData()
+{
+    return &m_eventTargetData;
+}
+
 } // namespace WebCore
diff --git a/WebCore/dom/MessagePort.h b/WebCore/dom/MessagePort.h
index d042bc1..e649d5d 100644
--- a/WebCore/dom/MessagePort.h
+++ b/WebCore/dom/MessagePort.h
@@ -29,9 +29,9 @@
 
 #include "AtomicStringHash.h"
 #include "EventListener.h"
+#include "EventNames.h"
 #include "EventTarget.h"
 #include "MessagePortChannel.h"
-
 #include <wtf/HashMap.h>
 #include <wtf/OwnPtr.h>
 #include <wtf/PassOwnPtr.h>
@@ -87,21 +87,17 @@ namespace WebCore {
 
         void dispatchMessages();
 
-        virtual void addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture);
-        virtual void removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture);
-        virtual bool dispatchEvent(PassRefPtr<Event>, ExceptionCode&);
-
-        typedef Vector<RefPtr<EventListener> > ListenerVector;
-        typedef HashMap<AtomicString, ListenerVector> EventListenersMap;
-        EventListenersMap& eventListeners() { return m_eventListeners; }
-
         using RefCounted<MessagePort>::ref;
         using RefCounted<MessagePort>::deref;
 
         bool hasPendingActivity();
 
-        void setOnmessage(PassRefPtr<EventListener>);
-        EventListener* onmessage() const { return m_onMessageListener.get(); }
+        void setOnmessage(PassRefPtr<EventListener> listener)
+        {
+            setAttributeEventListener(eventNames().messageEvent, listener);
+            start();
+        }
+        EventListener* onmessage() { return getAttributeEventListener(eventNames().messageEvent); }
 
         // Returns null if there is no entangled port, or if the entangled port is run by a different thread.
         // Returns null otherwise.
@@ -114,16 +110,15 @@ namespace WebCore {
 
         virtual void refEventTarget() { ref(); }
         virtual void derefEventTarget() { deref(); }
+        virtual EventTargetData* eventTargetData();
+        virtual EventTargetData* ensureEventTargetData();
 
         OwnPtr<MessagePortChannel> m_entangledChannel;
 
         bool m_started;
 
         ScriptExecutionContext* m_scriptExecutionContext;
-
-        RefPtr<EventListener> m_onMessageListener;
-
-        EventListenersMap m_eventListeners;
+        EventTargetData m_eventTargetData;
     };
 
 } // namespace WebCore
diff --git a/WebCore/dom/MessagePort.idl b/WebCore/dom/MessagePort.idl
index 11ab757..a9149ec 100644
--- a/WebCore/dom/MessagePort.idl
+++ b/WebCore/dom/MessagePort.idl
@@ -28,6 +28,7 @@ module events {
 
     interface [
         CustomMarkFunction,
+        EventTarget,
         GenerateConstructor,
         NoStaticTables
     ] MessagePort {
diff --git a/WebCore/dom/MutationEvent.h b/WebCore/dom/MutationEvent.h
index c5f2d1d..29b978c 100644
--- a/WebCore/dom/MutationEvent.h
+++ b/WebCore/dom/MutationEvent.h
@@ -41,10 +41,11 @@ namespace WebCore {
         {
             return adoptRef(new MutationEvent);
         }
-        static PassRefPtr<MutationEvent> create(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtr<Node> relatedNode,
-            const String& prevValue, const String& newValue, const String& attrName, unsigned short attrChange)
+
+        static PassRefPtr<MutationEvent> create(const AtomicString& type, bool canBubble, PassRefPtr<Node> relatedNode = 0,
+            const String& prevValue = String(), const String& newValue = String(), const String& attrName = String(), unsigned short attrChange = 0)
         {
-            return adoptRef(new MutationEvent(type, canBubble, cancelable, relatedNode, prevValue, newValue, attrName, attrChange));
+            return adoptRef(new MutationEvent(type, canBubble, false, relatedNode, prevValue, newValue, attrName, attrChange));
         }
 
         void initMutationEvent(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtr<Node> relatedNode,
diff --git a/WebCore/dom/Node.cpp b/WebCore/dom/Node.cpp
index a26dd04..2240dd8 100644
--- a/WebCore/dom/Node.cpp
+++ b/WebCore/dom/Node.cpp
@@ -2342,16 +2342,6 @@ ScriptExecutionContext* Node::scriptExecutionContext() const
     return document();
 }
 
-const RegisteredEventListenerVector& Node::eventListeners() const
-{
-    if (hasRareData()) {
-        if (RegisteredEventListenerVector* listeners = rareData()->listeners())
-            return *listeners;
-    }
-    static const RegisteredEventListenerVector* emptyListenersVector = new RegisteredEventListenerVector;
-    return *emptyListenersVector;
-}
-
 void Node::insertedIntoDocument()
 {
     setInDocument(true);
@@ -2399,69 +2389,45 @@ static inline void updateSVGElementInstancesAfterEventListenerChange(Node* refer
 #endif
 }
 
-void Node::addEventListener(const AtomicString& eventType, PassRefPtr<EventListener> listener, bool useCapture)
+bool Node::addEventListener(const AtomicString& eventType, PassRefPtr<EventListener> listener, bool useCapture)
 {
+    if (!EventTarget::addEventListener(eventType, listener, useCapture))
+        return false;
+
     if (Document* document = this->document())
         document->addListenerTypeIfNeeded(eventType);
-
-    RegisteredEventListenerVector& listeners = ensureRareData()->ensureListeners();
-
-    // Remove existing identical listener set with identical arguments.
-    // The DOM2 spec says that "duplicate instances are discarded" in this case.
-    removeEventListener(eventType, listener.get(), useCapture);
-
-    listeners.append(RegisteredEventListener::create(eventType, listener, useCapture));
     updateSVGElementInstancesAfterEventListenerChange(this);
+    return true;
 }
 
-void Node::removeEventListener(const AtomicString& eventType, EventListener* listener, bool useCapture)
+bool Node::removeEventListener(const AtomicString& eventType, EventListener* listener, bool useCapture)
 {
-    if (!hasRareData())
-        return;
-
-    RegisteredEventListenerVector* listeners = rareData()->listeners();
-    if (!listeners)
-        return;
-
-    size_t size = listeners->size();
-    for (size_t i = 0; i < size; ++i) {
-        RegisteredEventListener& r = *listeners->at(i);
-        if (r.eventType() == eventType && r.useCapture() == useCapture && *r.listener() == *listener) {
-            r.setRemoved(true);
-            listeners->remove(i);
+    if (!EventTarget::removeEventListener(eventType, listener, useCapture))
+        return false;
 
-            updateSVGElementInstancesAfterEventListenerChange(this);
-            return;
-        }
-    }
+    updateSVGElementInstancesAfterEventListenerChange(this);
+    return true;
 }
 
-void Node::removeAllEventListenersSlowCase()
+EventTargetData* Node::eventTargetData()
 {
-    ASSERT(hasRareData());
-
-    RegisteredEventListenerVector* listeners = rareData()->listeners();
-    if (!listeners)
-        return;
+    return hasRareData() ? rareData()->eventTargetData() : 0;
+}
 
-    size_t size = listeners->size();
-    for (size_t i = 0; i < size; ++i)
-        listeners->at(i)->setRemoved(true);
-    listeners->clear();
+EventTargetData* Node::ensureEventTargetData()
+{
+    return ensureRareData()->ensureEventTargetData();
 }
 
-void Node::handleLocalEvents(Event* event, bool useCapture)
+void Node::handleLocalEvents(Event* event)
 {
+    if (!hasRareData() || !rareData()->eventTargetData())
+        return;
+
     if (disabled() && event->isMouseEvent())
         return;
 
-    RegisteredEventListenerVector listenersCopy = eventListeners();
-    size_t size = listenersCopy.size();
-    for (size_t i = 0; i < size; ++i) {
-        const RegisteredEventListener& r = *listenersCopy[i];
-        if (r.eventType() == event->type() && r.useCapture() == useCapture && !r.removed())
-            r.listener()->handleEvent(event, false);
-    }
+    fireEventListeners(event);
 }
 
 #if ENABLE(SVG)
@@ -2502,19 +2468,15 @@ static inline EventTarget* eventTargetRespectingSVGTargetRules(Node* referenceNo
     return referenceNode;
 }
 
-bool Node::dispatchEvent(PassRefPtr<Event> e, ExceptionCode& ec)
+bool Node::dispatchEvent(PassRefPtr<Event> prpEvent)
 {
-    RefPtr<Event> evt(e);
-    ASSERT(!eventDispatchForbidden());
-    if (!evt || evt->type().isEmpty()) { 
-        ec = EventException::UNSPECIFIED_EVENT_TYPE_ERR;
-        return false;
-    }
+    RefPtr<EventTarget> protect = this;
+    RefPtr<Event> event = prpEvent;
 
-    evt->setTarget(eventTargetRespectingSVGTargetRules(this));
+    event->setTarget(eventTargetRespectingSVGTargetRules(this));
 
     RefPtr<FrameView> view = document()->view();
-    return dispatchGenericEvent(evt.release());
+    return dispatchGenericEvent(event.release());
 }
 
 bool Node::dispatchGenericEvent(PassRefPtr<Event> prpEvent)
@@ -2567,27 +2529,22 @@ bool Node::dispatchGenericEvent(PassRefPtr<Event> prpEvent)
 
     if (targetForWindowEvents) {
         event->setCurrentTarget(targetForWindowEvents);
-        targetForWindowEvents->handleEvent(event.get(), true);
+        targetForWindowEvents->fireEventListeners(event.get());
         if (event->propagationStopped())
             goto doneDispatching;
     }
     for (size_t i = ancestors.size(); i; --i) {
         ContainerNode* ancestor = ancestors[i - 1].get();
         event->setCurrentTarget(eventTargetRespectingSVGTargetRules(ancestor));
-        ancestor->handleLocalEvents(event.get(), true);
+        ancestor->handleLocalEvents(event.get());
         if (event->propagationStopped())
             goto doneDispatching;
     }
 
     event->setEventPhase(Event::AT_TARGET);
 
-    // We do want capturing event listeners to be invoked here, even though
-    // that violates some versions of the DOM specification; Mozilla does it.
     event->setCurrentTarget(eventTargetRespectingSVGTargetRules(this));
-    handleLocalEvents(event.get(), true);
-    if (event->propagationStopped())
-        goto doneDispatching;
-    handleLocalEvents(event.get(), false);
+    handleLocalEvents(event.get());
     if (event->propagationStopped())
         goto doneDispatching;
 
@@ -2599,13 +2556,13 @@ bool Node::dispatchGenericEvent(PassRefPtr<Event> prpEvent)
         for (size_t i = 0; i < size; ++i) {
             ContainerNode* ancestor = ancestors[i].get();
             event->setCurrentTarget(eventTargetRespectingSVGTargetRules(ancestor));
-            ancestor->handleLocalEvents(event.get(), false);
+            ancestor->handleLocalEvents(event.get());
             if (event->propagationStopped() || event->cancelBubble())
                 goto doneDispatching;
         }
         if (targetForWindowEvents) {
             event->setCurrentTarget(targetForWindowEvents);
-            targetForWindowEvents->handleEvent(event.get(), false);
+            targetForWindowEvents->fireEventListeners(event.get());
             if (event->propagationStopped() || event->cancelBubble())
                 goto doneDispatching;
         }
@@ -2663,8 +2620,7 @@ void Node::dispatchSubtreeModifiedEvent()
     if (!document()->hasListenerType(Document::DOMSUBTREEMODIFIED_LISTENER))
         return;
 
-    ExceptionCode ec = 0;
-    dispatchMutationEvent(eventNames().DOMSubtreeModifiedEvent, true, 0, String(), String(), ec); 
+    dispatchEvent(MutationEvent::create(eventNames().DOMSubtreeModifiedEvent, true));
 }
 
 void Node::dispatchUIEvent(const AtomicString& eventType, int detail, PassRefPtr<Event> underlyingEvent)
@@ -2674,18 +2630,15 @@ void Node::dispatchUIEvent(const AtomicString& eventType, int detail, PassRefPtr
     
     bool cancelable = eventType == eventNames().DOMActivateEvent;
     
-    ExceptionCode ec = 0;
-    RefPtr<UIEvent> evt = UIEvent::create(eventType, true, cancelable, document()->defaultView(), detail);
-    evt->setUnderlyingEvent(underlyingEvent);
-    dispatchEvent(evt.release(), ec);
+    RefPtr<UIEvent> event = UIEvent::create(eventType, true, cancelable, document()->defaultView(), detail);
+    event->setUnderlyingEvent(underlyingEvent);
+    dispatchEvent(event.release());
 }
 
 bool Node::dispatchKeyEvent(const PlatformKeyboardEvent& key)
 {
-    ASSERT(!eventDispatchForbidden());
-    ExceptionCode ec = 0;
     RefPtr<KeyboardEvent> keyboardEvent = KeyboardEvent::create(key, document()->defaultView());
-    bool r = dispatchEvent(keyboardEvent, ec);
+    bool r = dispatchEvent(keyboardEvent);
     
     // we want to return false if default is prevented (already taken care of)
     // or if the element is default-handled by the DOM. Otherwise we let it just
@@ -2779,8 +2732,6 @@ bool Node::dispatchMouseEvent(const AtomicString& eventType, int button, int det
     
     bool cancelable = eventType != eventNames().mousemoveEvent;
     
-    ExceptionCode ec = 0;
-    
     bool swallowEvent = false;
     
     // Attempting to dispatch with a non-EventTarget relatedTarget causes the relatedTarget to be silently ignored.
@@ -2805,7 +2756,7 @@ bool Node::dispatchMouseEvent(const AtomicString& eventType, int button, int det
     mouseEvent->setUnderlyingEvent(underlyingEvent.get());
     mouseEvent->setAbsoluteLocation(IntPoint(pageX, pageY));
     
-    dispatchEvent(mouseEvent, ec);
+    dispatchEvent(mouseEvent);
     bool defaultHandled = mouseEvent->defaultHandled();
     bool defaultPrevented = mouseEvent->defaultPrevented();
     if (defaultHandled || defaultPrevented)
@@ -2823,7 +2774,7 @@ bool Node::dispatchMouseEvent(const AtomicString& eventType, int button, int det
         doubleClickEvent->setUnderlyingEvent(underlyingEvent.get());
         if (defaultHandled)
             doubleClickEvent->setDefaultHandled();
-        dispatchEvent(doubleClickEvent, ec);
+        dispatchEvent(doubleClickEvent);
         if (doubleClickEvent->defaultHandled() || doubleClickEvent->defaultPrevented())
             swallowEvent = true;
     }
@@ -2860,98 +2811,18 @@ void Node::dispatchWheelEvent(PlatformWheelEvent& e)
 
     we->setAbsoluteLocation(IntPoint(pos.x(), pos.y()));
 
-    ExceptionCode ec = 0;
-    if (!dispatchEvent(we.release(), ec))
+    if (!dispatchEvent(we.release()))
         e.accept();
 }
 
-void Node::dispatchWebKitAnimationEvent(const AtomicString& eventType, const String& animationName, double elapsedTime)
-{
-    ASSERT(!eventDispatchForbidden());
-    
-    ExceptionCode ec = 0;
-    dispatchEvent(WebKitAnimationEvent::create(eventType, animationName, elapsedTime), ec);
-}
-
-void Node::dispatchWebKitTransitionEvent(const AtomicString& eventType, const String& propertyName, double elapsedTime)
-{
-    ASSERT(!eventDispatchForbidden());
-    
-    ExceptionCode ec = 0;
-    dispatchEvent(WebKitTransitionEvent::create(eventType, propertyName, elapsedTime), ec);
-}
-
-void Node::dispatchMutationEvent(const AtomicString& eventType, bool canBubble, PassRefPtr<Node> relatedNode, const String& prevValue, const String& newValue, ExceptionCode& ec)
-{
-    ASSERT(!eventDispatchForbidden());
-
-    dispatchEvent(MutationEvent::create(eventType, canBubble, false, relatedNode, prevValue, newValue, String(), 0), ec);
-}
-
 void Node::dispatchFocusEvent()
 {
-    dispatchEvent(eventNames().focusEvent, false, false);
+    dispatchEvent(Event::create(eventNames().focusEvent, false, false));
 }
 
 void Node::dispatchBlurEvent()
 {
-    dispatchEvent(eventNames().blurEvent, false, false);
-}
-
-bool Node::dispatchEvent(const AtomicString& eventType, bool canBubbleArg, bool cancelableArg)
-{
-    ASSERT(!eventDispatchForbidden());
-    ExceptionCode ec = 0;
-    return dispatchEvent(Event::create(eventType, canBubbleArg, cancelableArg), ec);
-}
-
-void Node::dispatchProgressEvent(const AtomicString &eventType, bool lengthComputableArg, unsigned loadedArg, unsigned totalArg)
-{
-    ASSERT(!eventDispatchForbidden());
-    ExceptionCode ec = 0;
-    dispatchEvent(ProgressEvent::create(eventType, lengthComputableArg, loadedArg, totalArg), ec);
-}
-
-void Node::clearAttributeEventListener(const AtomicString& eventType)
-{
-    if (!hasRareData())
-        return;
-
-    RegisteredEventListenerVector* listeners = rareData()->listeners();
-    if (!listeners)
-        return;
-
-    size_t size = listeners->size();
-    for (size_t i = 0; i < size; ++i) {
-        RegisteredEventListener& r = *listeners->at(i);
-        if (r.eventType() != eventType || !r.listener()->isAttribute())
-            continue;
-
-        r.setRemoved(true);
-        listeners->remove(i);
-
-        updateSVGElementInstancesAfterEventListenerChange(this);
-        return;
-    }
-}
-
-void Node::setAttributeEventListener(const AtomicString& eventType, PassRefPtr<EventListener> listener)
-{
-    clearAttributeEventListener(eventType);
-    if (listener)
-        addEventListener(eventType, listener, false);
-}
-
-EventListener* Node::getAttributeEventListener(const AtomicString& eventType) const
-{
-    const RegisteredEventListenerVector& listeners = eventListeners();
-    size_t size = listeners.size();
-    for (size_t i = 0; i < size; ++i) {
-        const RegisteredEventListener& r = *listeners[i];
-        if (r.eventType() == eventType && r.listener()->isAttribute())
-            return r.listener();
-    }
-    return 0;
+    dispatchEvent(Event::create(eventNames().blurEvent, false, false));
 }
 
 bool Node::disabled() const
@@ -2984,396 +2855,6 @@ void Node::defaultEventHandler(Event* event)
     }
 }
 
-EventListener* Node::onabort() const
-{
-    return getAttributeEventListener(eventNames().abortEvent);
-}
-
-void Node::setOnabort(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().abortEvent, eventListener);
-}
-
-EventListener* Node::onblur() const
-{
-    return getAttributeEventListener(eventNames().blurEvent);
-}
-
-void Node::setOnblur(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().blurEvent, eventListener);
-}
-
-EventListener* Node::onchange() const
-{
-    return getAttributeEventListener(eventNames().changeEvent);
-}
-
-void Node::setOnchange(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().changeEvent, eventListener);
-}
-
-EventListener* Node::onclick() const
-{
-    return getAttributeEventListener(eventNames().clickEvent);
-}
-
-void Node::setOnclick(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().clickEvent, eventListener);
-}
-
-EventListener* Node::oncontextmenu() const
-{
-    return getAttributeEventListener(eventNames().contextmenuEvent);
-}
-
-void Node::setOncontextmenu(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().contextmenuEvent, eventListener);
-}
-
-EventListener* Node::ondblclick() const
-{
-    return getAttributeEventListener(eventNames().dblclickEvent);
-}
-
-void Node::setOndblclick(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().dblclickEvent, eventListener);
-}
-
-EventListener* Node::onerror() const
-{
-    return getAttributeEventListener(eventNames().errorEvent);
-}
-
-void Node::setOnerror(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().errorEvent, eventListener);
-}
-
-EventListener* Node::onfocus() const
-{
-    return getAttributeEventListener(eventNames().focusEvent);
-}
-
-void Node::setOnfocus(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().focusEvent, eventListener);
-}
-
-EventListener* Node::oninput() const
-{
-    return getAttributeEventListener(eventNames().inputEvent);
-}
-
-void Node::setOninput(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().inputEvent, eventListener);
-}
-
-EventListener* Node::oninvalid() const
-{
-    return getAttributeEventListener(eventNames().invalidEvent);
-}
-
-void Node::setOninvalid(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().invalidEvent, eventListener);
-}
-
-EventListener* Node::onkeydown() const
-{
-    return getAttributeEventListener(eventNames().keydownEvent);
-}
-
-void Node::setOnkeydown(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().keydownEvent, eventListener);
-}
-
-EventListener* Node::onkeypress() const
-{
-    return getAttributeEventListener(eventNames().keypressEvent);
-}
-
-void Node::setOnkeypress(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().keypressEvent, eventListener);
-}
-
-EventListener* Node::onkeyup() const
-{
-    return getAttributeEventListener(eventNames().keyupEvent);
-}
-
-void Node::setOnkeyup(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().keyupEvent, eventListener);
-}
-
-EventListener* Node::onload() const
-{
-    return getAttributeEventListener(eventNames().loadEvent);
-}
-
-void Node::setOnload(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().loadEvent, eventListener);
-}
-
-EventListener* Node::onmousedown() const
-{
-    return getAttributeEventListener(eventNames().mousedownEvent);
-}
-
-void Node::setOnmousedown(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().mousedownEvent, eventListener);
-}
-
-EventListener* Node::onmousemove() const
-{
-    return getAttributeEventListener(eventNames().mousemoveEvent);
-}
-
-void Node::setOnmousemove(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().mousemoveEvent, eventListener);
-}
-
-EventListener* Node::onmouseout() const
-{
-    return getAttributeEventListener(eventNames().mouseoutEvent);
-}
-
-void Node::setOnmouseout(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().mouseoutEvent, eventListener);
-}
-
-EventListener* Node::onmouseover() const
-{
-    return getAttributeEventListener(eventNames().mouseoverEvent);
-}
-
-void Node::setOnmouseover(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().mouseoverEvent, eventListener);
-}
-
-EventListener* Node::onmouseup() const
-{
-    return getAttributeEventListener(eventNames().mouseupEvent);
-}
-
-void Node::setOnmouseup(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().mouseupEvent, eventListener);
-}
-
-EventListener* Node::onmousewheel() const
-{
-    return getAttributeEventListener(eventNames().mousewheelEvent);
-}
-
-void Node::setOnmousewheel(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().mousewheelEvent, eventListener);
-}
-
-EventListener* Node::ondragenter() const
-{
-    return getAttributeEventListener(eventNames().dragenterEvent);
-}
-
-void Node::setOndragenter(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().dragenterEvent, eventListener);
-}
-
-EventListener* Node::ondragover() const
-{
-    return getAttributeEventListener(eventNames().dragoverEvent);
-}
-
-void Node::setOndragover(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().dragoverEvent, eventListener);
-}
-
-EventListener* Node::ondragleave() const
-{
-    return getAttributeEventListener(eventNames().dragleaveEvent);
-}
-
-void Node::setOndragleave(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().dragleaveEvent, eventListener);
-}
-
-EventListener* Node::ondrop() const
-{
-    return getAttributeEventListener(eventNames().dropEvent);
-}
-
-void Node::setOndrop(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().dropEvent, eventListener);
-}
-
-EventListener* Node::ondragstart() const
-{
-    return getAttributeEventListener(eventNames().dragstartEvent);
-}
-
-void Node::setOndragstart(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().dragstartEvent, eventListener);
-}
-
-EventListener* Node::ondrag() const
-{
-    return getAttributeEventListener(eventNames().dragEvent);
-}
-
-void Node::setOndrag(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().dragEvent, eventListener);
-}
-
-EventListener* Node::ondragend() const
-{
-    return getAttributeEventListener(eventNames().dragendEvent);
-}
-
-void Node::setOndragend(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().dragendEvent, eventListener);
-}
-
-EventListener* Node::onscroll() const
-{
-    return getAttributeEventListener(eventNames().scrollEvent);
-}
-
-void Node::setOnscroll(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().scrollEvent, eventListener);
-}
-
-EventListener* Node::onselect() const
-{
-    return getAttributeEventListener(eventNames().selectEvent);
-}
-
-void Node::setOnselect(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().selectEvent, eventListener);
-}
-
-EventListener* Node::onsubmit() const
-{
-    return getAttributeEventListener(eventNames().submitEvent);
-}
-
-void Node::setOnsubmit(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().submitEvent, eventListener);
-}
-
-EventListener* Node::onbeforecut() const
-{
-    return getAttributeEventListener(eventNames().beforecutEvent);
-}
-
-void Node::setOnbeforecut(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().beforecutEvent, eventListener);
-}
-
-EventListener* Node::oncut() const
-{
-    return getAttributeEventListener(eventNames().cutEvent);
-}
-
-void Node::setOncut(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().cutEvent, eventListener);
-}
-
-EventListener* Node::onbeforecopy() const
-{
-    return getAttributeEventListener(eventNames().beforecopyEvent);
-}
-
-void Node::setOnbeforecopy(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().beforecopyEvent, eventListener);
-}
-
-EventListener* Node::oncopy() const
-{
-    return getAttributeEventListener(eventNames().copyEvent);
-}
-
-void Node::setOncopy(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().copyEvent, eventListener);
-}
-
-EventListener* Node::onbeforepaste() const
-{
-    return getAttributeEventListener(eventNames().beforepasteEvent);
-}
-
-void Node::setOnbeforepaste(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().beforepasteEvent, eventListener);
-}
-
-EventListener* Node::onpaste() const
-{
-    return getAttributeEventListener(eventNames().pasteEvent);
-}
-
-void Node::setOnpaste(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().pasteEvent, eventListener);
-}
-
-EventListener* Node::onreset() const
-{
-    return getAttributeEventListener(eventNames().resetEvent);
-}
-
-void Node::setOnreset(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().resetEvent, eventListener);
-}
-
-EventListener* Node::onsearch() const
-{
-    return getAttributeEventListener(eventNames().searchEvent);
-}
-
-void Node::setOnsearch(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().searchEvent, eventListener);
-}
-
-EventListener* Node::onselectstart() const
-{
-    return getAttributeEventListener(eventNames().selectstartEvent);
-}
-
-void Node::setOnselectstart(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().selectstartEvent, eventListener);
-}
-
 } // namespace WebCore
 
 #ifndef NDEBUG
diff --git a/WebCore/dom/Node.h b/WebCore/dom/Node.h
index 4f70b87..f3bebc6 100644
--- a/WebCore/dom/Node.h
+++ b/WebCore/dom/Node.h
@@ -512,19 +512,19 @@ public:
 
     virtual ScriptExecutionContext* scriptExecutionContext() const;
 
-    // Used for standard DOM addEventListener / removeEventListener APIs.
-    virtual void addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture);
-    virtual void removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture);
+    virtual bool addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture);
+    virtual bool removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture);
 
-    // Used for legacy "onEvent" property APIs.
-    void setAttributeEventListener(const AtomicString& eventType, PassRefPtr<EventListener>);
-    void clearAttributeEventListener(const AtomicString& eventType);
-    EventListener* getAttributeEventListener(const AtomicString& eventType) const;
+    // Handlers to do/undo actions on the target node before an event is dispatched to it and after the event
+    // has been dispatched.  The data pointer is handed back by the preDispatch and passed to postDispatch.
+    virtual void* preDispatchEventHandler(Event*) { return 0; }
+    virtual void postDispatchEventHandler(Event*, void* /*dataFromPreDispatch*/) { }
 
-    virtual bool dispatchEvent(PassRefPtr<Event>, ExceptionCode&);
-    bool dispatchEvent(const AtomicString& eventType, bool canBubble, bool cancelable);
+    using EventTarget::dispatchEvent;
+    virtual bool dispatchEvent(PassRefPtr<Event>);
 
-    void removeAllEventListeners() { if (hasRareData()) removeAllEventListenersSlowCase(); }
+    bool dispatchGenericEvent(PassRefPtr<Event>);
+    virtual void handleLocalEvents(Event*);
 
     void dispatchSubtreeModifiedEvent();
     void dispatchUIEvent(const AtomicString& eventType, int detail, PassRefPtr<Event> underlyingEvent);
@@ -538,14 +538,6 @@ public:
         bool isSimulated, Node* relatedTarget, PassRefPtr<Event> underlyingEvent);
     void dispatchSimulatedMouseEvent(const AtomicString& eventType, PassRefPtr<Event> underlyingEvent);
     void dispatchSimulatedClick(PassRefPtr<Event> underlyingEvent, bool sendMouseEvents = false, bool showPressedLook = true);
-    void dispatchProgressEvent(const AtomicString& eventType, bool lengthComputableArg, unsigned loadedArg, unsigned totalArg);
-    void dispatchWebKitAnimationEvent(const AtomicString& eventType, const String& animationName, double elapsedTime);
-    void dispatchWebKitTransitionEvent(const AtomicString& eventType, const String& propertyName, double elapsedTime);
-    void dispatchMutationEvent(const AtomicString& type, bool canBubble, PassRefPtr<Node> relatedNode, const String& prevValue, const String& newValue, ExceptionCode&);
-
-    bool dispatchGenericEvent(PassRefPtr<Event>);
-
-    virtual void handleLocalEvents(Event*, bool useCapture);
 
     virtual void dispatchFocusEvent();
     virtual void dispatchBlurEvent();
@@ -561,95 +553,12 @@ public:
      */
     virtual bool disabled() const;
 
-    const RegisteredEventListenerVector& eventListeners() const;
-
-    // These 4 attribute event handler attributes are overrided by HTMLBodyElement
-    // and HTMLFrameSetElement to forward to the DOMWindow.
-    virtual EventListener* onblur() const;
-    virtual void setOnblur(PassRefPtr<EventListener>);
-    virtual EventListener* onerror() const;
-    virtual void setOnerror(PassRefPtr<EventListener>);
-    virtual EventListener* onfocus() const;
-    virtual void setOnfocus(PassRefPtr<EventListener>);
-    virtual EventListener* onload() const;
-    virtual void setOnload(PassRefPtr<EventListener>);
-
-    EventListener* onabort() const;
-    void setOnabort(PassRefPtr<EventListener>);
-    EventListener* onchange() const;
-    void setOnchange(PassRefPtr<EventListener>);
-    EventListener* onclick() const;
-    void setOnclick(PassRefPtr<EventListener>);
-    EventListener* oncontextmenu() const;
-    void setOncontextmenu(PassRefPtr<EventListener>);
-    EventListener* ondblclick() const;
-    void setOndblclick(PassRefPtr<EventListener>);
-    EventListener* ondragenter() const;
-    void setOndragenter(PassRefPtr<EventListener>);
-    EventListener* ondragover() const;
-    void setOndragover(PassRefPtr<EventListener>);
-    EventListener* ondragleave() const;
-    void setOndragleave(PassRefPtr<EventListener>);
-    EventListener* ondrop() const;
-    void setOndrop(PassRefPtr<EventListener>);
-    EventListener* ondragstart() const;
-    void setOndragstart(PassRefPtr<EventListener>);
-    EventListener* ondrag() const;
-    void setOndrag(PassRefPtr<EventListener>);
-    EventListener* ondragend() const;
-    void setOndragend(PassRefPtr<EventListener>);
-    EventListener* oninput() const;
-    void setOninput(PassRefPtr<EventListener>);
-    EventListener* oninvalid() const;
-    void setOninvalid(PassRefPtr<EventListener>);
-    EventListener* onkeydown() const;
-    void setOnkeydown(PassRefPtr<EventListener>);
-    EventListener* onkeypress() const;
-    void setOnkeypress(PassRefPtr<EventListener>);
-    EventListener* onkeyup() const;
-    void setOnkeyup(PassRefPtr<EventListener>);
-    EventListener* onmousedown() const;
-    void setOnmousedown(PassRefPtr<EventListener>);
-    EventListener* onmousemove() const;
-    void setOnmousemove(PassRefPtr<EventListener>);
-    EventListener* onmouseout() const;
-    void setOnmouseout(PassRefPtr<EventListener>);
-    EventListener* onmouseover() const;
-    void setOnmouseover(PassRefPtr<EventListener>);
-    EventListener* onmouseup() const;
-    void setOnmouseup(PassRefPtr<EventListener>);
-    EventListener* onmousewheel() const;
-    void setOnmousewheel(PassRefPtr<EventListener>);
-    EventListener* onscroll() const;
-    void setOnscroll(PassRefPtr<EventListener>);
-    EventListener* onselect() const;
-    void setOnselect(PassRefPtr<EventListener>);
-    EventListener* onsubmit() const;
-    void setOnsubmit(PassRefPtr<EventListener>);
-
-    // WebKit extensions
-    EventListener* onbeforecut() const;
-    void setOnbeforecut(PassRefPtr<EventListener>);
-    EventListener* oncut() const;
-    void setOncut(PassRefPtr<EventListener>);
-    EventListener* onbeforecopy() const;
-    void setOnbeforecopy(PassRefPtr<EventListener>);
-    EventListener* oncopy() const;
-    void setOncopy(PassRefPtr<EventListener>);
-    EventListener* onbeforepaste() const;
-    void setOnbeforepaste(PassRefPtr<EventListener>);
-    EventListener* onpaste() const;
-    void setOnpaste(PassRefPtr<EventListener>);
-    EventListener* onreset() const;
-    void setOnreset(PassRefPtr<EventListener>);
-    EventListener* onsearch() const;
-    void setOnsearch(PassRefPtr<EventListener>);
-    EventListener* onselectstart() const;
-    void setOnselectstart(PassRefPtr<EventListener>);
-
     using TreeShared<Node>::ref;
     using TreeShared<Node>::deref;
 
+    virtual EventTargetData* eventTargetData();
+    virtual EventTargetData* ensureEventTargetData();
+
 protected:
     // CreateElementZeroRefCount is deprecated and can be removed once we convert all element
     // classes to start with a reference count of 1.
diff --git a/WebCore/dom/Node.idl b/WebCore/dom/Node.idl
index 1e31aea..45ea132 100644
--- a/WebCore/dom/Node.idl
+++ b/WebCore/dom/Node.idl
@@ -24,6 +24,7 @@ module core {
         CustomMarkFunction,
         CustomPushEventHandlerScope,
         CustomToJS,
+        EventTarget,
         GenerateConstructor,
         GenerateNativeConverter,
         InlineGetOwnPropertySlot,
diff --git a/WebCore/dom/NodeRareData.h b/WebCore/dom/NodeRareData.h
index 7740344..8b9e1bf 100644
--- a/WebCore/dom/NodeRareData.h
+++ b/WebCore/dom/NodeRareData.h
@@ -93,12 +93,12 @@ public:
     void setTabIndexExplicitly(short index) { m_tabIndex = index; m_tabIndexWasSetExplicitly = true; }
     bool tabIndexSetExplicitly() const { return m_tabIndexWasSetExplicitly; }
 
-    RegisteredEventListenerVector* listeners() { return m_eventListeners.get(); }
-    RegisteredEventListenerVector& ensureListeners()
+    EventTargetData* eventTargetData() { return m_eventTargetData.get(); }
+    EventTargetData* ensureEventTargetData()
     {
-        if (!m_eventListeners)
-            m_eventListeners.set(new RegisteredEventListenerVector);
-        return *m_eventListeners;
+        if (!m_eventTargetData)
+            m_eventTargetData.set(new EventTargetData);
+        return m_eventTargetData.get();
     }
 
     bool isFocused() const { return m_isFocused; }
@@ -111,7 +111,7 @@ protected:
 
 private:
     OwnPtr<NodeListsNodeData> m_nodeLists;
-    OwnPtr<RegisteredEventListenerVector > m_eventListeners;
+    OwnPtr<EventTargetData> m_eventTargetData;
     short m_tabIndex;
     bool m_tabIndexWasSetExplicitly : 1;
     bool m_isFocused : 1;
diff --git a/WebCore/dom/RegisteredEventListener.cpp b/WebCore/dom/RegisteredEventListener.cpp
index f257e56..e8bc594 100644
--- a/WebCore/dom/RegisteredEventListener.cpp
+++ b/WebCore/dom/RegisteredEventListener.cpp
@@ -27,12 +27,4 @@
 
 namespace WebCore {
 
-RegisteredEventListener::RegisteredEventListener(const AtomicString& eventType, PassRefPtr<EventListener> listener, bool useCapture)
-    : m_eventType(eventType)
-    , m_listener(listener)
-    , m_useCapture(useCapture)
-    , m_removed(false)
-{
-}
-
 } // namespace WebCore
diff --git a/WebCore/dom/RegisteredEventListener.h b/WebCore/dom/RegisteredEventListener.h
index 034f6c3..88d2279 100644
--- a/WebCore/dom/RegisteredEventListener.h
+++ b/WebCore/dom/RegisteredEventListener.h
@@ -29,47 +29,21 @@
 
 namespace WebCore {
 
-    class RegisteredEventListener : public RefCounted<RegisteredEventListener> {
-    public:
-        static PassRefPtr<RegisteredEventListener> create(const AtomicString& eventType, PassRefPtr<EventListener> listener, bool useCapture)
+    struct RegisteredEventListener {
+        RegisteredEventListener(PassRefPtr<EventListener> listener, bool useCapture)
+            : listener(listener)
+            , useCapture(useCapture)
         {
-            return adoptRef(new RegisteredEventListener(eventType, listener, useCapture));
         }
 
-        const AtomicString& eventType() const { return m_eventType; }
-        EventListener* listener() const { return m_listener.get(); }
-        bool useCapture() const { return m_useCapture; }
-        
-        bool removed() const { return m_removed; }
-        void setRemoved(bool removed) { m_removed = removed; }
-    
-    private:
-        RegisteredEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture);
-
-        AtomicString m_eventType;
-        RefPtr<EventListener> m_listener;
-        bool m_useCapture;
-        bool m_removed;
+        RefPtr<EventListener> listener;
+        bool useCapture;
     };
-
-    typedef Vector<RefPtr<RegisteredEventListener> > RegisteredEventListenerVector;
-
-#if USE(JSC)
-    inline void markEventListeners(JSC::MarkStack& markStack, const RegisteredEventListenerVector& listeners)
-    {
-        for (size_t i = 0; i < listeners.size(); ++i)
-            listeners[i]->listener()->markJSFunction(markStack);
-    }
-
-    inline void invalidateEventListeners(const RegisteredEventListenerVector& listeners)
+    
+    inline bool operator==(const RegisteredEventListener& a, const RegisteredEventListener& b)
     {
-        // For efficiency's sake, we just set the "removed" bit, instead of
-        // actually removing the event listener. The node that owns these
-        // listeners is about to be deleted, anyway.
-        for (size_t i = 0; i < listeners.size(); ++i)
-            listeners[i]->setRemoved(true);
+        return *a.listener == *b.listener && a.useCapture == b.useCapture;
     }
-#endif
 
 } // namespace WebCore
 
diff --git a/WebCore/history/CachedFrame.cpp b/WebCore/history/CachedFrame.cpp
index d542554..16c7087 100644
--- a/WebCore/history/CachedFrame.cpp
+++ b/WebCore/history/CachedFrame.cpp
@@ -29,11 +29,13 @@
 #include "CachedFramePlatformData.h"
 #include "CString.h"
 #include "DocumentLoader.h"
+#include "ExceptionCode.h"
 #include "EventNames.h"
 #include "Frame.h"
 #include "FrameLoaderClient.h"
 #include "FrameView.h"
 #include "Logging.h"
+#include "PageTransitionEvent.h"
 #include <wtf/RefCountedLeakCounter.h>
 
 #if ENABLE(SVG)
@@ -97,7 +99,7 @@ void CachedFrameBase::restore()
     for (unsigned i = 0; i < m_childFrames.size(); ++i)
         m_childFrames[i]->open();
 
-    m_document->dispatchPageTransitionEvent(EventNames().pageshowEvent, true);
+    m_document->dispatchWindowEvent(PageTransitionEvent::create(EventNames().pageshowEvent, true), m_document);
 }
 
 CachedFrame::CachedFrame(Frame* frame)
diff --git a/WebCore/html/HTMLBodyElement.cpp b/WebCore/html/HTMLBodyElement.cpp
index 924b8f6..a356bf3 100644
--- a/WebCore/html/HTMLBodyElement.cpp
+++ b/WebCore/html/HTMLBodyElement.cpp
@@ -326,136 +326,4 @@ void HTMLBodyElement::didMoveToNewOwnerDocument()
     HTMLElement::didMoveToNewOwnerDocument();
 }
 
-EventListener* HTMLBodyElement::onblur() const
-{
-    return document()->getWindowAttributeEventListener(eventNames().blurEvent);
-}
-
-void HTMLBodyElement::setOnblur(PassRefPtr<EventListener> eventListener)
-{
-    document()->setWindowAttributeEventListener(eventNames().blurEvent, eventListener);
-}
-
-EventListener* HTMLBodyElement::onerror() const
-{
-    return document()->getWindowAttributeEventListener(eventNames().errorEvent);
-}
-
-void HTMLBodyElement::setOnerror(PassRefPtr<EventListener> eventListener)
-{
-    document()->setWindowAttributeEventListener(eventNames().errorEvent, eventListener);
-}
-
-EventListener* HTMLBodyElement::onfocus() const
-{
-    return document()->getWindowAttributeEventListener(eventNames().focusEvent);
-}
-
-void HTMLBodyElement::setOnfocus(PassRefPtr<EventListener> eventListener)
-{
-    document()->setWindowAttributeEventListener(eventNames().focusEvent, eventListener);
-}
-
-EventListener* HTMLBodyElement::onload() const
-{
-    return document()->getWindowAttributeEventListener(eventNames().loadEvent);
-}
-
-void HTMLBodyElement::setOnload(PassRefPtr<EventListener> eventListener)
-{
-    document()->setWindowAttributeEventListener(eventNames().loadEvent, eventListener);
-}
-
-EventListener* HTMLBodyElement::onbeforeunload() const
-{
-    return document()->getWindowAttributeEventListener(eventNames().beforeunloadEvent);
-}
-
-void HTMLBodyElement::setOnbeforeunload(PassRefPtr<EventListener> eventListener)
-{
-    document()->setWindowAttributeEventListener(eventNames().beforeunloadEvent, eventListener);
-}
-
-EventListener* HTMLBodyElement::onhashchange() const
-{
-    return document()->getWindowAttributeEventListener(eventNames().hashchangeEvent);
-}
-
-void HTMLBodyElement::setOnhashchange(PassRefPtr<EventListener> eventListener)
-{
-    document()->setWindowAttributeEventListener(eventNames().hashchangeEvent, eventListener);
-}    
-                                                                                
-EventListener* HTMLBodyElement::onmessage() const
-{
-    return document()->getWindowAttributeEventListener(eventNames().messageEvent);
-}
-
-void HTMLBodyElement::setOnmessage(PassRefPtr<EventListener> eventListener)
-{
-    document()->setWindowAttributeEventListener(eventNames().messageEvent, eventListener);
-}
-
-EventListener* HTMLBodyElement::onoffline() const
-{
-    return document()->getWindowAttributeEventListener(eventNames().offlineEvent);
-}
-
-void HTMLBodyElement::setOnoffline(PassRefPtr<EventListener> eventListener)
-{
-    document()->setWindowAttributeEventListener(eventNames().offlineEvent, eventListener);
-}
-
-EventListener* HTMLBodyElement::ononline() const
-{
-    return document()->getWindowAttributeEventListener(eventNames().onlineEvent);
-}
-
-void HTMLBodyElement::setOnonline(PassRefPtr<EventListener> eventListener)
-{
-    document()->setWindowAttributeEventListener(eventNames().onlineEvent, eventListener);
-}
-
-#if ENABLE(ORIENTATION_EVENTS)
-EventListener* HTMLBodyElement::onorientationchange() const
-{
-    return document()->getWindowAttributeEventListener(eventNames().orientationchangeEvent);
-}
-
-void HTMLBodyElement::setOnorientationchange(PassRefPtr<EventListener> eventListener)
-{
-    document()->setWindowAttributeEventListener(eventNames().orientationchangeEvent, eventListener);
-}
-#endif
-
-EventListener* HTMLBodyElement::onresize() const
-{
-    return document()->getWindowAttributeEventListener(eventNames().resizeEvent);
-}
-
-void HTMLBodyElement::setOnresize(PassRefPtr<EventListener> eventListener)
-{
-    document()->setWindowAttributeEventListener(eventNames().resizeEvent, eventListener);
-}
-
-EventListener* HTMLBodyElement::onstorage() const
-{
-    return document()->getWindowAttributeEventListener(eventNames().storageEvent);
-}
-
-void HTMLBodyElement::setOnstorage(PassRefPtr<EventListener> eventListener)
-{
-    document()->setWindowAttributeEventListener(eventNames().storageEvent, eventListener);
-}
-
-EventListener* HTMLBodyElement::onunload() const
-{
-    return document()->getWindowAttributeEventListener(eventNames().unloadEvent);
-}
-
-void HTMLBodyElement::setOnunload(PassRefPtr<EventListener> eventListener)
-{
-    document()->setWindowAttributeEventListener(eventNames().unloadEvent, eventListener);
-}
-
 } // namespace WebCore
diff --git a/WebCore/html/HTMLBodyElement.h b/WebCore/html/HTMLBodyElement.h
index e0d4996..e898c88 100644
--- a/WebCore/html/HTMLBodyElement.h
+++ b/WebCore/html/HTMLBodyElement.h
@@ -25,6 +25,7 @@
 #define HTMLBodyElement_h
 
 #include "HTMLElement.h"
+#include "Document.h"
 
 namespace WebCore {
 
@@ -44,35 +45,23 @@ public:
     String vLink() const;
     void setVLink(const String&);
 
-    virtual EventListener* onblur() const;
-    virtual void setOnblur(PassRefPtr<EventListener>);
-    virtual EventListener* onerror() const;
-    virtual void setOnerror(PassRefPtr<EventListener>);
-    virtual EventListener* onfocus() const;
-    virtual void setOnfocus(PassRefPtr<EventListener>);
-    virtual EventListener* onload() const;
-    virtual void setOnload(PassRefPtr<EventListener>);
+    // Declared virtual in Element
+    DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(blur);
+    DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(error);
+    DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(focus);
+    DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(load);
 
-    EventListener* onbeforeunload() const;
-    void setOnbeforeunload(PassRefPtr<EventListener>);
-    EventListener* onmessage() const;
-    void setOnmessage(PassRefPtr<EventListener>);
-    EventListener* onhashchange() const;
-    void setOnhashchange(PassRefPtr<EventListener>);
-    EventListener* onoffline() const;
-    void setOnoffline(PassRefPtr<EventListener>);
-    EventListener* ononline() const;
-    void setOnonline(PassRefPtr<EventListener>);
+    DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(beforeunload);
+    DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(message);
+    DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(hashchange);
+    DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(offline);
+    DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(online);
+    DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(resize);
+    DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(storage);
+    DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(unload);
 #if ENABLE(ORIENTATION_EVENTS)
-    EventListener* onorientationchange() const;
-    void setOnorientationchange(PassRefPtr<EventListener>);
+    DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(orientationchange);
 #endif
-    EventListener* onresize() const;
-    void setOnresize(PassRefPtr<EventListener>);
-    EventListener* onstorage() const;
-    void setOnstorage(PassRefPtr<EventListener>);
-    EventListener* onunload() const;
-    void setOnunload(PassRefPtr<EventListener>);
 
 private:
     virtual HTMLTagStatus endTagRequirement() const { return TagStatusRequired; }
diff --git a/WebCore/html/HTMLFormControlElement.cpp b/WebCore/html/HTMLFormControlElement.cpp
index 61e112c..bc74ecf 100644
--- a/WebCore/html/HTMLFormControlElement.cpp
+++ b/WebCore/html/HTMLFormControlElement.cpp
@@ -27,6 +27,7 @@
 
 #include "ChromeClient.h"
 #include "Document.h"
+#include "Event.h"
 #include "EventHandler.h"
 #include "EventNames.h"
 #include "Frame.h"
@@ -186,7 +187,7 @@ void HTMLFormControlElement::setName(const AtomicString &value)
 
 void HTMLFormControlElement::dispatchFormControlChangeEvent()
 {
-    dispatchEvent(eventNames().changeEvent, true, false);
+    dispatchEvent(Event::create(eventNames().changeEvent, true, false));
 }
 
 bool HTMLFormControlElement::disabled() const
@@ -282,7 +283,7 @@ bool HTMLFormControlElement::willValidate() const
 bool HTMLFormControlElement::checkValidity()
 {
     if (willValidate() && !isValidFormControlElement()) {
-        dispatchEvent(EventNames().invalidEvent, false, true);
+        dispatchEvent(Event::create(EventNames().invalidEvent, false, true));
         return false;
     }
 
diff --git a/WebCore/html/HTMLFormElement.cpp b/WebCore/html/HTMLFormElement.cpp
index 9f2d7c2..ace0f2f 100644
--- a/WebCore/html/HTMLFormElement.cpp
+++ b/WebCore/html/HTMLFormElement.cpp
@@ -150,14 +150,14 @@ void HTMLFormElement::removedFromDocument()
     HTMLElement::removedFromDocument();
 }
 
-void HTMLFormElement::handleLocalEvents(Event* event, bool useCapture)
+void HTMLFormElement::handleLocalEvents(Event* event)
 {
     Node* targetNode = event->target()->toNode();
-    if (!useCapture && targetNode && targetNode != this && (event->type() == eventNames().submitEvent || event->type() == eventNames().resetEvent)) {
+    if (event->eventPhase() != Event::CAPTURING_PHASE && targetNode && targetNode != this && (event->type() == eventNames().submitEvent || event->type() == eventNames().resetEvent)) {
         event->stopPropagation();
         return;
     }
-    HTMLElement::handleLocalEvents(event, useCapture);
+    HTMLElement::handleLocalEvents(event);
 }
 
 unsigned HTMLFormElement::length() const
@@ -296,7 +296,7 @@ bool HTMLFormElement::prepareSubmit(Event* event)
     m_insubmit = true;
     m_doingsubmit = false;
 
-    if (dispatchEvent(eventNames().submitEvent, true, true) && !m_doingsubmit)
+    if (dispatchEvent(Event::create(eventNames().submitEvent, true, true)) && !m_doingsubmit)
         m_doingsubmit = true;
 
     m_insubmit = false;
@@ -416,7 +416,7 @@ void HTMLFormElement::reset()
 
     // ### DOM2 labels this event as not cancelable, however
     // common browsers( sick! ) allow it be cancelled.
-    if ( !dispatchEvent(eventNames().resetEvent, true, true) ) {
+    if (!dispatchEvent(Event::create(eventNames().resetEvent, true, true))) {
         m_inreset = false;
         return;
     }
diff --git a/WebCore/html/HTMLFormElement.h b/WebCore/html/HTMLFormElement.h
index af81fcc..a2e9585 100644
--- a/WebCore/html/HTMLFormElement.h
+++ b/WebCore/html/HTMLFormElement.h
@@ -54,7 +54,7 @@ public:
     virtual void insertedIntoDocument();
     virtual void removedFromDocument();
  
-    virtual void handleLocalEvents(Event*, bool useCapture);
+    virtual void handleLocalEvents(Event*);
      
     PassRefPtr<HTMLCollection> elements();
     void getNamedElements(const AtomicString&, Vector<RefPtr<Node> >&);
diff --git a/WebCore/html/HTMLFrameSetElement.cpp b/WebCore/html/HTMLFrameSetElement.cpp
index 79381be..cbeba87 100644
--- a/WebCore/html/HTMLFrameSetElement.cpp
+++ b/WebCore/html/HTMLFrameSetElement.cpp
@@ -234,136 +234,4 @@ void HTMLFrameSetElement::setRows(const String &value)
     setAttribute(rowsAttr, value);
 }
 
-EventListener* HTMLFrameSetElement::onblur() const
-{
-    return document()->getWindowAttributeEventListener(eventNames().blurEvent);
-}
-
-void HTMLFrameSetElement::setOnblur(PassRefPtr<EventListener> eventListener)
-{
-    document()->setWindowAttributeEventListener(eventNames().blurEvent, eventListener);
-}
-
-EventListener* HTMLFrameSetElement::onerror() const
-{
-    return document()->getWindowAttributeEventListener(eventNames().errorEvent);
-}
-
-void HTMLFrameSetElement::setOnerror(PassRefPtr<EventListener> eventListener)
-{
-    document()->setWindowAttributeEventListener(eventNames().errorEvent, eventListener);
-}
-
-EventListener* HTMLFrameSetElement::onfocus() const
-{
-    return document()->getWindowAttributeEventListener(eventNames().focusEvent);
-}
-
-void HTMLFrameSetElement::setOnfocus(PassRefPtr<EventListener> eventListener)
-{
-    document()->setWindowAttributeEventListener(eventNames().focusEvent, eventListener);
-}
-
-EventListener* HTMLFrameSetElement::onhashchange() const
-{
-    return document()->getWindowAttributeEventListener(eventNames().hashchangeEvent);
-}
-
-void HTMLFrameSetElement::setOnhashchange(PassRefPtr<EventListener> eventListener)
-{
-    document()->setWindowAttributeEventListener(eventNames().hashchangeEvent, eventListener);
-}   
-
-EventListener* HTMLFrameSetElement::onload() const
-{
-    return document()->getWindowAttributeEventListener(eventNames().loadEvent);
-}
-
-void HTMLFrameSetElement::setOnload(PassRefPtr<EventListener> eventListener)
-{
-    document()->setWindowAttributeEventListener(eventNames().loadEvent, eventListener);
-}
-
-EventListener* HTMLFrameSetElement::onbeforeunload() const
-{
-    return document()->getWindowAttributeEventListener(eventNames().beforeunloadEvent);
-}
-
-void HTMLFrameSetElement::setOnbeforeunload(PassRefPtr<EventListener> eventListener)
-{
-    document()->setWindowAttributeEventListener(eventNames().beforeunloadEvent, eventListener);
-}
-
-EventListener* HTMLFrameSetElement::onmessage() const
-{
-    return document()->getWindowAttributeEventListener(eventNames().messageEvent);
-}
-
-void HTMLFrameSetElement::setOnmessage(PassRefPtr<EventListener> eventListener)
-{
-    document()->setWindowAttributeEventListener(eventNames().messageEvent, eventListener);
-}
-
-EventListener* HTMLFrameSetElement::onoffline() const
-{
-    return document()->getWindowAttributeEventListener(eventNames().offlineEvent);
-}
-
-void HTMLFrameSetElement::setOnoffline(PassRefPtr<EventListener> eventListener)
-{
-    document()->setWindowAttributeEventListener(eventNames().offlineEvent, eventListener);
-}
-
-EventListener* HTMLFrameSetElement::ononline() const
-{
-    return document()->getWindowAttributeEventListener(eventNames().onlineEvent);
-}
-
-void HTMLFrameSetElement::setOnonline(PassRefPtr<EventListener> eventListener)
-{
-    document()->setWindowAttributeEventListener(eventNames().onlineEvent, eventListener);
-}
-
-#if ENABLE(ORIENTATION_EVENTS)
-EventListener* HTMLFrameSetElement::onorientationchange() const
-{
-    return document()->getWindowAttributeEventListener(eventNames().orientationchangeEvent);
-}
-
-void HTMLFrameSetElement::setOnorientationchange(PassRefPtr<EventListener> eventListener)
-{
-    document()->setWindowAttributeEventListener(eventNames().orientationchangeEvent, eventListener);
-}
-#endif
-    
-EventListener* HTMLFrameSetElement::onresize() const
-{
-    return document()->getWindowAttributeEventListener(eventNames().resizeEvent);
-}
-
-void HTMLFrameSetElement::setOnresize(PassRefPtr<EventListener> eventListener)
-{
-    document()->setWindowAttributeEventListener(eventNames().resizeEvent, eventListener);
-}
-
-EventListener* HTMLFrameSetElement::onstorage() const
-{
-    return document()->getWindowAttributeEventListener(eventNames().storageEvent);
-}
-
-void HTMLFrameSetElement::setOnstorage(PassRefPtr<EventListener> eventListener)
-{
-    document()->setWindowAttributeEventListener(eventNames().storageEvent, eventListener);
-}
-
-EventListener* HTMLFrameSetElement::onunload() const
-{
-    return document()->getWindowAttributeEventListener(eventNames().unloadEvent);
-}
-
-void HTMLFrameSetElement::setOnunload(PassRefPtr<EventListener> eventListener)
-{
-    document()->setWindowAttributeEventListener(eventNames().unloadEvent, eventListener);
-}
-
 } // namespace WebCore
diff --git a/WebCore/html/HTMLFrameSetElement.h b/WebCore/html/HTMLFrameSetElement.h
index 0deacf1..2b2d7ea 100644
--- a/WebCore/html/HTMLFrameSetElement.h
+++ b/WebCore/html/HTMLFrameSetElement.h
@@ -24,8 +24,9 @@
 #ifndef HTMLFrameSetElement_h
 #define HTMLFrameSetElement_h
 
-#include "HTMLElement.h"
 #include "Color.h"
+#include "Document.h"
+#include "HTMLElement.h"
 
 namespace WebCore {
 
@@ -67,36 +68,23 @@ public:
     const Length* rowLengths() const { return m_rows; }
     const Length* colLengths() const { return m_cols; }
 
-    // Event handler attributes
-    virtual EventListener* onblur() const;
-    virtual void setOnblur(PassRefPtr<EventListener>);
-    virtual EventListener* onerror() const;
-    virtual void setOnerror(PassRefPtr<EventListener>);
-    virtual EventListener* onfocus() const;
-    virtual void setOnfocus(PassRefPtr<EventListener>);
-    virtual EventListener* onload() const;
-    virtual void setOnload(PassRefPtr<EventListener>);
-
-    EventListener* onbeforeunload() const;
-    void setOnbeforeunload(PassRefPtr<EventListener>);
-    EventListener* onhashchange() const;
-    void setOnhashchange(PassRefPtr<EventListener>);
-    EventListener* onmessage() const;
-    void setOnmessage(PassRefPtr<EventListener>);
-    EventListener* onoffline() const;
-    void setOnoffline(PassRefPtr<EventListener>);
-    EventListener* ononline() const;
-    void setOnonline(PassRefPtr<EventListener>);
+    // Declared virtual in Element
+    DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(blur);
+    DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(error);
+    DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(focus);
+    DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(load);
+
+    DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(beforeunload);
+    DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(hashchange);
+    DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(message);
+    DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(offline);
+    DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(online);
+    DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(resize);
+    DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(storage);
+    DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(unload);
 #if ENABLE(ORIENTATION_EVENTS)
-    EventListener* onorientationchange() const;
-    void setOnorientationchange(PassRefPtr<EventListener>);
+    DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(orientationchange);
 #endif
-    EventListener* onresize() const;
-    void setOnresize(PassRefPtr<EventListener>);
-    EventListener* onstorage() const;
-    void setOnstorage(PassRefPtr<EventListener>);
-    EventListener* onunload() const;
-    void setOnunload(PassRefPtr<EventListener>);
 
 private:
     Length* m_rows;
diff --git a/WebCore/html/HTMLImageLoader.cpp b/WebCore/html/HTMLImageLoader.cpp
index 2b9f09c..c6f49aa 100644
--- a/WebCore/html/HTMLImageLoader.cpp
+++ b/WebCore/html/HTMLImageLoader.cpp
@@ -25,6 +25,7 @@
 #include "CSSHelper.h"
 #include "CachedImage.h"
 #include "Element.h"
+#include "Event.h"
 #include "EventNames.h"
 #include "HTMLNames.h"
 #include "HTMLObjectElement.h"
@@ -45,7 +46,7 @@ void HTMLImageLoader::dispatchLoadEvent()
     bool errorOccurred = image()->errorOccurred();
     if (!errorOccurred && image()->httpStatusCodeErrorOccurred())
         errorOccurred = element()->hasTagName(HTMLNames::objectTag); // An <object> considers a 404 to be an error and should fire onerror.
-    element()->dispatchEvent(errorOccurred ? eventNames().errorEvent : eventNames().loadEvent, false, false);
+    element()->dispatchEvent(Event::create(errorOccurred ? eventNames().errorEvent : eventNames().loadEvent, false, false));
 }
 
 String HTMLImageLoader::sourceURI(const AtomicString& attr) const
diff --git a/WebCore/html/HTMLInputElement.cpp b/WebCore/html/HTMLInputElement.cpp
index 8b884cf..5ba780a 100644
--- a/WebCore/html/HTMLInputElement.cpp
+++ b/WebCore/html/HTMLInputElement.cpp
@@ -1742,7 +1742,7 @@ void HTMLInputElement::onSearch()
     ASSERT(isSearchField());
     if (renderer())
         toRenderTextControlSingleLine(renderer())->stopSearchEventTimer();
-    dispatchEvent(eventNames().searchEvent, true, false);
+    dispatchEvent(Event::create(eventNames().searchEvent, true, false));
 }
 
 VisibleSelection HTMLInputElement::selection() const
diff --git a/WebCore/html/HTMLMediaElement.cpp b/WebCore/html/HTMLMediaElement.cpp
index 3b1a025..2409d37 100644
--- a/WebCore/html/HTMLMediaElement.cpp
+++ b/WebCore/html/HTMLMediaElement.cpp
@@ -463,8 +463,8 @@ void HTMLMediaElement::loadInternal()
         bool totalKnown = m_player && m_player->totalBytesKnown();
         unsigned loaded = m_player ? m_player->bytesLoaded() : 0;
         unsigned total = m_player ? m_player->totalBytes() : 0;
-        dispatchProgressEvent(eventNames().abortEvent, totalKnown, loaded, total);
-        dispatchProgressEvent(eventNames().loadendEvent, totalKnown, loaded, total);
+        dispatchEvent(ProgressEvent::create(eventNames().abortEvent, totalKnown, loaded, total));
+        dispatchEvent(ProgressEvent::create(eventNames().loadendEvent, totalKnown, loaded, total));
     }
 
     // 5
@@ -487,7 +487,7 @@ void HTMLMediaElement::loadInternal()
             m_playing = false;
             m_player->seek(0);
         }
-        dispatchEvent(eventNames().emptiedEvent, false, true);
+        dispatchEvent(Event::create(eventNames().emptiedEvent, false, true));
     }
 
     selectMediaResource();
diff --git a/WebCore/html/HTMLScriptElement.cpp b/WebCore/html/HTMLScriptElement.cpp
index 86cc3a2..ce7fee6 100644
--- a/WebCore/html/HTMLScriptElement.cpp
+++ b/WebCore/html/HTMLScriptElement.cpp
@@ -24,6 +24,7 @@
 #include "HTMLScriptElement.h"
 
 #include "Document.h"
+#include "Event.h"
 #include "EventNames.h"
 #include "HTMLNames.h"
 #include "MappedAttribute.h"
@@ -222,12 +223,12 @@ void HTMLScriptElement::dispatchLoadEvent()
     ASSERT(!m_data.haveFiredLoadEvent());
     m_data.setHaveFiredLoadEvent(true);
 
-    dispatchEvent(eventNames().loadEvent, false, false);
+    dispatchEvent(Event::create(eventNames().loadEvent, false, false));
 }
 
 void HTMLScriptElement::dispatchErrorEvent()
 {
-    dispatchEvent(eventNames().errorEvent, true, false);
+    dispatchEvent(Event::create(eventNames().errorEvent, true, false));
 }
 
 }
diff --git a/WebCore/html/HTMLSourceElement.cpp b/WebCore/html/HTMLSourceElement.cpp
index 2f09997..4b9401d 100644
--- a/WebCore/html/HTMLSourceElement.cpp
+++ b/WebCore/html/HTMLSourceElement.cpp
@@ -28,6 +28,7 @@
 #if ENABLE(VIDEO)
 #include "HTMLSourceElement.h"
 
+#include "Event.h"
 #include "EventNames.h"
 #include "HTMLDocument.h"
 #include "HTMLMediaElement.h"
@@ -105,7 +106,7 @@ void HTMLSourceElement::cancelPendingErrorEvent()
 
 void HTMLSourceElement::errorEventTimerFired(Timer<HTMLSourceElement>*)
 {
-    dispatchEvent(eventNames().errorEvent, false, true);
+    dispatchEvent(Event::create(eventNames().errorEvent, false, true));
 }
 
 }
diff --git a/WebCore/html/HTMLTokenizer.cpp b/WebCore/html/HTMLTokenizer.cpp
index 71faac0..fa68151 100644
--- a/WebCore/html/HTMLTokenizer.cpp
+++ b/WebCore/html/HTMLTokenizer.cpp
@@ -33,6 +33,7 @@
 #include "CachedScript.h"
 #include "DocLoader.h"
 #include "DocumentFragment.h"
+#include "Event.h"
 #include "EventNames.h"
 #include "Frame.h"
 #include "FrameLoader.h"
@@ -2029,7 +2030,7 @@ void HTMLTokenizer::notifyFinished(CachedResource*)
 #endif
 
         if (errorOccurred)
-            n->dispatchEvent(eventNames().errorEvent, true, false);
+            n->dispatchEvent(Event::create(eventNames().errorEvent, true, false));
         else {
             if (static_cast<HTMLScriptElement*>(n.get())->shouldExecuteAsJavaScript())
                 m_state = scriptExecution(sourceCode, m_state);
@@ -2037,7 +2038,7 @@ void HTMLTokenizer::notifyFinished(CachedResource*)
             else
                 m_doc->setShouldProcessNoscriptElement(true);
 #endif
-            n->dispatchEvent(eventNames().loadEvent, false, false);
+            n->dispatchEvent(Event::create(eventNames().loadEvent, false, false));
         }
 
         // The state of m_pendingScripts.isEmpty() can change inside the scriptExecution()
diff --git a/WebCore/inspector/InspectorDOMAgent.cpp b/WebCore/inspector/InspectorDOMAgent.cpp
index c7299d6..4a4902d 100644
--- a/WebCore/inspector/InspectorDOMAgent.cpp
+++ b/WebCore/inspector/InspectorDOMAgent.cpp
@@ -123,7 +123,7 @@ void InspectorDOMAgent::stopListening(Document* doc)
     m_documents.remove(doc);
 }
 
-void InspectorDOMAgent::handleEvent(Event* event, bool)
+void InspectorDOMAgent::handleEvent(Event* event)
 {
     AtomicString type = event->type();
     Node* node = event->target()->toNode();
diff --git a/WebCore/inspector/InspectorDOMAgent.h b/WebCore/inspector/InspectorDOMAgent.h
index 3f4eaf5..bd539a5 100644
--- a/WebCore/inspector/InspectorDOMAgent.h
+++ b/WebCore/inspector/InspectorDOMAgent.h
@@ -85,7 +85,7 @@ namespace WebCore {
         void startListening(Document* document);
         void stopListening(Document* document);
 
-        virtual void handleEvent(Event* event, bool isWindowEvent);
+        virtual void handleEvent(Event* event);
 
         typedef HashMap<RefPtr<Node>, long> NodeToIdMap;
         long bind(Node* node, NodeToIdMap* nodesMap);
diff --git a/WebCore/inspector/InspectorDOMStorageResource.cpp b/WebCore/inspector/InspectorDOMStorageResource.cpp
index 5b3a7d1..99a2dba 100644
--- a/WebCore/inspector/InspectorDOMStorageResource.cpp
+++ b/WebCore/inspector/InspectorDOMStorageResource.cpp
@@ -96,7 +96,7 @@ void InspectorDOMStorageResource::startReportingChangesToFrontend()
     }
 }
 
-void InspectorDOMStorageResource::handleEvent(Event* event, bool)
+void InspectorDOMStorageResource::handleEvent(Event* event)
 {
     ASSERT(m_frontend);
     ASSERT(eventNames().storageEvent == event->type());
diff --git a/WebCore/inspector/InspectorDOMStorageResource.h b/WebCore/inspector/InspectorDOMStorageResource.h
index 483c98e..6f29d9d 100644
--- a/WebCore/inspector/InspectorDOMStorageResource.h
+++ b/WebCore/inspector/InspectorDOMStorageResource.h
@@ -62,7 +62,7 @@ namespace WebCore {
         void unbind();
         void startReportingChangesToFrontend();
 
-        virtual void handleEvent(Event*, bool isWindowEvent);
+        virtual void handleEvent(Event*);
         virtual bool operator==(const EventListener& listener);
 
         bool isSameHostAndType(Frame*, bool isLocalStorage) const;
diff --git a/WebCore/loader/FrameLoader.cpp b/WebCore/loader/FrameLoader.cpp
index f5ff025..807edef 100644
--- a/WebCore/loader/FrameLoader.cpp
+++ b/WebCore/loader/FrameLoader.cpp
@@ -71,6 +71,7 @@
 #include "Page.h"
 #include "PageCache.h"
 #include "PageGroup.h"
+#include "PageTransitionEvent.h"
 #include "PlaceholderDocument.h"
 #include "PluginData.h"
 #include "PluginDocument.h"
@@ -592,9 +593,9 @@ void FrameLoader::stopLoading(UnloadEventPolicy unloadEventPolicy, DatabasePolic
                 m_unloadEventBeingDispatched = true;
                 if (m_frame->domWindow()) {
                     if (unloadEventPolicy == UnloadEventPolicyUnloadAndPageHide)
-                        m_frame->domWindow()->dispatchPageTransitionEvent(EventNames().pagehideEvent, m_frame->document()->inPageCache());
+                        m_frame->domWindow()->dispatchEvent(PageTransitionEvent::create(EventNames().pagehideEvent, m_frame->document()->inPageCache()), m_frame->document());
                     if (!m_frame->document()->inPageCache())
-                        m_frame->domWindow()->dispatchUnloadEvent();
+                        m_frame->domWindow()->dispatchEvent(Event::create(eventNames().unloadEvent, false, false), m_frame->domWindow()->document());
                 }
                 m_unloadEventBeingDispatched = false;
                 if (m_frame->document())
@@ -1882,7 +1883,7 @@ bool FrameLoader::canCachePageContainingThisFrame()
         && !m_containsPlugIns
         && !m_URL.protocolIs("https")
 #ifndef PAGE_CACHE_ACCEPTS_UNLOAD_HANDLERS
-        && (!m_frame->domWindow() || !m_frame->domWindow()->hasEventListener(eventNames().unloadEvent))
+        && (!m_frame->domWindow() || !m_frame->domWindow()->hasEventListeners(eventNames().unloadEvent))
 #endif
 #if ENABLE(DATABASE)
         && !m_frame->document()->hasOpenDatabases()
@@ -2029,7 +2030,7 @@ bool FrameLoader::logCanCacheFrameDecision(int indentLevel)
         if (m_URL.protocolIs("https"))
             { PCLOG("   -Frame is HTTPS"); cannotCache = true; }
 #ifndef PAGE_CACHE_ACCEPTS_UNLOAD_HANDLERS
-        if (m_frame->domWindow() && m_frame->domWindow()->hasEventListener(eventNames().unloadEvent))
+        if (m_frame->domWindow() && m_frame->domWindow()->hasEventListeners(eventNames().unloadEvent))
             { PCLOG("   -Frame has an unload event listener"); cannotCache = true; }
 #endif
 #if ENABLE(DATABASE)
@@ -2096,7 +2097,7 @@ public:
     virtual void performTask(ScriptExecutionContext* context)
     {
         ASSERT_UNUSED(context, context->isDocument());
-        m_document->dispatchWindowEvent(eventNames().hashchangeEvent, false, false);
+        m_document->dispatchWindowEvent(Event::create(eventNames().hashchangeEvent, false, false));
     }
     
 private:
@@ -4322,7 +4323,7 @@ void FrameLoader::pageHidden()
 {
     m_unloadEventBeingDispatched = true;
     if (m_frame->domWindow())
-        m_frame->domWindow()->dispatchPageTransitionEvent(EventNames().pagehideEvent, true);
+        m_frame->domWindow()->dispatchEvent(PageTransitionEvent::create(EventNames().pagehideEvent, true), m_frame->document());
     m_unloadEventBeingDispatched = false;
 
     // Send pagehide event for subframes as well
diff --git a/WebCore/loader/ImageDocument.cpp b/WebCore/loader/ImageDocument.cpp
index d2b1dd6..8078ccd 100644
--- a/WebCore/loader/ImageDocument.cpp
+++ b/WebCore/loader/ImageDocument.cpp
@@ -70,7 +70,7 @@ private:
     {
     }
 
-    virtual void handleEvent(Event*, bool isWindowEvent);
+    virtual void handleEvent(Event*);
 
     ImageDocument* m_doc;
 };
@@ -358,7 +358,7 @@ bool ImageDocument::shouldShrinkToFit() const
 
 // --------
 
-void ImageEventListener::handleEvent(Event* event, bool)
+void ImageEventListener::handleEvent(Event* event)
 {
     if (event->type() == eventNames().resizeEvent)
         m_doc->windowSizeChanged();
diff --git a/WebCore/loader/appcache/ApplicationCacheGroup.cpp b/WebCore/loader/appcache/ApplicationCacheGroup.cpp
index d18dcf2..327596e 100644
--- a/WebCore/loader/appcache/ApplicationCacheGroup.cpp
+++ b/WebCore/loader/appcache/ApplicationCacheGroup.cpp
@@ -962,7 +962,7 @@ public:
     
         ASSERT(frame->loader()->documentLoader() == m_documentLoader.get());
 
-        m_documentLoader->applicationCacheHost()->notifyEventListener(m_eventID);
+        m_documentLoader->applicationCacheHost()->notifyDOMApplicationCache(m_eventID);
     }
 
 private:
diff --git a/WebCore/loader/appcache/ApplicationCacheHost.cpp b/WebCore/loader/appcache/ApplicationCacheHost.cpp
index 992f9e9..751efc1 100644
--- a/WebCore/loader/appcache/ApplicationCacheHost.cpp
+++ b/WebCore/loader/appcache/ApplicationCacheHost.cpp
@@ -227,10 +227,13 @@ void ApplicationCacheHost::setDOMApplicationCache(DOMApplicationCache* domApplic
     m_domApplicationCache = domApplicationCache;
 }
 
-void ApplicationCacheHost::notifyEventListener(EventID id)
+void ApplicationCacheHost::notifyDOMApplicationCache(EventID id)
 {
-    if (m_domApplicationCache)
-        m_domApplicationCache->callEventListener(id);
+    if (m_domApplicationCache) {
+        ExceptionCode ec = 0;
+        m_domApplicationCache->dispatchEvent(Event::create(DOMApplicationCache::toEventType(id), false, false), ec);
+        ASSERT(!ec);    
+    }
 }
 
 void ApplicationCacheHost::setCandidateApplicationCacheGroup(ApplicationCacheGroup* group)
diff --git a/WebCore/loader/appcache/ApplicationCacheHost.h b/WebCore/loader/appcache/ApplicationCacheHost.h
index cb68862..236013d 100644
--- a/WebCore/loader/appcache/ApplicationCacheHost.h
+++ b/WebCore/loader/appcache/ApplicationCacheHost.h
@@ -108,7 +108,7 @@ namespace WebCore {
         bool swapCache();
 
         void setDOMApplicationCache(DOMApplicationCache* domApplicationCache);
-        void notifyEventListener(EventID id);
+        void notifyDOMApplicationCache(EventID id);
 
     private:
         bool isApplicationCacheEnabled();
diff --git a/WebCore/loader/appcache/DOMApplicationCache.cpp b/WebCore/loader/appcache/DOMApplicationCache.cpp
index dd0aed9..29c1bd5 100644
--- a/WebCore/loader/appcache/DOMApplicationCache.cpp
+++ b/WebCore/loader/appcache/DOMApplicationCache.cpp
@@ -91,73 +91,6 @@ ScriptExecutionContext* DOMApplicationCache::scriptExecutionContext() const
     return m_frame->document();
 }
 
-void DOMApplicationCache::addEventListener(const AtomicString& eventType, PassRefPtr<EventListener> eventListener, bool)
-{
-    EventListenersMap::iterator iter = m_eventListeners.find(eventType);
-    if (iter == m_eventListeners.end()) {
-        ListenerVector listeners;
-        listeners.append(eventListener);
-        m_eventListeners.add(eventType, listeners);
-    } else {
-        ListenerVector& listeners = iter->second;
-        for (ListenerVector::iterator listenerIter = listeners.begin(); listenerIter != listeners.end(); ++listenerIter) {
-            if (**listenerIter == *eventListener)
-                return;
-        }
-        
-        listeners.append(eventListener);
-        m_eventListeners.add(eventType, listeners);
-    }    
-}
-
-void DOMApplicationCache::removeEventListener(const AtomicString& eventType, EventListener* eventListener, bool)
-{
-    EventListenersMap::iterator iter = m_eventListeners.find(eventType);
-    if (iter == m_eventListeners.end())
-        return;
-    
-    ListenerVector& listeners = iter->second;
-    for (ListenerVector::const_iterator listenerIter = listeners.begin(); listenerIter != listeners.end(); ++listenerIter) {
-        if (**listenerIter == *eventListener) {
-            listeners.remove(listenerIter - listeners.begin());
-            return;
-        }
-    }
-}
-
-bool DOMApplicationCache::dispatchEvent(PassRefPtr<Event> event, ExceptionCode& ec)
-{
-    if (!event || event->type().isEmpty()) {
-        ec = EventException::UNSPECIFIED_EVENT_TYPE_ERR;
-        return true;
-    }
-
-    ListenerVector listenersCopy = m_eventListeners.get(event->type());
-    for (ListenerVector::const_iterator listenerIter = listenersCopy.begin(); listenerIter != listenersCopy.end(); ++listenerIter) {
-        event->setTarget(this);
-        event->setCurrentTarget(this);
-        listenerIter->get()->handleEvent(event.get(), false);
-    }
-    
-    return !event->defaultPrevented();
-}
-
-void DOMApplicationCache::callListener(const AtomicString& eventType, EventListener* listener)
-{
-    ASSERT(m_frame);
-    
-    RefPtr<Event> event = Event::create(eventType, false, false);
-    if (listener) {
-        event->setTarget(this);
-        event->setCurrentTarget(this);
-        listener->handleEvent(event.get(), false);
-    }
-    
-    ExceptionCode ec = 0;
-    dispatchEvent(event.release(), ec);
-    ASSERT(!ec);    
-}
-
 const AtomicString& DOMApplicationCache::toEventType(ApplicationCacheHost::EventID id)
 {
     switch (id) {
@@ -182,27 +115,14 @@ const AtomicString& DOMApplicationCache::toEventType(ApplicationCacheHost::Event
     return eventNames().errorEvent;
 }
 
-ApplicationCacheHost::EventID DOMApplicationCache::toEventID(const AtomicString& eventType)
+EventTargetData* DOMApplicationCache::eventTargetData()
 {
-    if (eventType == eventNames().checkingEvent)
-        return ApplicationCacheHost::CHECKING_EVENT;
-    if (eventType == eventNames().errorEvent)
-        return ApplicationCacheHost::ERROR_EVENT;
-    if (eventType == eventNames().noupdateEvent)
-        return ApplicationCacheHost::NOUPDATE_EVENT;
-    if (eventType == eventNames().downloadingEvent)
-        return ApplicationCacheHost::DOWNLOADING_EVENT;
-    if (eventType == eventNames().progressEvent)
-        return ApplicationCacheHost::PROGRESS_EVENT;
-    if (eventType == eventNames().updatereadyEvent)
-        return ApplicationCacheHost::UPDATEREADY_EVENT;
-    if (eventType == eventNames().cachedEvent)
-        return ApplicationCacheHost::CACHED_EVENT;
-    if (eventType == eventNames().obsoleteEvent)
-        return ApplicationCacheHost::OBSOLETE_EVENT;
-  
-    ASSERT_NOT_REACHED();
-    return ApplicationCacheHost::ERROR_EVENT;
+    return &m_eventTargetData;
+}
+
+EventTargetData* DOMApplicationCache::ensureEventTargetData()
+{
+    return &m_eventTargetData;
 }
 
 } // namespace WebCore
diff --git a/WebCore/loader/appcache/DOMApplicationCache.h b/WebCore/loader/appcache/DOMApplicationCache.h
index 09e9a03..077cae0 100644
--- a/WebCore/loader/appcache/DOMApplicationCache.h
+++ b/WebCore/loader/appcache/DOMApplicationCache.h
@@ -30,8 +30,9 @@
 
 #include "ApplicationCacheHost.h"
 #include "AtomicStringHash.h"
-#include "EventTarget.h"
 #include "EventListener.h"
+#include "EventNames.h"
+#include "EventTarget.h"
 #include <wtf/HashMap.h>
 #include <wtf/PassRefPtr.h>
 #include <wtf/RefCounted.h>
@@ -55,72 +56,39 @@ public:
     void update(ExceptionCode&);
     void swapCache(ExceptionCode&);
 
-    // Event listener attributes by EventID
-
-    void setAttributeEventListener(ApplicationCacheHost::EventID id, PassRefPtr<EventListener> eventListener) { m_attributeEventListeners[id] = eventListener; }
-    EventListener* getAttributeEventListener(ApplicationCacheHost::EventID id) const { return m_attributeEventListeners[id].get(); }
-    void clearAttributeEventListener(ApplicationCacheHost::EventID id) { m_attributeEventListeners[id] = 0; }
-    void callEventListener(ApplicationCacheHost::EventID id) { callListener(toEventType(id), getAttributeEventListener(id)); }
-
     // EventTarget impl
 
-    virtual void addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture);
-    virtual void removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture);
-    virtual bool dispatchEvent(PassRefPtr<Event>, ExceptionCode&);
-    typedef Vector<RefPtr<EventListener> > ListenerVector;
-    typedef HashMap<AtomicString, ListenerVector> EventListenersMap;
-    EventListenersMap& eventListeners() { return m_eventListeners; }
-
     using RefCounted<DOMApplicationCache>::ref;
     using RefCounted<DOMApplicationCache>::deref;
 
     // Explicitly named attribute event listener helpers
 
-    void setOnchecking(PassRefPtr<EventListener> listener) { setAttributeEventListener(ApplicationCacheHost::CHECKING_EVENT, listener); }
-    EventListener* onchecking() const { return getAttributeEventListener(ApplicationCacheHost::CHECKING_EVENT); }
-
-    void setOnerror(PassRefPtr<EventListener> listener) { setAttributeEventListener(ApplicationCacheHost::ERROR_EVENT, listener);}
-    EventListener* onerror() const { return getAttributeEventListener(ApplicationCacheHost::ERROR_EVENT); }
-
-    void setOnnoupdate(PassRefPtr<EventListener> listener) { setAttributeEventListener(ApplicationCacheHost::NOUPDATE_EVENT, listener); }
-    EventListener* onnoupdate() const { return getAttributeEventListener(ApplicationCacheHost::NOUPDATE_EVENT); }
-
-    void setOndownloading(PassRefPtr<EventListener> listener) { setAttributeEventListener(ApplicationCacheHost::DOWNLOADING_EVENT, listener); }
-    EventListener* ondownloading() const { return getAttributeEventListener(ApplicationCacheHost::DOWNLOADING_EVENT); }
-
-    void setOnprogress(PassRefPtr<EventListener> listener) { setAttributeEventListener(ApplicationCacheHost::PROGRESS_EVENT, listener); }
-    EventListener* onprogress() const { return getAttributeEventListener(ApplicationCacheHost::PROGRESS_EVENT); }
-
-    void setOnupdateready(PassRefPtr<EventListener> listener) { setAttributeEventListener(ApplicationCacheHost::UPDATEREADY_EVENT, listener); }
-    EventListener* onupdateready() const { return getAttributeEventListener(ApplicationCacheHost::UPDATEREADY_EVENT); }
-
-    void setOncached(PassRefPtr<EventListener> listener) { setAttributeEventListener(ApplicationCacheHost::CACHED_EVENT, listener); }
-    EventListener* oncached() const { return getAttributeEventListener(ApplicationCacheHost::CACHED_EVENT); }
-
-    void setOnobsolete(PassRefPtr<EventListener> listener) { setAttributeEventListener(ApplicationCacheHost::OBSOLETE_EVENT, listener); }
-    EventListener* onobsolete() const { return getAttributeEventListener(ApplicationCacheHost::OBSOLETE_EVENT); }
+    DEFINE_ATTRIBUTE_EVENT_LISTENER(checking);
+    DEFINE_ATTRIBUTE_EVENT_LISTENER(error);
+    DEFINE_ATTRIBUTE_EVENT_LISTENER(noupdate);
+    DEFINE_ATTRIBUTE_EVENT_LISTENER(downloading);
+    DEFINE_ATTRIBUTE_EVENT_LISTENER(progress);
+    DEFINE_ATTRIBUTE_EVENT_LISTENER(updateready);
+    DEFINE_ATTRIBUTE_EVENT_LISTENER(cached);
+    DEFINE_ATTRIBUTE_EVENT_LISTENER(obsolete);
 
     virtual ScriptExecutionContext* scriptExecutionContext() const;
     DOMApplicationCache* toDOMApplicationCache() { return this; }
 
     static const AtomicString& toEventType(ApplicationCacheHost::EventID id);
-    static ApplicationCacheHost::EventID toEventID(const AtomicString& eventType);
 
 private:
     DOMApplicationCache(Frame*);
 
-    void callListener(const AtomicString& eventType, EventListener*);
-    
     virtual void refEventTarget() { ref(); }
     virtual void derefEventTarget() { deref(); }
+    virtual EventTargetData* eventTargetData();
+    virtual EventTargetData* ensureEventTargetData();
 
     ApplicationCacheHost* applicationCacheHost() const;
-    
-    RefPtr<EventListener> m_attributeEventListeners[ApplicationCacheHost::OBSOLETE_EVENT + 1];
-
-    EventListenersMap m_eventListeners;
 
     Frame* m_frame;
+    EventTargetData m_eventTargetData;
 };
 
 } // namespace WebCore
diff --git a/WebCore/loader/appcache/DOMApplicationCache.idl b/WebCore/loader/appcache/DOMApplicationCache.idl
index ebc1d19..dd5468a 100644
--- a/WebCore/loader/appcache/DOMApplicationCache.idl
+++ b/WebCore/loader/appcache/DOMApplicationCache.idl
@@ -27,7 +27,7 @@ module offline {
  
     interface [
         Conditional=OFFLINE_WEB_APPLICATIONS,
-        CustomMarkFunction
+        EventTarget
     ] DOMApplicationCache {
         // update status
         const unsigned short UNCACHED = 0;
diff --git a/WebCore/notifications/Notification.cpp b/WebCore/notifications/Notification.cpp
index 61ad1f3..8dd168f 100644
--- a/WebCore/notifications/Notification.cpp
+++ b/WebCore/notifications/Notification.cpp
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2009 Google Inc. All rights reserved.
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
@@ -96,137 +97,14 @@ void Notification::cancel()
         m_presenter->cancel(this);
 }
 
-EventListener* Notification::ondisplay() const
+EventTargetData* Notification::eventTargetData()
 {
-    return getAttributeEventListener("display");
+    return &m_eventTargetData;
 }
 
-void Notification::setOndisplay(PassRefPtr<EventListener> eventListener)
+EventTargetData* Notification::ensureEventTargetData()
 {
-    setAttributeEventListener("display", eventListener);
-}
-
-EventListener* Notification::onerror() const
-{
-    return getAttributeEventListener(eventNames().errorEvent);
-}
-
-void Notification::setOnerror(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().errorEvent, eventListener);
-}
-
-EventListener* Notification::onclose() const
-{
-    return getAttributeEventListener(eventNames().closeEvent);
-}
-
-void Notification::setOnclose(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().closeEvent, eventListener);
-}
-
-EventListener* Notification::getAttributeEventListener(const AtomicString& eventType) const
-{
-    const RegisteredEventListenerVector& listeners = m_eventListeners;
-    size_t size = listeners.size();
-    for (size_t i = 0; i < size; ++i) {
-        const RegisteredEventListener& r = *listeners[i];
-        if (r.eventType() == eventType && r.listener()->isAttribute())
-            return r.listener();
-    }
-    return 0;
-}
-
-void Notification::setAttributeEventListener(const AtomicString& eventType, PassRefPtr<EventListener> listener)
-{
-    clearAttributeEventListener(eventType);
-    if (listener)
-        addEventListener(eventType, listener, false);
-}
-
-void Notification::clearAttributeEventListener(const AtomicString& eventType)
-{
-    RegisteredEventListenerVector* listeners = &m_eventListeners;
-    size_t size = listeners->size();
-    for (size_t i = 0; i < size; ++i) {
-        RegisteredEventListener& r = *listeners->at(i);
-        if (r.eventType() != eventType || !r.listener()->isAttribute())
-            continue;
-
-        r.setRemoved(true);
-        listeners->remove(i);
-        return;
-    }
-}
-
-void Notification::dispatchDisplayEvent() 
-{   
-    RefPtr<Event> event = Event::create("display", false, true);
-    ExceptionCode ec = 0;
-    dispatchEvent(event.release(), ec);
-    ASSERT(!ec);
-}
-
-void Notification::dispatchErrorEvent()
-{  
-    RefPtr<Event> event = Event::create(eventNames().errorEvent, false, true);
-    ExceptionCode ec = 0;
-    dispatchEvent(event.release(), ec);
-    ASSERT(!ec);
-}
-
-void Notification::dispatchCloseEvent() 
-{   
-    RefPtr<Event> event = Event::create(eventNames().closeEvent, false, true);
-    ExceptionCode ec = 0;
-    dispatchEvent(event.release(), ec);
-    ASSERT(!ec);
-}
-
-void Notification::addEventListener(const AtomicString& eventType, PassRefPtr<EventListener> listener, bool useCapture)
-{
-    RefPtr<RegisteredEventListener> registeredListener = RegisteredEventListener::create(eventType, listener, useCapture);
-    m_eventListeners.append(registeredListener);
-}
-
-void Notification::removeEventListener(const AtomicString& eventType, EventListener* listener, bool useCapture)
-{
-    size_t size = m_eventListeners.size();
-    for (size_t i = 0; i < size; ++i) {
-        RegisteredEventListener& r = *m_eventListeners[i];
-        if (r.eventType() == eventType && r.useCapture() == useCapture && *r.listener() == *listener) {
-            r.setRemoved(true);
-            m_eventListeners.remove(i);
-            return; 
-        }
-    }
-}
-
-void Notification::handleEvent(PassRefPtr<Event> event, bool useCapture)
-{
-    RegisteredEventListenerVector listenersCopy = m_eventListeners;
-    size_t size = listenersCopy.size();
-    for (size_t i = 0; i < size; ++i) {
-        RegisteredEventListener& r = *listenersCopy[i];
-        if (r.eventType() == event->type() && r.useCapture() == useCapture && !r.removed())
-            r.listener()->handleEvent(event.get());
-    }
-}
-
-bool Notification::dispatchEvent(PassRefPtr<Event> inEvent, ExceptionCode&)
-{
-    RefPtr<Event> event(inEvent);
-
-    event->setEventPhase(Event::AT_TARGET);
-    event->setCurrentTarget(this);
-
-    handleEvent(event.get(), true);
-    if (!event->propagationStopped()) {
-        handleEvent(event.get(), false);
-    }
-
-    return !event->defaultPrevented();
+    return &m_eventTargetData;
 }
 
 } // namespace WebCore
diff --git a/WebCore/notifications/Notification.h b/WebCore/notifications/Notification.h
index baae4ee..6545579 100644
--- a/WebCore/notifications/Notification.h
+++ b/WebCore/notifications/Notification.h
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2009 Google Inc. All rights reserved.
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
@@ -35,6 +36,7 @@
 #include "AtomicStringHash.h"
 #include "Event.h"
 #include "EventListener.h"
+#include "EventNames.h"
 #include "EventTarget.h"
 #include "ExceptionCode.h"
 #include "KURL.h"
@@ -65,33 +67,17 @@ namespace WebCore {
         KURL url() { return m_notificationURL; }
         NotificationContents& contents() { return m_contents; }
 
-        EventListener* ondisplay() const;
-        void setOndisplay(PassRefPtr<EventListener> eventListener);
-        EventListener* onerror() const;
-        void setOnerror(PassRefPtr<EventListener> eventListener);
-        EventListener* onclose() const;
-        void setOnclose(PassRefPtr<EventListener> eventListener);
+        DEFINE_ATTRIBUTE_EVENT_LISTENER(display);
+        DEFINE_ATTRIBUTE_EVENT_LISTENER(error);
+        DEFINE_ATTRIBUTE_EVENT_LISTENER(close);
     
         using RefCounted<Notification>::ref;
         using RefCounted<Notification>::deref;
     
-        // Dispatching of events on the notification.  The presenter should call these when events occur.
-        void dispatchDisplayEvent();
-        void dispatchErrorEvent();
-        void dispatchCloseEvent();
-
         // EventTarget interface
         virtual ScriptExecutionContext* scriptExecutionContext() const { return ActiveDOMObject::scriptExecutionContext(); }
-        virtual void addEventListener(const AtomicString&, PassRefPtr<EventListener>, bool);
-        virtual void removeEventListener(const AtomicString&, EventListener*, bool);
-        virtual bool dispatchEvent(PassRefPtr<Event>, ExceptionCode&);
         virtual Notification* toNotification() { return this; }
 
-        // These methods are for onEvent style listeners.
-        EventListener* getAttributeEventListener(const AtomicString&) const;
-        void setAttributeEventListener(const AtomicString&, PassRefPtr<EventListener>);
-        void clearAttributeEventListener(const AtomicString&);
-
     private:
         Notification(const String& url, ScriptExecutionContext* context, ExceptionCode& ec, NotificationPresenter* provider);
         Notification(const NotificationContents& fields, ScriptExecutionContext* context, ExceptionCode& ec, NotificationPresenter* provider);
@@ -99,8 +85,8 @@ namespace WebCore {
         // EventTarget interface
         virtual void refEventTarget() { ref(); }
         virtual void derefEventTarget() { deref(); }
-  
-        void handleEvent(PassRefPtr<Event> event, bool useCapture);
+        virtual EventTargetData* eventTargetData();
+        virtual EventTargetData* ensureEventTargetData();
 
         bool m_isHTML;
         KURL m_notificationURL;
@@ -108,9 +94,9 @@ namespace WebCore {
 
         bool m_isShowing;
 
-        RegisteredEventListenerVector m_eventListeners;
-
         NotificationPresenter* m_presenter;
+        
+        EventTargetData m_eventTargetData;
     };
 
 } // namespace WebCore
diff --git a/WebCore/notifications/Notification.idl b/WebCore/notifications/Notification.idl
index eca2eb4..ec6a9c8 100644
--- a/WebCore/notifications/Notification.idl
+++ b/WebCore/notifications/Notification.idl
@@ -31,7 +31,8 @@
 module threads {
 
     interface [
-        Conditional=NOTIFICATIONS
+        Conditional=NOTIFICATIONS,
+        EventTarget
     ] Notification {
         void show();
         void cancel();
diff --git a/WebCore/page/DOMWindow.cpp b/WebCore/page/DOMWindow.cpp
index 943f119..809d541 100644
--- a/WebCore/page/DOMWindow.cpp
+++ b/WebCore/page/DOMWindow.cpp
@@ -105,7 +105,7 @@ public:
     PassRefPtr<MessageEvent> event(ScriptExecutionContext* context)
     {
         OwnPtr<MessagePortArray> messagePorts = MessagePort::entanglePorts(*context, m_channels.release());
-        return MessageEvent::create(m_message, m_origin, "", m_source, messagePorts.release());
+        return MessageEvent::create(messagePorts.release(), m_message, m_origin, "", m_source);
     }
     SecurityOrigin* targetOrigin() const { return m_targetOrigin.get(); }
 
@@ -123,83 +123,36 @@ private:
     RefPtr<SecurityOrigin> m_targetOrigin;
 };
 
-typedef HashMap<DOMWindow*, RegisteredEventListenerVector*> DOMWindowRegisteredEventListenerMap;
+typedef HashCountedSet<DOMWindow*> DOMWindowSet;
 
-static DOMWindowRegisteredEventListenerMap& pendingUnloadEventListenerMap()
+static DOMWindowSet& windowsWithUnloadEventListeners()
 {
-    DEFINE_STATIC_LOCAL(DOMWindowRegisteredEventListenerMap, eventListenerMap, ());
-    return eventListenerMap;
+    DEFINE_STATIC_LOCAL(DOMWindowSet, windowsWithUnloadEventListeners, ());
+    return windowsWithUnloadEventListeners;
 }
 
-static DOMWindowRegisteredEventListenerMap& pendingBeforeUnloadEventListenerMap()
+static DOMWindowSet& windowsWithBeforeUnloadEventListeners()
 {
-    DEFINE_STATIC_LOCAL(DOMWindowRegisteredEventListenerMap, eventListenerMap, ());
-    return eventListenerMap;
+    DEFINE_STATIC_LOCAL(DOMWindowSet, windowsWithBeforeUnloadEventListeners, ());
+    return windowsWithBeforeUnloadEventListeners;
 }
 
-static bool allowsPendingBeforeUnloadListeners(DOMWindow* window)
+static bool allowsBeforeUnloadListeners(DOMWindow* window)
 {
     ASSERT_ARG(window, window);
     Frame* frame = window->frame();
+    if (!frame)
+        return false;
     Page* page = frame->page();
-    return page && frame == page->mainFrame();
-}
-
-static void addPendingEventListener(DOMWindowRegisteredEventListenerMap& map, DOMWindow* window, RegisteredEventListener* listener)
-{
-    ASSERT_ARG(window, window);
-    ASSERT_ARG(listener, listener);
-
-    if (map.isEmpty())
-        disableSuddenTermination();
-
-    pair<DOMWindowRegisteredEventListenerMap::iterator, bool> result = map.add(window, 0);
-    if (result.second)
-        result.first->second = new RegisteredEventListenerVector;
-    result.first->second->append(listener);
-}
-
-static void removePendingEventListener(DOMWindowRegisteredEventListenerMap& map, DOMWindow* window, RegisteredEventListener* listener)
-{
-    ASSERT_ARG(window, window);
-    ASSERT_ARG(listener, listener);
-
-    DOMWindowRegisteredEventListenerMap::iterator it = map.find(window);
-    ASSERT(it != map.end());
-
-    RegisteredEventListenerVector* listeners = it->second;
-    size_t index = listeners->find(listener);
-    ASSERT(index != WTF::notFound);
-    listeners->remove(index);
-
-    if (!listeners->isEmpty())
-        return;
-
-    map.remove(it);
-    delete listeners;
-
-    if (map.isEmpty())
-        enableSuddenTermination();
-}
-
-static void removePendingEventListeners(DOMWindowRegisteredEventListenerMap& map, DOMWindow* window)
-{
-    ASSERT_ARG(window, window);
-
-    RegisteredEventListenerVector* listeners = map.take(window);
-    if (!listeners)
-        return;
-
-    delete listeners;
-
-    if (map.isEmpty())
-        enableSuddenTermination();
+    if (!page)
+        return false;
+    return frame == page->mainFrame();
 }
 
 bool DOMWindow::dispatchAllPendingBeforeUnloadEvents()
 {
-    DOMWindowRegisteredEventListenerMap& map = pendingBeforeUnloadEventListenerMap();
-    if (map.isEmpty())
+    DOMWindowSet& set = windowsWithBeforeUnloadEventListeners();
+    if (set.isEmpty())
         return true;
 
     static bool alreadyDispatched = false;
@@ -208,20 +161,21 @@ bool DOMWindow::dispatchAllPendingBeforeUnloadEvents()
         return true;
 
     Vector<RefPtr<DOMWindow> > windows;
-    DOMWindowRegisteredEventListenerMap::iterator mapEnd = map.end();
-    for (DOMWindowRegisteredEventListenerMap::iterator it = map.begin(); it != mapEnd; ++it)
+    DOMWindowSet::iterator end = set.end();
+    for (DOMWindowSet::iterator it = set.begin(); it != end; ++it)
         windows.append(it->first);
 
     size_t size = windows.size();
     for (size_t i = 0; i < size; ++i) {
         DOMWindow* window = windows[i].get();
-        RegisteredEventListenerVector* listeners = map.get(window);
-        if (!listeners)
+        if (!set.contains(window))
             continue;
 
-        RegisteredEventListenerVector listenersCopy = *listeners;
         Frame* frame = window->frame();
-        if (!frame->shouldClose(&listenersCopy))
+        if (!frame)
+            continue;
+
+        if (!frame->shouldClose())
             return false;
     }
 
@@ -234,14 +188,13 @@ bool DOMWindow::dispatchAllPendingBeforeUnloadEvents()
 
 unsigned DOMWindow::pendingUnloadEventListeners() const
 {
-    RegisteredEventListenerVector* listeners = pendingUnloadEventListenerMap().get(const_cast<DOMWindow*>(this));
-    return listeners ? listeners->size() : 0;
+    return windowsWithUnloadEventListeners().count(const_cast<DOMWindow*>(this));
 }
 
 void DOMWindow::dispatchAllPendingUnloadEvents()
 {
-    DOMWindowRegisteredEventListenerMap& map = pendingUnloadEventListenerMap();
-    if (map.isEmpty())
+    DOMWindowSet& set = windowsWithBeforeUnloadEventListeners();
+    if (set.isEmpty())
         return;
 
     static bool alreadyDispatched = false;
@@ -250,19 +203,18 @@ void DOMWindow::dispatchAllPendingUnloadEvents()
         return;
 
     Vector<RefPtr<DOMWindow> > windows;
-    DOMWindowRegisteredEventListenerMap::iterator mapEnd = map.end();
-    for (DOMWindowRegisteredEventListenerMap::iterator it = map.begin(); it != mapEnd; ++it)
+    DOMWindowSet::iterator end = set.end();
+    for (DOMWindowSet::iterator it = set.begin(); it != end; ++it)
         windows.append(it->first);
 
     size_t size = windows.size();
     for (size_t i = 0; i < size; ++i) {
         DOMWindow* window = windows[i].get();
-        RegisteredEventListenerVector* listeners = map.get(window);
-        if (!listeners)
+        if (!set.contains(window))
             continue;
-        RegisteredEventListenerVector listenersCopy = *listeners;
-        window->dispatchPageTransitionEvent(EventNames().pagehideEvent, false);
-        window->dispatchUnloadEvent(&listenersCopy);
+
+        window->dispatchEvent(PageTransitionEvent::create(EventNames().pagehideEvent, false), window->document());
+        window->dispatchEvent(Event::create(eventNames().unloadEvent, false, false), window->document());
     }
 
     enableSuddenTermination();
@@ -376,8 +328,8 @@ DOMWindow::~DOMWindow()
     if (m_frame)
         m_frame->clearFormerDOMWindow(this);
 
-    removePendingEventListeners(pendingUnloadEventListenerMap(), this);
-    removePendingEventListeners(pendingBeforeUnloadEventListenerMap(), this);
+    windowsWithUnloadEventListeners().clear(this);
+    windowsWithBeforeUnloadEventListeners().clear(this);
 }
 
 ScriptExecutionContext* DOMWindow::scriptExecutionContext() const
@@ -471,7 +423,7 @@ int DOMWindow::orientation() const
     return m_frame->orientation();
 }
 #endif
-    
+
 Screen* DOMWindow::screen() const
 {
     if (!m_screen)
@@ -692,8 +644,7 @@ void DOMWindow::postMessageTimerFired(PostMessageTimer* t)
         }
     }
 
-    ExceptionCode ec = 0;
-    dispatchEvent(timer->event(document()), ec);
+    dispatchEvent(timer->event(document()));
 }
 
 DOMSelection* DOMWindow::getSelection()
@@ -1255,104 +1206,38 @@ void DOMWindow::clearInterval(int timeoutId)
     DOMTimer::removeById(scriptExecutionContext(), timeoutId);
 }
 
-void DOMWindow::handleEvent(Event* event, bool useCapture, RegisteredEventListenerVector* alternateListeners)
+bool DOMWindow::addEventListener(const AtomicString& eventType, PassRefPtr<EventListener> listener, bool useCapture)
 {
-    RegisteredEventListenerVector& listeners = (alternateListeners ? *alternateListeners : m_eventListeners);
-    if (listeners.isEmpty())
-        return;
-
-    // If any HTML event listeners are registered on the window, dispatch them here.
-    RegisteredEventListenerVector listenersCopy = listeners;
-    size_t size = listenersCopy.size();
-    for (size_t i = 0; i < size; ++i) {
-        RegisteredEventListener& r = *listenersCopy[i];
-        if (r.eventType() == event->type() && r.useCapture() == useCapture && !r.removed())
-            r.listener()->handleEvent(event, true);
-    }
-}
+    if (!EventTarget::addEventListener(eventType, listener, useCapture))
+        return false;
 
-void DOMWindow::addEventListener(const AtomicString& eventType, PassRefPtr<EventListener> listener, bool useCapture)
-{
-    // Remove existing identical listener set with identical arguments.
-    // The DOM 2 spec says that "duplicate instances are discarded" in this case.
-    removeEventListener(eventType, listener.get(), useCapture);
     if (Document* document = this->document())
         document->addListenerTypeIfNeeded(eventType);
 
-    RefPtr<RegisteredEventListener> registeredListener = RegisteredEventListener::create(eventType, listener, useCapture);
-    m_eventListeners.append(registeredListener);
-
     if (eventType == eventNames().unloadEvent)
-        addPendingEventListener(pendingUnloadEventListenerMap(), this, registeredListener.get());
-    else if (eventType == eventNames().beforeunloadEvent && allowsPendingBeforeUnloadListeners(this))
-        addPendingEventListener(pendingBeforeUnloadEventListenerMap(), this, registeredListener.get());
-}
+        windowsWithUnloadEventListeners().add(this);
+    else if (eventType == eventNames().beforeunloadEvent && allowsBeforeUnloadListeners(this))
+        windowsWithBeforeUnloadEventListeners().add(this);
 
-void DOMWindow::removeEventListener(const AtomicString& eventType, EventListener* listener, bool useCapture)
-{
-    size_t size = m_eventListeners.size();
-    for (size_t i = 0; i < size; ++i) {
-        RegisteredEventListener& r = *m_eventListeners[i];
-        if (r.eventType() == eventType && r.useCapture() == useCapture && *r.listener() == *listener) {
-            if (eventType == eventNames().unloadEvent)
-                removePendingEventListener(pendingUnloadEventListenerMap(), this, &r);
-            else if (eventType == eventNames().beforeunloadEvent && allowsPendingBeforeUnloadListeners(this))
-                removePendingEventListener(pendingBeforeUnloadEventListenerMap(), this, &r);
-            r.setRemoved(true);
-            m_eventListeners.remove(i);
-            return;
-        }
-    }
-}
-
-bool DOMWindow::dispatchEvent(PassRefPtr<Event> e, ExceptionCode& ec)
-{
-    ASSERT(!eventDispatchForbidden());
-
-    RefPtr<Event> event = e;
-    if (!event || event->type().isEmpty()) {
-        ec = EventException::UNSPECIFIED_EVENT_TYPE_ERR;
-        return true;
-    }
-
-    RefPtr<DOMWindow> protect(this);
-
-    event->setTarget(this);
-    event->setCurrentTarget(this);
-
-    handleEvent(event.get(), true);
-    handleEvent(event.get(), false);
-
-    return !event->defaultPrevented();
-}
-
-void DOMWindow::dispatchEvent(const AtomicString& eventType, bool canBubble, bool cancelable)
-{
-    ASSERT(!eventDispatchForbidden());
-    ExceptionCode ec = 0;
-    dispatchEvent(Event::create(eventType, canBubble, cancelable), ec);
+    return true;
 }
 
-// This function accommodates the Firefox quirk of dispatching the load, unload and
-// beforeunload events on the window, but setting event.target to be the Document. 
-inline void DOMWindow::dispatchEventWithDocumentAsTarget(PassRefPtr<Event> e, RegisteredEventListenerVector* alternateEventListeners)
+bool DOMWindow::removeEventListener(const AtomicString& eventType, EventListener* listener, bool useCapture)
 {
-    ASSERT(!eventDispatchForbidden());
-
-    RefPtr<Event> event = e;
-    RefPtr<DOMWindow> protect(this);
-    RefPtr<Document> document = this->document();
+    if (!EventTarget::removeEventListener(eventType, listener, useCapture))
+        return false;
 
-    event->setTarget(document);
-    event->setCurrentTarget(this);
+    if (eventType == eventNames().unloadEvent)
+        windowsWithUnloadEventListeners().remove(this);
+    else if (eventType == eventNames().beforeunloadEvent && allowsBeforeUnloadListeners(this))
+        windowsWithBeforeUnloadEventListeners().remove(this);
 
-    handleEvent(event.get(), true, alternateEventListeners);
-    handleEvent(event.get(), false, alternateEventListeners);
+    return true;
 }
 
 void DOMWindow::dispatchLoadEvent()
 {
-    dispatchEventWithDocumentAsTarget(Event::create(eventNames().loadEvent, false, false));
+    dispatchEvent(Event::create(eventNames().loadEvent, false, false), document());
 
     // For load events, send a separate load event to the enclosing frame only.
     // This is a DOM extension and is independent of bubbling/capturing rules of
@@ -1365,759 +1250,44 @@ void DOMWindow::dispatchLoadEvent()
     }
 }
 
-void DOMWindow::dispatchUnloadEvent(RegisteredEventListenerVector* alternateEventListeners)
+bool DOMWindow::dispatchEvent(PassRefPtr<Event> prpEvent, PassRefPtr<EventTarget> prpTarget)
 {
-    dispatchEventWithDocumentAsTarget(Event::create(eventNames().unloadEvent, false, false), alternateEventListeners);
-}
+    RefPtr<EventTarget> protect = this;
+    RefPtr<Event> event = prpEvent;
 
-PassRefPtr<BeforeUnloadEvent> DOMWindow::dispatchBeforeUnloadEvent(RegisteredEventListenerVector* alternateEventListeners)
-{
-    RefPtr<BeforeUnloadEvent> beforeUnloadEvent = BeforeUnloadEvent::create();
-    dispatchEventWithDocumentAsTarget(beforeUnloadEvent.get(), alternateEventListeners);
-    return beforeUnloadEvent.release();
-}
+    event->setTarget(prpTarget ? prpTarget : this);
+    event->setCurrentTarget(this);
+    event->setEventPhase(Event::AT_TARGET);
 
-void DOMWindow::dispatchPageTransitionEvent(const AtomicString& eventType, bool persisted)
-{
-    dispatchEventWithDocumentAsTarget(PageTransitionEvent::create(eventType, persisted));
+    return fireEventListeners(event.get());
 }
 
 void DOMWindow::removeAllEventListeners()
 {
-    size_t size = m_eventListeners.size();
-    for (size_t i = 0; i < size; ++i)
-        m_eventListeners[i]->setRemoved(true);
-    m_eventListeners.clear();
-
-    removePendingEventListeners(pendingUnloadEventListenerMap(), this);
-    removePendingEventListeners(pendingBeforeUnloadEventListenerMap(), this);
-}
-
-bool DOMWindow::hasEventListener(const AtomicString& eventType)
-{
-    size_t size = m_eventListeners.size();
-    for (size_t i = 0; i < size; ++i) {
-        if (m_eventListeners[i]->eventType() == eventType)
-            return true;
-    }
-    return false;
-}
-
-void DOMWindow::setAttributeEventListener(const AtomicString& eventType, PassRefPtr<EventListener> listener)
-{
-    clearAttributeEventListener(eventType);
-    if (listener)
-        addEventListener(eventType, listener, false);
-}
-
-void DOMWindow::clearAttributeEventListener(const AtomicString& eventType)
-{
-    size_t size = m_eventListeners.size();
-    for (size_t i = 0; i < size; ++i) {
-        RegisteredEventListener& r = *m_eventListeners[i];
-        if (r.eventType() == eventType && r.listener()->isAttribute()) {
-            if (eventType == eventNames().unloadEvent)
-                removePendingEventListener(pendingUnloadEventListenerMap(), this, &r);
-            else if (eventType == eventNames().beforeunloadEvent && allowsPendingBeforeUnloadListeners(this))
-                removePendingEventListener(pendingBeforeUnloadEventListenerMap(), this, &r);
-            r.setRemoved(true);
-            m_eventListeners.remove(i);
-            return;
-        }
-    }
-}
-
-EventListener* DOMWindow::getAttributeEventListener(const AtomicString& eventType) const
-{
-    size_t size = m_eventListeners.size();
-    for (size_t i = 0; i < size; ++i) {
-        RegisteredEventListener& r = *m_eventListeners[i];
-        if (r.eventType() == eventType && r.listener()->isAttribute())
-            return r.listener();
-    }
-    return 0;
-}
-
-EventListener* DOMWindow::onabort() const
-{
-    return getAttributeEventListener(eventNames().abortEvent);
-}
-
-void DOMWindow::setOnabort(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().abortEvent, eventListener);
-}
-
-EventListener* DOMWindow::onblur() const
-{
-    return getAttributeEventListener(eventNames().blurEvent);
-}
-
-void DOMWindow::setOnblur(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().blurEvent, eventListener);
-}
-
-EventListener* DOMWindow::onchange() const
-{
-    return getAttributeEventListener(eventNames().changeEvent);
-}
-
-void DOMWindow::setOnchange(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().changeEvent, eventListener);
-}
-
-EventListener* DOMWindow::onclick() const
-{
-    return getAttributeEventListener(eventNames().clickEvent);
-}
-
-void DOMWindow::setOnclick(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().clickEvent, eventListener);
-}
-
-EventListener* DOMWindow::ondblclick() const
-{
-    return getAttributeEventListener(eventNames().dblclickEvent);
-}
-
-void DOMWindow::setOndblclick(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().dblclickEvent, eventListener);
-}
-
-EventListener* DOMWindow::ondrag() const
-{
-    return getAttributeEventListener(eventNames().dragEvent);
-}
-
-void DOMWindow::setOndrag(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().dragEvent, eventListener);
-}
-
-EventListener* DOMWindow::ondragend() const
-{
-    return getAttributeEventListener(eventNames().dragendEvent);
-}
-
-void DOMWindow::setOndragend(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().dragendEvent, eventListener);
-}
-
-EventListener* DOMWindow::ondragenter() const
-{
-    return getAttributeEventListener(eventNames().dragenterEvent);
-}
-
-void DOMWindow::setOndragenter(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().dragenterEvent, eventListener);
-}
-
-EventListener* DOMWindow::ondragleave() const
-{
-    return getAttributeEventListener(eventNames().dragleaveEvent);
-}
-
-void DOMWindow::setOndragleave(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().dragleaveEvent, eventListener);
-}
-
-EventListener* DOMWindow::ondragover() const
-{
-    return getAttributeEventListener(eventNames().dragoverEvent);
-}
-
-void DOMWindow::setOndragover(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().dragoverEvent, eventListener);
-}
-
-EventListener* DOMWindow::ondragstart() const
-{
-    return getAttributeEventListener(eventNames().dragstartEvent);
-}
-
-void DOMWindow::setOndragstart(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().dragstartEvent, eventListener);
-}
-
-EventListener* DOMWindow::ondrop() const
-{
-    return getAttributeEventListener(eventNames().dropEvent);
-}
-
-void DOMWindow::setOndrop(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().dropEvent, eventListener);
-}
-
-EventListener* DOMWindow::onerror() const
-{
-    return getAttributeEventListener(eventNames().errorEvent);
-}
-
-void DOMWindow::setOnerror(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().errorEvent, eventListener);
-}
-
-EventListener* DOMWindow::onfocus() const
-{
-    return getAttributeEventListener(eventNames().focusEvent);
-}
-
-void DOMWindow::setOnfocus(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().focusEvent, eventListener);
-}
-
-EventListener* DOMWindow::onhashchange() const
-{
-    return getAttributeEventListener(eventNames().hashchangeEvent);
-}
-
-void DOMWindow::setOnhashchange(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().hashchangeEvent, eventListener);
-}
-
-EventListener* DOMWindow::onkeydown() const
-{
-    return getAttributeEventListener(eventNames().keydownEvent);
-}
-
-void DOMWindow::setOnkeydown(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().keydownEvent, eventListener);
-}
-
-EventListener* DOMWindow::onkeypress() const
-{
-    return getAttributeEventListener(eventNames().keypressEvent);
-}
-
-void DOMWindow::setOnkeypress(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().keypressEvent, eventListener);
-}
-
-EventListener* DOMWindow::onkeyup() const
-{
-    return getAttributeEventListener(eventNames().keyupEvent);
-}
-
-void DOMWindow::setOnkeyup(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().keyupEvent, eventListener);
-}
-
-EventListener* DOMWindow::onload() const
-{
-    return getAttributeEventListener(eventNames().loadEvent);
-}
-
-void DOMWindow::setOnload(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().loadEvent, eventListener);
-}
-
-EventListener* DOMWindow::onmousedown() const
-{
-    return getAttributeEventListener(eventNames().mousedownEvent);
-}
-
-void DOMWindow::setOnmousedown(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().mousedownEvent, eventListener);
-}
-
-EventListener* DOMWindow::onmousemove() const
-{
-    return getAttributeEventListener(eventNames().mousemoveEvent);
-}
-
-void DOMWindow::setOnmousemove(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().mousemoveEvent, eventListener);
-}
-
-EventListener* DOMWindow::onmouseout() const
-{
-    return getAttributeEventListener(eventNames().mouseoutEvent);
-}
-
-void DOMWindow::setOnmouseout(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().mouseoutEvent, eventListener);
-}
-
-EventListener* DOMWindow::onmouseover() const
-{
-    return getAttributeEventListener(eventNames().mouseoverEvent);
-}
-
-void DOMWindow::setOnmouseover(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().mouseoverEvent, eventListener);
-}
-
-EventListener* DOMWindow::onmouseup() const
-{
-    return getAttributeEventListener(eventNames().mouseupEvent);
-}
-
-void DOMWindow::setOnmouseup(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().mouseupEvent, eventListener);
-}
-
-EventListener* DOMWindow::onmousewheel() const
-{
-    return getAttributeEventListener(eventNames().mousewheelEvent);
-}
-
-void DOMWindow::setOnmousewheel(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().mousewheelEvent, eventListener);
-}
-
-EventListener* DOMWindow::onoffline() const
-{
-    return getAttributeEventListener(eventNames().offlineEvent);
-}
-
-void DOMWindow::setOnoffline(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().offlineEvent, eventListener);
-}
-
-EventListener* DOMWindow::ononline() const
-{
-    return getAttributeEventListener(eventNames().onlineEvent);
-}
-
-void DOMWindow::setOnonline(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().onlineEvent, eventListener);
-}
-
-EventListener* DOMWindow::onpagehide() const
-{
-    return getAttributeEventListener(eventNames().pagehideEvent);
-}
-
-void DOMWindow::setOnpagehide(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().pagehideEvent, eventListener);
-}
-
-EventListener* DOMWindow::onpageshow() const
-{
-    return getAttributeEventListener(eventNames().pageshowEvent);
-}
+    EventTarget::removeAllEventListeners();
 
-void DOMWindow::setOnpageshow(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().pageshowEvent, eventListener);
-}
-
-EventListener* DOMWindow::onreset() const
-{
-    return getAttributeEventListener(eventNames().resetEvent);
-}
-
-void DOMWindow::setOnreset(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().resetEvent, eventListener);
-}
-
-EventListener* DOMWindow::onresize() const
-{
-    return getAttributeEventListener(eventNames().resizeEvent);
-}
-
-void DOMWindow::setOnresize(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().resizeEvent, eventListener);
-}
-
-EventListener* DOMWindow::onscroll() const
-{
-    return getAttributeEventListener(eventNames().scrollEvent);
-}
-
-void DOMWindow::setOnscroll(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().scrollEvent, eventListener);
-}
-
-EventListener* DOMWindow::onsearch() const
-{
-    return getAttributeEventListener(eventNames().searchEvent);
-}
-
-void DOMWindow::setOnsearch(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().searchEvent, eventListener);
-}
-
-EventListener* DOMWindow::onselect() const
-{
-    return getAttributeEventListener(eventNames().selectEvent);
-}
-
-void DOMWindow::setOnselect(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().selectEvent, eventListener);
-}
-
-EventListener* DOMWindow::onstorage() const
-{
-    return getAttributeEventListener(eventNames().storageEvent);
-}
-
-void DOMWindow::setOnstorage(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().storageEvent, eventListener);
-}
-
-EventListener* DOMWindow::onsubmit() const
-{
-    return getAttributeEventListener(eventNames().submitEvent);
-}
-
-void DOMWindow::setOnsubmit(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().submitEvent, eventListener);
-}
-
-EventListener* DOMWindow::onunload() const
-{
-    return getAttributeEventListener(eventNames().unloadEvent);
-}
-
-void DOMWindow::setOnunload(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().unloadEvent, eventListener);
-}
-
-EventListener* DOMWindow::onbeforeunload() const
-{
-    return getAttributeEventListener(eventNames().beforeunloadEvent);
-}
-
-void DOMWindow::setOnbeforeunload(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().beforeunloadEvent, eventListener);
-}
-
-EventListener* DOMWindow::onwebkitanimationstart() const
-{
-    return getAttributeEventListener(eventNames().webkitAnimationStartEvent);
-}
-
-void DOMWindow::setOnwebkitanimationstart(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().webkitAnimationStartEvent, eventListener);
-}
-
-EventListener* DOMWindow::onwebkitanimationiteration() const
-{
-    return getAttributeEventListener(eventNames().webkitAnimationIterationEvent);
-}
-
-void DOMWindow::setOnwebkitanimationiteration(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().webkitAnimationIterationEvent, eventListener);
-}
-
-EventListener* DOMWindow::onwebkitanimationend() const
-{
-    return getAttributeEventListener(eventNames().webkitAnimationEndEvent);
-}
-
-void DOMWindow::setOnwebkitanimationend(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().webkitAnimationEndEvent, eventListener);
-}
-
-EventListener* DOMWindow::onwebkittransitionend() const
-{
-    return getAttributeEventListener(eventNames().webkitTransitionEndEvent);
-}
-
-void DOMWindow::setOnwebkittransitionend(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().webkitTransitionEndEvent, eventListener);
-}
-
-EventListener* DOMWindow::oncanplay() const
-{
-    return getAttributeEventListener(eventNames().canplayEvent);
-}
-
-void DOMWindow::setOncanplay(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().canplayEvent, eventListener);
-}
-
-EventListener* DOMWindow::oncanplaythrough() const
-{
-    return getAttributeEventListener(eventNames().canplaythroughEvent);
-}
-
-void DOMWindow::setOncanplaythrough(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().canplaythroughEvent, eventListener);
-}
-
-EventListener* DOMWindow::ondurationchange() const
-{
-    return getAttributeEventListener(eventNames().durationchangeEvent);
-}
-
-void DOMWindow::setOndurationchange(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().durationchangeEvent, eventListener);
-}
-
-EventListener* DOMWindow::onemptied() const
-{
-    return getAttributeEventListener(eventNames().emptiedEvent);
-}
-
-void DOMWindow::setOnemptied(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().emptiedEvent, eventListener);
-}
-
-EventListener* DOMWindow::onended() const
-{
-    return getAttributeEventListener(eventNames().endedEvent);
-}
-
-void DOMWindow::setOnended(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().endedEvent, eventListener);
+    windowsWithUnloadEventListeners().clear(this);
+    windowsWithBeforeUnloadEventListeners().clear(this);
 }
 
-EventListener* DOMWindow::onloadeddata() const
-{
-    return getAttributeEventListener(eventNames().loadeddataEvent);
-}
-
-void DOMWindow::setOnloadeddata(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().loadeddataEvent, eventListener);
-}
-
-EventListener* DOMWindow::onloadedmetadata() const
-{
-    return getAttributeEventListener(eventNames().loadedmetadataEvent);
-}
-
-void DOMWindow::setOnloadedmetadata(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().loadedmetadataEvent, eventListener);
-}
-
-EventListener* DOMWindow::onpause() const
-{
-    return getAttributeEventListener(eventNames().pauseEvent);
-}
-
-void DOMWindow::setOnpause(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().pauseEvent, eventListener);
-}
-
-EventListener* DOMWindow::onplay() const
-{
-    return getAttributeEventListener(eventNames().playEvent);
-}
-
-void DOMWindow::setOnplay(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().playEvent, eventListener);
-}
-
-EventListener* DOMWindow::onplaying() const
-{
-    return getAttributeEventListener(eventNames().playingEvent);
-}
-
-void DOMWindow::setOnplaying(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().playingEvent, eventListener);
-}
-
-EventListener* DOMWindow::onratechange() const
-{
-    return getAttributeEventListener(eventNames().ratechangeEvent);
-}
-
-void DOMWindow::setOnratechange(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().ratechangeEvent, eventListener);
-}
-
-EventListener* DOMWindow::onseeked() const
-{
-    return getAttributeEventListener(eventNames().seekedEvent);
-}
-
-void DOMWindow::setOnseeked(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().seekedEvent, eventListener);
-}
-
-EventListener* DOMWindow::onseeking() const
-{
-    return getAttributeEventListener(eventNames().seekingEvent);
-}
-
-void DOMWindow::setOnseeking(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().seekingEvent, eventListener);
-}
-
-EventListener* DOMWindow::ontimeupdate() const
-{
-    return getAttributeEventListener(eventNames().timeupdateEvent);
-}
-
-void DOMWindow::setOntimeupdate(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().timeupdateEvent, eventListener);
-}
-
-EventListener* DOMWindow::onvolumechange() const
-{
-    return getAttributeEventListener(eventNames().volumechangeEvent);
-}
-
-void DOMWindow::setOnvolumechange(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().volumechangeEvent, eventListener);
-}
-
-EventListener* DOMWindow::onwaiting() const
-{
-    return getAttributeEventListener(eventNames().waitingEvent);
-}
-
-void DOMWindow::setOnwaiting(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().waitingEvent, eventListener);
-}
-
-EventListener* DOMWindow::onloadstart() const
-{
-    return getAttributeEventListener(eventNames().loadstartEvent);
-}
-
-void DOMWindow::setOnloadstart(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().loadstartEvent, eventListener);
-}
-
-EventListener* DOMWindow::onprogress() const
-{
-    return getAttributeEventListener(eventNames().progressEvent);
-}
-
-void DOMWindow::setOnprogress(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().progressEvent, eventListener);
-}
-
-EventListener* DOMWindow::onstalled() const
-{
-    return getAttributeEventListener(eventNames().stalledEvent);
-}
-
-void DOMWindow::setOnstalled(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().stalledEvent, eventListener);
-}
-
-EventListener* DOMWindow::onsuspend() const
-{
-    return getAttributeEventListener(eventNames().suspendEvent);
-}
-
-void DOMWindow::setOnsuspend(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().suspendEvent, eventListener);
-}
-
-EventListener* DOMWindow::oninput() const
-{
-    return getAttributeEventListener(eventNames().inputEvent);
-}
-
-void DOMWindow::setOninput(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().inputEvent, eventListener);
-}
-
-EventListener* DOMWindow::onmessage() const
-{
-    return getAttributeEventListener(eventNames().messageEvent);
-}
-
-void DOMWindow::setOnmessage(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().messageEvent, eventListener);
-}
-
-EventListener* DOMWindow::oncontextmenu() const
-{
-    return getAttributeEventListener(eventNames().contextmenuEvent);
-}
-
-void DOMWindow::setOncontextmenu(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().contextmenuEvent, eventListener);
-}
-
-EventListener* DOMWindow::oninvalid() const
-{
-    return getAttributeEventListener(eventNames().invalidEvent);
-}
-
-void DOMWindow::setOninvalid(PassRefPtr<EventListener> eventListener)
-{
-    setAttributeEventListener(eventNames().invalidEvent, eventListener);
-}
-
-#if ENABLE(ORIENTATION_EVENTS)
-EventListener* DOMWindow::onorientationchange() const
+void DOMWindow::captureEvents()
 {
-    return getAttributeEventListener(eventNames().orientationchangeEvent);
+    // Not implemented.
 }
 
-void DOMWindow::setOnorientationchange(PassRefPtr<EventListener> eventListener)
+void DOMWindow::releaseEvents()
 {
-    setAttributeEventListener(eventNames().orientationchangeEvent, eventListener);
+    // Not implemented.
 }
-#endif
 
-void DOMWindow::captureEvents()
+EventTargetData* DOMWindow::eventTargetData()
 {
-    // Not implemented.
+    return &m_eventTargetData;
 }
 
-void DOMWindow::releaseEvents()
+EventTargetData* DOMWindow::ensureEventTargetData()
 {
-    // Not implemented.
+    return &m_eventTargetData;
 }
 
 } // namespace WebCore
diff --git a/WebCore/page/DOMWindow.h b/WebCore/page/DOMWindow.h
index 8817511..f2177ee 100644
--- a/WebCore/page/DOMWindow.h
+++ b/WebCore/page/DOMWindow.h
@@ -237,164 +237,85 @@ namespace WebCore {
 
         // Events
         // EventTarget API
-        virtual void addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture);
-        virtual void removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture);
-        virtual bool dispatchEvent(PassRefPtr<Event>, ExceptionCode&);
+        virtual bool addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture);
+        virtual bool removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture);
+        virtual void removeAllEventListeners();
 
-        void handleEvent(Event*, bool useCapture, RegisteredEventListenerVector* = 0);
-
-        void dispatchEvent(const AtomicString& eventType, bool canBubble, bool cancelable);
+        using EventTarget::dispatchEvent;
+        bool dispatchEvent(PassRefPtr<Event> prpEvent, PassRefPtr<EventTarget> prpTarget);
         void dispatchLoadEvent();
-        void dispatchUnloadEvent(RegisteredEventListenerVector* = 0);
-        PassRefPtr<BeforeUnloadEvent> dispatchBeforeUnloadEvent(RegisteredEventListenerVector* = 0);
-        void dispatchPageTransitionEvent(const AtomicString& eventType, bool persisted);
-
-        // Used for legacy "onEvent" property APIs.
-        void setAttributeEventListener(const AtomicString& eventType, PassRefPtr<EventListener>);
-        void clearAttributeEventListener(const AtomicString& eventType);
-        EventListener* getAttributeEventListener(const AtomicString& eventType) const;
-
-        const RegisteredEventListenerVector& eventListeners() const { return m_eventListeners; }
-        bool hasEventListener(const AtomicString& eventType);
-        void removeAllEventListeners();
-
-        EventListener* onabort() const;
-        void setOnabort(PassRefPtr<EventListener>);
-        EventListener* onblur() const;
-        void setOnblur(PassRefPtr<EventListener>);
-        EventListener* onchange() const;
-        void setOnchange(PassRefPtr<EventListener>);
-        EventListener* onclick() const;
-        void setOnclick(PassRefPtr<EventListener>);
-        EventListener* ondblclick() const;
-        void setOndblclick(PassRefPtr<EventListener>);
-        EventListener* ondrag() const;
-        void setOndrag(PassRefPtr<EventListener>);
-        EventListener* ondragend() const;
-        void setOndragend(PassRefPtr<EventListener>);
-        EventListener* ondragenter() const;
-        void setOndragenter(PassRefPtr<EventListener>);
-        EventListener* ondragleave() const;
-        void setOndragleave(PassRefPtr<EventListener>);
-        EventListener* ondragover() const;
-        void setOndragover(PassRefPtr<EventListener>);
-        EventListener* ondragstart() const;
-        void setOndragstart(PassRefPtr<EventListener>);
-        EventListener* ondrop() const;
-        void setOndrop(PassRefPtr<EventListener>);
-        EventListener* onerror() const;
-        void setOnerror(PassRefPtr<EventListener>);
-        EventListener* onfocus() const;
-        void setOnfocus(PassRefPtr<EventListener>);
-        EventListener* onhashchange() const;
-        void setOnhashchange(PassRefPtr<EventListener>);
-        EventListener* onkeydown() const;
-        void setOnkeydown(PassRefPtr<EventListener>);
-        EventListener* onkeypress() const;
-        void setOnkeypress(PassRefPtr<EventListener>);
-        EventListener* onkeyup() const;
-        void setOnkeyup(PassRefPtr<EventListener>);
-        EventListener* onload() const;
-        void setOnload(PassRefPtr<EventListener>);
-        EventListener* onmousedown() const;
-        void setOnmousedown(PassRefPtr<EventListener>);
-        EventListener* onmousemove() const;
-        void setOnmousemove(PassRefPtr<EventListener>);
-        EventListener* onmouseout() const;
-        void setOnmouseout(PassRefPtr<EventListener>);
-        EventListener* onmouseover() const;
-        void setOnmouseover(PassRefPtr<EventListener>);
-        EventListener* onmouseup() const;
-        void setOnmouseup(PassRefPtr<EventListener>);
-        EventListener* onmousewheel() const;
-        void setOnmousewheel(PassRefPtr<EventListener>);
-        EventListener* onoffline() const;
-        void setOnoffline(PassRefPtr<EventListener>);
-        EventListener* ononline() const;
-        void setOnonline(PassRefPtr<EventListener>);
-        EventListener* onpagehide() const;
-        void setOnpagehide(PassRefPtr<EventListener>);
-        EventListener* onpageshow() const;
-        void setOnpageshow(PassRefPtr<EventListener>);
-        EventListener* onreset() const;
-        void setOnreset(PassRefPtr<EventListener>);
-        EventListener* onresize() const;
-        void setOnresize(PassRefPtr<EventListener>);
-        EventListener* onscroll() const;
-        void setOnscroll(PassRefPtr<EventListener>);
-        EventListener* onsearch() const;
-        void setOnsearch(PassRefPtr<EventListener>);
-        EventListener* onselect() const;
-        void setOnselect(PassRefPtr<EventListener>);
-        EventListener* onstorage() const;
-        void setOnstorage(PassRefPtr<EventListener>);
-        EventListener* onsubmit() const;
-        void setOnsubmit(PassRefPtr<EventListener>);
-        EventListener* onunload() const;
-        void setOnunload(PassRefPtr<EventListener>);
-        EventListener* onbeforeunload() const;
-        void setOnbeforeunload(PassRefPtr<EventListener>);
-        EventListener* onwebkitanimationstart() const;
-        void setOnwebkitanimationstart(PassRefPtr<EventListener>);
-        EventListener* onwebkitanimationiteration() const;
-        void setOnwebkitanimationiteration(PassRefPtr<EventListener>);
-        EventListener* onwebkitanimationend() const;
-        void setOnwebkitanimationend(PassRefPtr<EventListener>);
-        EventListener* onwebkittransitionend() const;
-        void setOnwebkittransitionend(PassRefPtr<EventListener>);
-        EventListener* oncanplay() const;
-        void setOncanplay(PassRefPtr<EventListener>);
-        EventListener* oncanplaythrough() const;
-        void setOncanplaythrough(PassRefPtr<EventListener>);
-        EventListener* ondurationchange() const;
-        void setOndurationchange(PassRefPtr<EventListener>);
-        EventListener* onemptied() const;
-        void setOnemptied(PassRefPtr<EventListener>);
-        EventListener* onended() const;
-        void setOnended(PassRefPtr<EventListener>);
-        EventListener* onloadeddata() const;
-        void setOnloadeddata(PassRefPtr<EventListener>);
-        EventListener* onloadedmetadata() const;
-        void setOnloadedmetadata(PassRefPtr<EventListener>);
-        EventListener* onpause() const;
-        void setOnpause(PassRefPtr<EventListener>);
-        EventListener* onplay() const;
-        void setOnplay(PassRefPtr<EventListener>);
-        EventListener* onplaying() const;
-        void setOnplaying(PassRefPtr<EventListener>);
-        EventListener* onratechange() const;
-        void setOnratechange(PassRefPtr<EventListener>);
-        EventListener* onseeked() const;
-        void setOnseeked(PassRefPtr<EventListener>);
-        EventListener* onseeking() const;
-        void setOnseeking(PassRefPtr<EventListener>);
-        EventListener* ontimeupdate() const;
-        void setOntimeupdate(PassRefPtr<EventListener>);
-        EventListener* onvolumechange() const;
-        void setOnvolumechange(PassRefPtr<EventListener>);
-        EventListener* onwaiting() const;
-        void setOnwaiting(PassRefPtr<EventListener>);
-        EventListener* onloadstart() const;
-        void setOnloadstart(PassRefPtr<EventListener>);
-        EventListener* onprogress() const;
-        void setOnprogress(PassRefPtr<EventListener>);
-        EventListener* onstalled() const;
-        void setOnstalled(PassRefPtr<EventListener>);
-        EventListener* onsuspend() const;
-        void setOnsuspend(PassRefPtr<EventListener>);
-        EventListener* oninput() const;
-        void setOninput(PassRefPtr<EventListener>);
-        EventListener* onmessage() const;
-        void setOnmessage(PassRefPtr<EventListener>);
-        EventListener* oncontextmenu() const;
-        void setOncontextmenu(PassRefPtr<EventListener>);
-        EventListener* oninvalid() const;
-        void setOninvalid(PassRefPtr<EventListener>);
+
+        DEFINE_ATTRIBUTE_EVENT_LISTENER(abort);
+        DEFINE_ATTRIBUTE_EVENT_LISTENER(blur);
+        DEFINE_ATTRIBUTE_EVENT_LISTENER(change);
+        DEFINE_ATTRIBUTE_EVENT_LISTENER(click);
+        DEFINE_ATTRIBUTE_EVENT_LISTENER(dblclick);
+        DEFINE_ATTRIBUTE_EVENT_LISTENER(drag);
+        DEFINE_ATTRIBUTE_EVENT_LISTENER(dragend);
+        DEFINE_ATTRIBUTE_EVENT_LISTENER(dragenter);
+        DEFINE_ATTRIBUTE_EVENT_LISTENER(dragleave);
+        DEFINE_ATTRIBUTE_EVENT_LISTENER(dragover);
+        DEFINE_ATTRIBUTE_EVENT_LISTENER(dragstart);
+        DEFINE_ATTRIBUTE_EVENT_LISTENER(drop);
+        DEFINE_ATTRIBUTE_EVENT_LISTENER(error);
+        DEFINE_ATTRIBUTE_EVENT_LISTENER(focus);
+        DEFINE_ATTRIBUTE_EVENT_LISTENER(hashchange);
+        DEFINE_ATTRIBUTE_EVENT_LISTENER(keydown);
+        DEFINE_ATTRIBUTE_EVENT_LISTENER(keypress);
+        DEFINE_ATTRIBUTE_EVENT_LISTENER(keyup);
+        DEFINE_ATTRIBUTE_EVENT_LISTENER(load);
+        DEFINE_ATTRIBUTE_EVENT_LISTENER(mousedown);
+        DEFINE_ATTRIBUTE_EVENT_LISTENER(mousemove);
+        DEFINE_ATTRIBUTE_EVENT_LISTENER(mouseout);
+        DEFINE_ATTRIBUTE_EVENT_LISTENER(mouseover);
+        DEFINE_ATTRIBUTE_EVENT_LISTENER(mouseup);
+        DEFINE_ATTRIBUTE_EVENT_LISTENER(mousewheel);
+        DEFINE_ATTRIBUTE_EVENT_LISTENER(offline);
+        DEFINE_ATTRIBUTE_EVENT_LISTENER(online);
+        DEFINE_ATTRIBUTE_EVENT_LISTENER(pagehide);
+        DEFINE_ATTRIBUTE_EVENT_LISTENER(pageshow);
+        DEFINE_ATTRIBUTE_EVENT_LISTENER(reset);
+        DEFINE_ATTRIBUTE_EVENT_LISTENER(resize);
+        DEFINE_ATTRIBUTE_EVENT_LISTENER(scroll);
+        DEFINE_ATTRIBUTE_EVENT_LISTENER(search);
+        DEFINE_ATTRIBUTE_EVENT_LISTENER(select);
+        DEFINE_ATTRIBUTE_EVENT_LISTENER(storage);
+        DEFINE_ATTRIBUTE_EVENT_LISTENER(submit);
+        DEFINE_ATTRIBUTE_EVENT_LISTENER(unload);
+        DEFINE_ATTRIBUTE_EVENT_LISTENER(beforeunload);
+        DEFINE_ATTRIBUTE_EVENT_LISTENER(canplay);
+        DEFINE_ATTRIBUTE_EVENT_LISTENER(canplaythrough);
+        DEFINE_ATTRIBUTE_EVENT_LISTENER(durationchange);
+        DEFINE_ATTRIBUTE_EVENT_LISTENER(emptied);
+        DEFINE_ATTRIBUTE_EVENT_LISTENER(ended);
+        DEFINE_ATTRIBUTE_EVENT_LISTENER(loadeddata);
+        DEFINE_ATTRIBUTE_EVENT_LISTENER(loadedmetadata);
+        DEFINE_ATTRIBUTE_EVENT_LISTENER(pause);
+        DEFINE_ATTRIBUTE_EVENT_LISTENER(play);
+        DEFINE_ATTRIBUTE_EVENT_LISTENER(playing);
+        DEFINE_ATTRIBUTE_EVENT_LISTENER(ratechange);
+        DEFINE_ATTRIBUTE_EVENT_LISTENER(seeked);
+        DEFINE_ATTRIBUTE_EVENT_LISTENER(seeking);
+        DEFINE_ATTRIBUTE_EVENT_LISTENER(timeupdate);
+        DEFINE_ATTRIBUTE_EVENT_LISTENER(volumechange);
+        DEFINE_ATTRIBUTE_EVENT_LISTENER(waiting);
+        DEFINE_ATTRIBUTE_EVENT_LISTENER(loadstart);
+        DEFINE_ATTRIBUTE_EVENT_LISTENER(progress);
+        DEFINE_ATTRIBUTE_EVENT_LISTENER(stalled);
+        DEFINE_ATTRIBUTE_EVENT_LISTENER(suspend);
+        DEFINE_ATTRIBUTE_EVENT_LISTENER(input);
+        DEFINE_ATTRIBUTE_EVENT_LISTENER(message);
+        DEFINE_ATTRIBUTE_EVENT_LISTENER(contextmenu);
+        DEFINE_ATTRIBUTE_EVENT_LISTENER(invalid);
 #if ENABLE(ORIENTATION_EVENTS)
-        EventListener* onorientationchange() const;
-        void setOnorientationchange(PassRefPtr<EventListener>);
+        DEFINE_ATTRIBUTE_EVENT_LISTENER(orientationchange);
 #endif
 
+        DEFINE_MAPPED_ATTRIBUTE_EVENT_LISTENER(webkitanimationstart, webkitAnimationStart);
+        DEFINE_MAPPED_ATTRIBUTE_EVENT_LISTENER(webkitanimationiteration, webkitAnimationIteration);
+        DEFINE_MAPPED_ATTRIBUTE_EVENT_LISTENER(webkitanimationend, webkitAnimationEnd);
+        DEFINE_MAPPED_ATTRIBUTE_EVENT_LISTENER(webkittransitionend, webkitTransitionEnd);
+
         void captureEvents();
         void releaseEvents();
 
@@ -428,8 +349,8 @@ namespace WebCore {
 
         virtual void refEventTarget() { ref(); }
         virtual void derefEventTarget() { deref(); }
-
-        void dispatchEventWithDocumentAsTarget(PassRefPtr<Event>, RegisteredEventListenerVector* = 0);
+        virtual EventTargetData* eventTargetData();
+        virtual EventTargetData* ensureEventTargetData();
 
         RefPtr<SecurityOrigin> m_securityOrigin;
         KURL m_url;
@@ -458,7 +379,7 @@ namespace WebCore {
         mutable RefPtr<NotificationCenter> m_notifications;
 #endif
 
-        RegisteredEventListenerVector m_eventListeners;
+        EventTargetData m_eventTargetData;
     };
 
 } // namespace WebCore
diff --git a/WebCore/page/DOMWindow.idl b/WebCore/page/DOMWindow.idl
index 03a0ce3..f36175e 100644
--- a/WebCore/page/DOMWindow.idl
+++ b/WebCore/page/DOMWindow.idl
@@ -39,6 +39,7 @@ module window {
         CustomNativeConverter,
         CustomPutFunction,
         ExtendsDOMGlobalObject,
+        EventTarget,
         GenerateNativeConverter,
         LegacyParent=JSDOMWindowBase
     ] DOMWindow {
diff --git a/WebCore/page/EventHandler.cpp b/WebCore/page/EventHandler.cpp
index 1fe01b9..8d519ef 100644
--- a/WebCore/page/EventHandler.cpp
+++ b/WebCore/page/EventHandler.cpp
@@ -1897,7 +1897,7 @@ bool EventHandler::canMouseDownStartSelect(Node* node)
             
     for (RenderObject* curr = node->renderer(); curr; curr = curr->parent()) {
         if (Node* node = curr->node())
-            return node->dispatchEvent(eventNames().selectstartEvent, true, true);
+            return node->dispatchEvent(Event::create(eventNames().selectstartEvent, true, true));
     }
 
     return true;
@@ -1911,7 +1911,7 @@ bool EventHandler::canMouseDragExtendSelect(Node* node)
             
     for (RenderObject* curr = node->renderer(); curr; curr = curr->parent()) {
         if (Node* node = curr->node())
-            return node->dispatchEvent(eventNames().selectstartEvent, true, true);
+            return node->dispatchEvent(Event::create(eventNames().selectstartEvent, true, true));
     }
 
     return true;
@@ -2466,7 +2466,7 @@ void EventHandler::capsLockStateMayHaveChanged()
 
 void EventHandler::sendResizeEvent()
 {
-    m_frame->document()->dispatchWindowEvent(eventNames().resizeEvent, false, false);
+    m_frame->document()->dispatchWindowEvent(Event::create(eventNames().resizeEvent, false, false));
 }
 
 void EventHandler::sendScrollEvent()
@@ -2475,7 +2475,7 @@ void EventHandler::sendScrollEvent()
     if (!v)
         return;
     v->setWasScrolledByUser(true);
-    m_frame->document()->dispatchEvent(eventNames().scrollEvent, true, false);
+    m_frame->document()->dispatchEvent(Event::create(eventNames().scrollEvent, true, false));
 }
 
 bool EventHandler::passMousePressEventToScrollbar(MouseEventWithHitTestResults& mev, Scrollbar* scrollbar)
diff --git a/WebCore/page/EventSource.cpp b/WebCore/page/EventSource.cpp
index afec20f..ae3c0c3 100644
--- a/WebCore/page/EventSource.cpp
+++ b/WebCore/page/EventSource.cpp
@@ -108,7 +108,7 @@ void EventSource::endRequest()
     m_requestInFlight = false;
 
     if (!m_failSilently)
-        dispatchGenericEvent(eventNames().errorEvent);
+        dispatchEvent(Event::create(eventNames().errorEvent, false, false));
 
     if (!scriptExecutionContext()->isWorkerContext())
         cache()->loader()->nonCacheRequestComplete(m_url);
@@ -162,70 +162,12 @@ ScriptExecutionContext* EventSource::scriptExecutionContext() const
     return ActiveDOMObject::scriptExecutionContext();
 }
 
-void EventSource::addEventListener(const AtomicString& eventType, PassRefPtr<EventListener> eventListener, bool)
-{
-    EventListenersMap::iterator iter = m_eventListeners.find(eventType);
-    if (iter == m_eventListeners.end()) {
-        ListenerVector listeners;
-        listeners.append(eventListener);
-        m_eventListeners.add(eventType, listeners);
-    } else {
-        ListenerVector& listeners = iter->second;
-        for (ListenerVector::iterator listenerIter = listeners.begin(); listenerIter != listeners.end(); ++listenerIter) {
-            if (**listenerIter == *eventListener)
-                return;
-        }
-
-        listeners.append(eventListener);
-        m_eventListeners.add(eventType, listeners);
-    }
-}
-
-void EventSource::removeEventListener(const AtomicString& eventType, EventListener* eventListener, bool)
-{
-    EventListenersMap::iterator iter = m_eventListeners.find(eventType);
-    if (iter == m_eventListeners.end())
-        return;
-
-    ListenerVector& listeners = iter->second;
-    for (ListenerVector::const_iterator listenerIter = listeners.begin(); listenerIter != listeners.end(); ++listenerIter) {
-        if (**listenerIter == *eventListener) {
-            listeners.remove(listenerIter - listeners.begin());
-            return;
-        }
-    }
-}
-
-bool EventSource::dispatchEvent(PassRefPtr<Event> event, ExceptionCode& ec)
-{
-    if (!event || event->type().isEmpty()) {
-        ec = EventException::UNSPECIFIED_EVENT_TYPE_ERR;
-        return true;
-    }
-
-    EventListener* attributeListener = m_attributeListeners.get(event->type()).get();
-    if (attributeListener) {
-        event->setTarget(this);
-        event->setCurrentTarget(this);
-        attributeListener->handleEvent(event.get(), false);
-    }
-
-    ListenerVector listenersCopy = m_eventListeners.get(event->type());
-    for (ListenerVector::const_iterator listenerIter = listenersCopy.begin(); listenerIter != listenersCopy.end(); ++listenerIter) {
-        event->setTarget(this);
-        event->setCurrentTarget(this);
-        listenerIter->get()->handleEvent(event.get(), false);
-    }
-
-    return !event->defaultPrevented();
-}
-
 void EventSource::didReceiveResponse(const ResourceResponse& response)
 {
     int statusCode = response.httpStatusCode();
     if (statusCode == 200 && response.httpHeaderField("Content-Type") == "text/event-stream") {
         m_state = OPEN;
-        dispatchGenericEvent(eventNames().openEvent);
+        dispatchEvent(Event::create(eventNames().openEvent, false, false));
     } else {
         if (statusCode <= 200 || statusCode > 299)
             m_state = CLOSED;
@@ -304,7 +246,7 @@ void EventSource::parseEventStreamLine(unsigned int bufPos, int fieldLength, int
 {
     if (!lineLength) {
         if (!m_data.isEmpty())
-            dispatchMessageEvent();
+            dispatchEvent(createMessageEvent());
         if (!m_eventName.isEmpty())
             m_eventName = "";
     } else if (fieldLength) {
@@ -344,27 +286,26 @@ void EventSource::parseEventStreamLine(unsigned int bufPos, int fieldLength, int
     }
 }
 
-void EventSource::dispatchGenericEvent(const AtomicString& type)
+void EventSource::stop()
 {
-    RefPtr<Event> evt = Event::create(type, false, false);
-    ExceptionCode ec = 0;
-    dispatchEvent(evt.release(), ec);
-    ASSERT(!ec);
+    close();
 }
 
-void EventSource::dispatchMessageEvent()
+PassRefPtr<MessageEvent> EventSource::createMessageEvent()
 {
-    RefPtr<MessageEvent> evt = MessageEvent::create();
-    String eventName = m_eventName.isEmpty() ? eventNames().messageEvent.string() : m_eventName;
-    evt->initMessageEvent(eventName, false, false, String::adopt(m_data), m_origin, m_lastEventId, 0, 0);
-    ExceptionCode ec = 0;
-    dispatchEvent(evt.release(), ec);
-    ASSERT(!ec);
+    RefPtr<MessageEvent> event = MessageEvent::create();
+    event->initMessageEvent(m_eventName.isEmpty() ? eventNames().messageEvent : AtomicString(m_eventName), false, false, String::adopt(m_data), m_origin, m_lastEventId, 0, 0);
+    return event.release();
 }
 
-void EventSource::stop()
+EventTargetData* EventSource::eventTargetData()
 {
-    close();
+    return &m_eventTargetData;
+}
+
+EventTargetData* EventSource::ensureEventTargetData()
+{
+    return &m_eventTargetData;
 }
 
 } // namespace WebCore
diff --git a/WebCore/page/EventSource.h b/WebCore/page/EventSource.h
index df55694..5b037a4 100644
--- a/WebCore/page/EventSource.h
+++ b/WebCore/page/EventSource.h
@@ -50,6 +50,7 @@
 
 namespace WebCore {
 
+    class MessageEvent;
     class ResourceResponse;
     class TextResourceDecoder;
     class ThreadableLoader;
@@ -71,14 +72,9 @@ namespace WebCore {
 
         State readyState() const;
 
-        void setOnopen(PassRefPtr<EventListener> eventListener) { m_attributeListeners.set(eventNames().openEvent, eventListener); }
-        EventListener* onopen() const { return m_attributeListeners.get(eventNames().openEvent).get(); }
-
-        void setOnmessage(PassRefPtr<EventListener> eventListener) { m_attributeListeners.set(eventNames().messageEvent, eventListener); }
-        EventListener* onmessage() const { return m_attributeListeners.get(eventNames().messageEvent).get(); }
-
-        void setOnerror(PassRefPtr<EventListener> eventListener) { m_attributeListeners.set(eventNames().errorEvent, eventListener); }
-        EventListener* onerror() const { return m_attributeListeners.get(eventNames().errorEvent).get(); }
+        DEFINE_ATTRIBUTE_EVENT_LISTENER(open);
+        DEFINE_ATTRIBUTE_EVENT_LISTENER(message);
+        DEFINE_ATTRIBUTE_EVENT_LISTENER(error);
 
         void close();
 
@@ -88,14 +84,6 @@ namespace WebCore {
         virtual EventSource* toEventSource() { return this; }
         virtual ScriptExecutionContext* scriptExecutionContext() const;
 
-        typedef Vector<RefPtr<EventListener> > ListenerVector;
-        typedef HashMap<AtomicString, ListenerVector> EventListenersMap;
-
-        virtual void addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture);
-        virtual void removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture);
-        virtual bool dispatchEvent(PassRefPtr<Event>, ExceptionCode&);
-        EventListenersMap& eventListeners() { return m_eventListeners; }
-
         virtual void stop();
 
     private:
@@ -103,6 +91,8 @@ namespace WebCore {
 
         virtual void refEventTarget() { ref(); }
         virtual void derefEventTarget() { deref(); }
+        virtual EventTargetData* eventTargetData();
+        virtual EventTargetData* ensureEventTargetData();
 
         virtual void didReceiveResponse(const ResourceResponse& response);
         virtual void didReceiveData(const char* data, int length);
@@ -116,15 +106,11 @@ namespace WebCore {
         void reconnectTimerFired(Timer<EventSource>*);
         void parseEventStream();
         void parseEventStreamLine(unsigned int pos, int fieldLength, int lineLength);
-        void dispatchGenericEvent(const AtomicString& type);
-        void dispatchMessageEvent();
+        PassRefPtr<MessageEvent> createMessageEvent();
 
         KURL m_url;
         State m_state;
 
-        HashMap<AtomicString, RefPtr<EventListener> > m_attributeListeners;
-        EventListenersMap m_eventListeners;
-
         RefPtr<TextResourceDecoder> m_decoder;
         RefPtr<ThreadableLoader> m_loader;
         Timer<EventSource> m_reconnectTimer;
@@ -137,6 +123,8 @@ namespace WebCore {
         String m_lastEventId;
         unsigned long long m_reconnectDelay;
         String m_origin;
+        
+        EventTargetData m_eventTargetData;
     };
 
 } // namespace WebCore
diff --git a/WebCore/page/EventSource.idl b/WebCore/page/EventSource.idl
index c438e68..561bd68 100644
--- a/WebCore/page/EventSource.idl
+++ b/WebCore/page/EventSource.idl
@@ -33,7 +33,7 @@ module window {
 
     interface [
         Conditional=EVENTSOURCE,
-        CustomMarkFunction,
+        EventTarget,
         NoStaticTables
     ] EventSource {
 
diff --git a/WebCore/page/FocusController.cpp b/WebCore/page/FocusController.cpp
index bc9e477..5e78c7d 100644
--- a/WebCore/page/FocusController.cpp
+++ b/WebCore/page/FocusController.cpp
@@ -36,6 +36,7 @@
 #include "Event.h"
 #include "EventHandler.h"
 #include "EventNames.h"
+#include "ExceptionCode.h"
 #include "Frame.h"
 #include "FrameView.h"
 #include "FrameTree.h"
@@ -62,7 +63,7 @@ static inline void dispatchEventsOnWindowAndFocusedNode(Document* document, bool
     // https://bugs.webkit.org/show_bug.cgi?id=27105
     if (!focused && document->focusedNode())
         document->focusedNode()->dispatchBlurEvent();
-    document->dispatchWindowEvent(focused ? eventNames().focusEvent : eventNames().blurEvent, false, false);
+    document->dispatchWindowEvent(Event::create(focused ? eventNames().focusEvent : eventNames().blurEvent, false, false));
     if (focused && document->focusedNode())
         document->focusedNode()->dispatchFocusEvent();
 }
@@ -87,12 +88,12 @@ void FocusController::setFocusedFrame(PassRefPtr<Frame> frame)
     // Now that the frame is updated, fire events and update the selection focused states of both frames.
     if (oldFrame && oldFrame->view()) {
         oldFrame->selection()->setFocused(false);
-        oldFrame->document()->dispatchWindowEvent(eventNames().blurEvent, false, false);
+        oldFrame->document()->dispatchWindowEvent(Event::create(eventNames().blurEvent, false, false));
     }
 
     if (newFrame && newFrame->view() && isFocused()) {
         newFrame->selection()->setFocused(true);
-        newFrame->document()->dispatchWindowEvent(eventNames().focusEvent, false, false);
+        newFrame->document()->dispatchWindowEvent(Event::create(eventNames().focusEvent, false, false));
     }
 }
 
diff --git a/WebCore/page/Frame.cpp b/WebCore/page/Frame.cpp
index 1114dee..28e6a9e 100644
--- a/WebCore/page/Frame.cpp
+++ b/WebCore/page/Frame.cpp
@@ -1665,7 +1665,7 @@ void Frame::unfocusWindow()
         page()->chrome()->unfocus();
 }
 
-bool Frame::shouldClose(RegisteredEventListenerVector* alternateEventListeners)
+bool Frame::shouldClose()
 {
     Chrome* chrome = page() ? page()->chrome() : 0;
     if (!chrome || !chrome->canRunBeforeUnloadConfirmPanel())
@@ -1679,7 +1679,8 @@ bool Frame::shouldClose(RegisteredEventListenerVector* alternateEventListeners)
     if (!body)
         return true;
 
-    RefPtr<BeforeUnloadEvent> beforeUnloadEvent = m_domWindow->dispatchBeforeUnloadEvent(alternateEventListeners);
+    RefPtr<BeforeUnloadEvent> beforeUnloadEvent = BeforeUnloadEvent::create();
+    m_domWindow->dispatchEvent(beforeUnloadEvent.get(), m_domWindow->document());
 
     if (!beforeUnloadEvent->defaultPrevented())
         doc->defaultEventHandler(beforeUnloadEvent.get());
diff --git a/WebCore/page/Frame.h b/WebCore/page/Frame.h
index ceb6fc1..b98dbc4 100644
--- a/WebCore/page/Frame.h
+++ b/WebCore/page/Frame.h
@@ -198,7 +198,7 @@ namespace WebCore {
     public:
         void focusWindow();
         void unfocusWindow();
-        bool shouldClose(RegisteredEventListenerVector* alternateEventListeners = 0);
+        bool shouldClose();
         void scheduleClose();
 
         void setJSStatusBarText(const String&);
diff --git a/WebCore/page/Page.cpp b/WebCore/page/Page.cpp
index f6f6a81..182d22c 100644
--- a/WebCore/page/Page.cpp
+++ b/WebCore/page/Page.cpp
@@ -29,8 +29,10 @@
 #include "ContextMenuController.h"
 #include "DOMWindow.h"
 #include "DragController.h"
+#include "ExceptionCode.h"
 #include "EditorClient.h"
 #include "EventNames.h"
+#include "Event.h"
 #include "FileSystem.h"
 #include "FocusController.h"
 #include "Frame.h"
@@ -94,7 +96,7 @@ static void networkStateChanged()
 
     AtomicString eventName = networkStateNotifier().onLine() ? eventNames().onlineEvent : eventNames().offlineEvent;
     for (unsigned i = 0; i < frames.size(); i++)
-        frames[i]->document()->dispatchWindowEvent(eventName, false, false);
+        frames[i]->document()->dispatchWindowEvent(Event::create(eventName, false, false));
 }
 
 Page::Page(ChromeClient* chromeClient, ContextMenuClient* contextMenuClient, EditorClient* editorClient, DragClient* dragClient, InspectorClient* inspectorClient)
diff --git a/WebCore/page/animation/AnimationController.cpp b/WebCore/page/animation/AnimationController.cpp
index 1d2ebe2..691932e 100644
--- a/WebCore/page/animation/AnimationController.cpp
+++ b/WebCore/page/animation/AnimationController.cpp
@@ -36,6 +36,8 @@
 #include "EventNames.h"
 #include "Frame.h"
 #include "RenderView.h"
+#include "WebKitAnimationEvent.h"
+#include "WebKitTransitionEvent.h"
 #include <wtf/CurrentTime.h>
 #include <wtf/UnusedParam.h>
 
@@ -136,9 +138,9 @@ void AnimationControllerPrivate::updateStyleIfNeededDispatcherFired(Timer<Animat
     Vector<EventToDispatch>::const_iterator eventsToDispatchEnd = m_eventsToDispatch.end();
     for (Vector<EventToDispatch>::const_iterator it = m_eventsToDispatch.begin(); it != eventsToDispatchEnd; ++it) {
         if (it->eventType == eventNames().webkitTransitionEndEvent)
-            it->element->dispatchWebKitTransitionEvent(it->eventType, it->name, it->elapsedTime);
+            it->element->dispatchEvent(WebKitTransitionEvent::create(it->eventType, it->name, it->elapsedTime));
         else
-            it->element->dispatchWebKitAnimationEvent(it->eventType, it->name, it->elapsedTime);
+            it->element->dispatchEvent(WebKitAnimationEvent::create(it->eventType, it->name, it->elapsedTime));
     }
     
     m_eventsToDispatch.clear();
diff --git a/WebCore/rendering/RenderListBox.cpp b/WebCore/rendering/RenderListBox.cpp
index e6c28f7..f94f7ce 100644
--- a/WebCore/rendering/RenderListBox.cpp
+++ b/WebCore/rendering/RenderListBox.cpp
@@ -527,8 +527,7 @@ void RenderListBox::valueChanged(Scrollbar*)
     if (newOffset != m_indexOffset) {
         m_indexOffset = newOffset;
         repaint();
-        // Fire the scroll DOM event.
-        node()->dispatchEvent(eventNames().scrollEvent, false, false);
+        node()->dispatchEvent(Event::create(eventNames().scrollEvent, false, false));
     }
 }
 
diff --git a/WebCore/rendering/RenderTextControl.cpp b/WebCore/rendering/RenderTextControl.cpp
index 4f4b570..cd90854 100644
--- a/WebCore/rendering/RenderTextControl.cpp
+++ b/WebCore/rendering/RenderTextControl.cpp
@@ -501,7 +501,7 @@ void RenderTextControl::selectionChanged(bool userTriggered)
 
     if (Frame* frame = document()->frame()) {
         if (frame->selection()->isRange() && userTriggered)
-            node()->dispatchEvent(eventNames().selectEvent, true, false);
+            node()->dispatchEvent(Event::create(eventNames().selectEvent, true, false));
     }
 }
 
diff --git a/WebCore/rendering/RenderTextControlMultiLine.cpp b/WebCore/rendering/RenderTextControlMultiLine.cpp
index 8dfb858..3f0d041 100644
--- a/WebCore/rendering/RenderTextControlMultiLine.cpp
+++ b/WebCore/rendering/RenderTextControlMultiLine.cpp
@@ -22,6 +22,7 @@
 #include "config.h"
 #include "RenderTextControlMultiLine.h"
 
+#include "Event.h"
 #include "EventNames.h"
 #include "Frame.h"
 #include "HTMLNames.h"
@@ -50,8 +51,7 @@ void RenderTextControlMultiLine::subtreeHasChanged()
     if (!node()->focused())
         return;
 
-    // Fire the "input" DOM event
-    node()->dispatchEvent(eventNames().inputEvent, true, false);
+    node()->dispatchEvent(Event::create(eventNames().inputEvent, true, false));
 
     if (Frame* frame = document()->frame())
         frame->textDidChangeInTextArea(static_cast<Element*>(node()));
diff --git a/WebCore/svg/SVGElement.cpp b/WebCore/svg/SVGElement.cpp
index 5c5d609..d455717 100644
--- a/WebCore/svg/SVGElement.cpp
+++ b/WebCore/svg/SVGElement.cpp
@@ -190,18 +190,17 @@ bool SVGElement::haveLoadedRequiredResources()
     return true;
 }
 
-static bool hasLoadListener(SVGElement* node)
+static bool hasLoadListener(Node* node)
 {
-    Node* currentNode = node;
-    while (currentNode && currentNode->isElementNode()) {
-        const RegisteredEventListenerVector& listeners = static_cast<Element*>(currentNode)->eventListeners();
-        size_t size = listeners.size();
-        for (size_t i = 0; i < size; ++i) {
-            const RegisteredEventListener& r = *listeners[i];
-            if (r.eventType() == eventNames().loadEvent && r.useCapture() || currentNode == node)
+    if (node->hasEventListeners(eventNames().loadEvent))
+        return true;
+
+    for (node = node->parentNode(); node && node->isElementNode(); node = node->parentNode()) {
+        const EventListenerVector& entry = node->getEventListeners(eventNames().loadEvent);
+        for (size_t i = 0; i < entry.size(); ++i) {
+            if (entry[i].useCapture)
                 return true;
         }
-        currentNode = currentNode->parentNode();
     }
 
     return false;
diff --git a/WebCore/svg/SVGElementInstance.cpp b/WebCore/svg/SVGElementInstance.cpp
index 3a82067..46e8221 100644
--- a/WebCore/svg/SVGElementInstance.cpp
+++ b/WebCore/svg/SVGElementInstance.cpp
@@ -43,6 +43,13 @@ namespace WebCore {
 static WTF::RefCountedLeakCounter instanceCounter("WebCoreSVGElementInstance");
 #endif
 
+static EventTargetData& dummyEventTargetData()
+{
+    DEFINE_STATIC_LOCAL(EventTargetData, dummyEventTargetData, ());
+    dummyEventTargetData.eventListenerMap.clear();
+    return dummyEventTargetData;
+}
+
 SVGElementInstance::SVGElementInstance(SVGUseElement* useElement, PassRefPtr<SVGElement> originalElement)
     : m_needsUpdate(false)
     , m_useElement(useElement)
@@ -137,438 +144,52 @@ ScriptExecutionContext* SVGElementInstance::scriptExecutionContext() const
     return 0;
 }
 
-void SVGElementInstance::addEventListener(const AtomicString& eventType, PassRefPtr<EventListener> listener, bool useCapture)
-{
-    if (SVGElement* element = correspondingElement())
-        element->addEventListener(eventType, listener, useCapture);
-}
-
-void SVGElementInstance::removeEventListener(const AtomicString& eventType, EventListener* listener, bool useCapture)
-{
-    if (SVGElement* element = correspondingElement())
-        element->removeEventListener(eventType, listener, useCapture);
-}
-
-bool SVGElementInstance::dispatchEvent(PassRefPtr<Event> e, ExceptionCode& ec)
+bool SVGElementInstance::addEventListener(const AtomicString& eventType, PassRefPtr<EventListener> listener, bool useCapture)
 {
-    RefPtr<Event> evt(e);
-    ASSERT(!eventDispatchForbidden());
-    if (!evt || evt->type().isEmpty()) {
-        ec = EventException::UNSPECIFIED_EVENT_TYPE_ERR;
-        return false;
-    }
-
-    // The event has to be dispatched to the shadowTreeElement(), not the correspondingElement()!
-    SVGElement* element = shadowTreeElement();
-    if (!element)
+    if (!correspondingElement())
         return false;
-
-    evt->setTarget(this);
-
-    RefPtr<FrameView> view = element->document()->view();
-    return element->dispatchGenericEvent(evt.release());
-}
-
-EventListener* SVGElementInstance::onabort() const
-{
-    return correspondingElement()->getAttributeEventListener(eventNames().abortEvent);
-}
-
-void SVGElementInstance::setOnabort(PassRefPtr<EventListener> eventListener)
-{
-    correspondingElement()->setAttributeEventListener(eventNames().abortEvent, eventListener);
-}
-
-EventListener* SVGElementInstance::onblur() const
-{
-    return correspondingElement()->getAttributeEventListener(eventNames().blurEvent);
-}
-
-void SVGElementInstance::setOnblur(PassRefPtr<EventListener> eventListener)
-{
-    correspondingElement()->setAttributeEventListener(eventNames().blurEvent, eventListener);
-}
-
-EventListener* SVGElementInstance::onchange() const
-{
-    return correspondingElement()->getAttributeEventListener(eventNames().changeEvent);
-}
-
-void SVGElementInstance::setOnchange(PassRefPtr<EventListener> eventListener)
-{
-    correspondingElement()->setAttributeEventListener(eventNames().changeEvent, eventListener);
-}
-
-EventListener* SVGElementInstance::onclick() const
-{
-    return correspondingElement()->getAttributeEventListener(eventNames().clickEvent);
-}
-
-void SVGElementInstance::setOnclick(PassRefPtr<EventListener> eventListener)
-{
-    correspondingElement()->setAttributeEventListener(eventNames().clickEvent, eventListener);
-}
-
-EventListener* SVGElementInstance::oncontextmenu() const
-{
-    return correspondingElement()->getAttributeEventListener(eventNames().contextmenuEvent);
-}
-
-void SVGElementInstance::setOncontextmenu(PassRefPtr<EventListener> eventListener)
-{
-    correspondingElement()->setAttributeEventListener(eventNames().contextmenuEvent, eventListener);
-}
-
-EventListener* SVGElementInstance::ondblclick() const
-{
-    return correspondingElement()->getAttributeEventListener(eventNames().dblclickEvent);
-}
-
-void SVGElementInstance::setOndblclick(PassRefPtr<EventListener> eventListener)
-{
-    correspondingElement()->setAttributeEventListener(eventNames().dblclickEvent, eventListener);
-}
-
-EventListener* SVGElementInstance::onerror() const
-{
-    return correspondingElement()->getAttributeEventListener(eventNames().errorEvent);
-}
-
-void SVGElementInstance::setOnerror(PassRefPtr<EventListener> eventListener)
-{
-    correspondingElement()->setAttributeEventListener(eventNames().errorEvent, eventListener);
-}
-
-EventListener* SVGElementInstance::onfocus() const
-{
-    return correspondingElement()->getAttributeEventListener(eventNames().focusEvent);
-}
-
-void SVGElementInstance::setOnfocus(PassRefPtr<EventListener> eventListener)
-{
-    correspondingElement()->setAttributeEventListener(eventNames().focusEvent, eventListener);
-}
-
-EventListener* SVGElementInstance::oninput() const
-{
-    return correspondingElement()->getAttributeEventListener(eventNames().inputEvent);
-}
-
-void SVGElementInstance::setOninput(PassRefPtr<EventListener> eventListener)
-{
-    correspondingElement()->setAttributeEventListener(eventNames().inputEvent, eventListener);
-}
-
-EventListener* SVGElementInstance::onkeydown() const
-{
-    return correspondingElement()->getAttributeEventListener(eventNames().keydownEvent);
-}
-
-void SVGElementInstance::setOnkeydown(PassRefPtr<EventListener> eventListener)
-{
-    correspondingElement()->setAttributeEventListener(eventNames().keydownEvent, eventListener);
-}
-
-EventListener* SVGElementInstance::onkeypress() const
-{
-    return correspondingElement()->getAttributeEventListener(eventNames().keypressEvent);
-}
-
-void SVGElementInstance::setOnkeypress(PassRefPtr<EventListener> eventListener)
-{
-    correspondingElement()->setAttributeEventListener(eventNames().keypressEvent, eventListener);
-}
-
-EventListener* SVGElementInstance::onkeyup() const
-{
-    return correspondingElement()->getAttributeEventListener(eventNames().keyupEvent);
-}
-
-void SVGElementInstance::setOnkeyup(PassRefPtr<EventListener> eventListener)
-{
-    correspondingElement()->setAttributeEventListener(eventNames().keyupEvent, eventListener);
-}
-
-EventListener* SVGElementInstance::onload() const
-{
-    return correspondingElement()->getAttributeEventListener(eventNames().loadEvent);
+    return correspondingElement()->addEventListener(eventType, listener, useCapture);
 }
 
-void SVGElementInstance::setOnload(PassRefPtr<EventListener> eventListener)
+bool SVGElementInstance::removeEventListener(const AtomicString& eventType, EventListener* listener, bool useCapture)
 {
-    correspondingElement()->setAttributeEventListener(eventNames().loadEvent, eventListener);
-}
-
-EventListener* SVGElementInstance::onmousedown() const
-{
-    return correspondingElement()->getAttributeEventListener(eventNames().mousedownEvent);
-}
-
-void SVGElementInstance::setOnmousedown(PassRefPtr<EventListener> eventListener)
-{
-    correspondingElement()->setAttributeEventListener(eventNames().mousedownEvent, eventListener);
-}
-
-EventListener* SVGElementInstance::onmousemove() const
-{
-    return correspondingElement()->getAttributeEventListener(eventNames().mousemoveEvent);
-}
-
-void SVGElementInstance::setOnmousemove(PassRefPtr<EventListener> eventListener)
-{
-    correspondingElement()->setAttributeEventListener(eventNames().mousemoveEvent, eventListener);
-}
-
-EventListener* SVGElementInstance::onmouseout() const
-{
-    return correspondingElement()->getAttributeEventListener(eventNames().mouseoutEvent);
-}
-
-void SVGElementInstance::setOnmouseout(PassRefPtr<EventListener> eventListener)
-{
-    correspondingElement()->setAttributeEventListener(eventNames().mouseoutEvent, eventListener);
-}
-
-EventListener* SVGElementInstance::onmouseover() const
-{
-    return correspondingElement()->getAttributeEventListener(eventNames().mouseoverEvent);
-}
-
-void SVGElementInstance::setOnmouseover(PassRefPtr<EventListener> eventListener)
-{
-    correspondingElement()->setAttributeEventListener(eventNames().mouseoverEvent, eventListener);
-}
-
-EventListener* SVGElementInstance::onmouseup() const
-{
-    return correspondingElement()->getAttributeEventListener(eventNames().mouseupEvent);
-}
-
-void SVGElementInstance::setOnmouseup(PassRefPtr<EventListener> eventListener)
-{
-    correspondingElement()->setAttributeEventListener(eventNames().mouseupEvent, eventListener);
-}
-
-EventListener* SVGElementInstance::onmousewheel() const
-{
-    return correspondingElement()->getAttributeEventListener(eventNames().mousewheelEvent);
-}
-
-void SVGElementInstance::setOnmousewheel(PassRefPtr<EventListener> eventListener)
-{
-    correspondingElement()->setAttributeEventListener(eventNames().mousewheelEvent, eventListener);
-}
-
-EventListener* SVGElementInstance::onbeforecut() const
-{
-    return correspondingElement()->getAttributeEventListener(eventNames().beforecutEvent);
-}
-
-void SVGElementInstance::setOnbeforecut(PassRefPtr<EventListener> eventListener)
-{
-    correspondingElement()->setAttributeEventListener(eventNames().beforecutEvent, eventListener);
-}
-
-EventListener* SVGElementInstance::oncut() const
-{
-    return correspondingElement()->getAttributeEventListener(eventNames().cutEvent);
-}
-
-void SVGElementInstance::setOncut(PassRefPtr<EventListener> eventListener)
-{
-    correspondingElement()->setAttributeEventListener(eventNames().cutEvent, eventListener);
-}
-
-EventListener* SVGElementInstance::onbeforecopy() const
-{
-    return correspondingElement()->getAttributeEventListener(eventNames().beforecopyEvent);
-}
-
-void SVGElementInstance::setOnbeforecopy(PassRefPtr<EventListener> eventListener)
-{
-    correspondingElement()->setAttributeEventListener(eventNames().beforecopyEvent, eventListener);
-}
-
-EventListener* SVGElementInstance::oncopy() const
-{
-    return correspondingElement()->getAttributeEventListener(eventNames().copyEvent);
-}
-
-void SVGElementInstance::setOncopy(PassRefPtr<EventListener> eventListener)
-{
-    correspondingElement()->setAttributeEventListener(eventNames().copyEvent, eventListener);
-}
-
-EventListener* SVGElementInstance::onbeforepaste() const
-{
-    return correspondingElement()->getAttributeEventListener(eventNames().beforepasteEvent);
-}
-
-void SVGElementInstance::setOnbeforepaste(PassRefPtr<EventListener> eventListener)
-{
-    correspondingElement()->setAttributeEventListener(eventNames().beforepasteEvent, eventListener);
-}
-
-EventListener* SVGElementInstance::onpaste() const
-{
-    return correspondingElement()->getAttributeEventListener(eventNames().pasteEvent);
-}
-
-void SVGElementInstance::setOnpaste(PassRefPtr<EventListener> eventListener)
-{
-    correspondingElement()->setAttributeEventListener(eventNames().pasteEvent, eventListener);
-}
-
-EventListener* SVGElementInstance::ondragenter() const
-{
-    return correspondingElement()->getAttributeEventListener(eventNames().dragenterEvent);
-}
-
-void SVGElementInstance::setOndragenter(PassRefPtr<EventListener> eventListener)
-{
-    correspondingElement()->setAttributeEventListener(eventNames().dragenterEvent, eventListener);
-}
-
-EventListener* SVGElementInstance::ondragover() const
-{
-    return correspondingElement()->getAttributeEventListener(eventNames().dragoverEvent);
-}
-
-void SVGElementInstance::setOndragover(PassRefPtr<EventListener> eventListener)
-{
-    correspondingElement()->setAttributeEventListener(eventNames().dragoverEvent, eventListener);
-}
-
-EventListener* SVGElementInstance::ondragleave() const
-{
-    return correspondingElement()->getAttributeEventListener(eventNames().dragleaveEvent);
-}
-
-void SVGElementInstance::setOndragleave(PassRefPtr<EventListener> eventListener)
-{
-    correspondingElement()->setAttributeEventListener(eventNames().dragleaveEvent, eventListener);
-}
-
-EventListener* SVGElementInstance::ondrop() const
-{
-    return correspondingElement()->getAttributeEventListener(eventNames().dropEvent);
-}
-
-void SVGElementInstance::setOndrop(PassRefPtr<EventListener> eventListener)
-{
-    correspondingElement()->setAttributeEventListener(eventNames().dropEvent, eventListener);
-}
-
-EventListener* SVGElementInstance::ondragstart() const
-{
-    return correspondingElement()->getAttributeEventListener(eventNames().dragstartEvent);
-}
-
-void SVGElementInstance::setOndragstart(PassRefPtr<EventListener> eventListener)
-{
-    correspondingElement()->setAttributeEventListener(eventNames().dragstartEvent, eventListener);
-}
-
-EventListener* SVGElementInstance::ondrag() const
-{
-    return correspondingElement()->getAttributeEventListener(eventNames().dragEvent);
-}
-
-void SVGElementInstance::setOndrag(PassRefPtr<EventListener> eventListener)
-{
-    correspondingElement()->setAttributeEventListener(eventNames().dragEvent, eventListener);
-}
-
-EventListener* SVGElementInstance::ondragend() const
-{
-    return correspondingElement()->getAttributeEventListener(eventNames().dragendEvent);
-}
-
-void SVGElementInstance::setOndragend(PassRefPtr<EventListener> eventListener)
-{
-    correspondingElement()->setAttributeEventListener(eventNames().dragendEvent, eventListener);
-}
-
-EventListener* SVGElementInstance::onreset() const
-{
-    return correspondingElement()->getAttributeEventListener(eventNames().resetEvent);
-}
-
-void SVGElementInstance::setOnreset(PassRefPtr<EventListener> eventListener)
-{
-    correspondingElement()->setAttributeEventListener(eventNames().resetEvent, eventListener);
-}
-
-EventListener* SVGElementInstance::onresize() const
-{
-    return correspondingElement()->getAttributeEventListener(eventNames().resizeEvent);
-}
-
-void SVGElementInstance::setOnresize(PassRefPtr<EventListener> eventListener)
-{
-    correspondingElement()->setAttributeEventListener(eventNames().resizeEvent, eventListener);
-}
-
-EventListener* SVGElementInstance::onscroll() const
-{
-    return correspondingElement()->getAttributeEventListener(eventNames().scrollEvent);
-}
-
-void SVGElementInstance::setOnscroll(PassRefPtr<EventListener> eventListener)
-{
-    correspondingElement()->setAttributeEventListener(eventNames().scrollEvent, eventListener);
-}
-
-EventListener* SVGElementInstance::onsearch() const
-{
-    return correspondingElement()->getAttributeEventListener(eventNames().searchEvent);
-}
-
-void SVGElementInstance::setOnsearch(PassRefPtr<EventListener> eventListener)
-{
-    correspondingElement()->setAttributeEventListener(eventNames().searchEvent, eventListener);
-}
-
-EventListener* SVGElementInstance::onselect() const
-{
-    return correspondingElement()->getAttributeEventListener(eventNames().selectEvent);
+    if (!correspondingElement())
+        return false;
+    return correspondingElement()->removeEventListener(eventType, listener, useCapture);
 }
 
-void SVGElementInstance::setOnselect(PassRefPtr<EventListener> eventListener)
+void SVGElementInstance::removeAllEventListeners()
 {
-    correspondingElement()->setAttributeEventListener(eventNames().selectEvent, eventListener);
+    if (!correspondingElement())
+        return;
+    correspondingElement()->removeAllEventListeners();
 }
 
-EventListener* SVGElementInstance::onselectstart() const
+bool SVGElementInstance::dispatchEvent(PassRefPtr<Event> prpEvent)
 {
-    return correspondingElement()->getAttributeEventListener(eventNames().selectstartEvent);
-}
+    RefPtr<EventTarget> protect = this;
+    RefPtr<Event> event = prpEvent;
 
-void SVGElementInstance::setOnselectstart(PassRefPtr<EventListener> eventListener)
-{
-    correspondingElement()->setAttributeEventListener(eventNames().selectstartEvent, eventListener);
-}
+    event->setTarget(this);
 
-EventListener* SVGElementInstance::onsubmit() const
-{
-    return correspondingElement()->getAttributeEventListener(eventNames().submitEvent);
-}
+    SVGElement* element = shadowTreeElement();
+    if (!element)
+        return false;
 
-void SVGElementInstance::setOnsubmit(PassRefPtr<EventListener> eventListener)
-{
-    correspondingElement()->setAttributeEventListener(eventNames().submitEvent, eventListener);
+    RefPtr<FrameView> view = element->document()->view();
+    return element->dispatchGenericEvent(event.release());
 }
 
-EventListener* SVGElementInstance::onunload() const
+EventTargetData* SVGElementInstance::eventTargetData()
 {
-    return correspondingElement()->getAttributeEventListener(eventNames().unloadEvent);
+    return correspondingElement() ? correspondingElement()->eventTargetData() : 0;
 }
 
-void SVGElementInstance::setOnunload(PassRefPtr<EventListener> eventListener)
+EventTargetData* SVGElementInstance::ensureEventTargetData()
 {
-    correspondingElement()->setAttributeEventListener(eventNames().unloadEvent, eventListener);
+    return &dummyEventTargetData(); // return something, so we don't crash
 }
 
-}
+} // namespace WebCore
 
 #endif // ENABLE(SVG)
diff --git a/WebCore/svg/SVGElementInstance.h b/WebCore/svg/SVGElementInstance.h
index 048c66c..3cdc761 100644
--- a/WebCore/svg/SVGElementInstance.h
+++ b/WebCore/svg/SVGElementInstance.h
@@ -51,10 +51,11 @@ namespace WebCore {
 
         virtual ScriptExecutionContext* scriptExecutionContext() const;
 
-        virtual void addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture);
-        virtual void removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture);
-        virtual bool dispatchEvent(PassRefPtr<Event>, ExceptionCode&);
-        const RegisteredEventListenerVector& eventListeners() const { return correspondingElement()->eventListeners(); }
+        virtual bool addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture);
+        virtual bool removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture);
+        virtual void removeAllEventListeners();
+        using EventTarget::dispatchEvent;
+        virtual bool dispatchEvent(PassRefPtr<Event>);
 
         SVGElement* correspondingElement() const { return m_element.get(); }
         SVGUseElement* correspondingUseElement() const { return m_useElement; }
@@ -77,86 +78,46 @@ namespace WebCore {
         using TreeShared<SVGElementInstance>::deref;
 
         // EventTarget API
-        EventListener* onabort() const;
-        void setOnabort(PassRefPtr<EventListener>);
-        EventListener* onblur() const;
-        void setOnblur(PassRefPtr<EventListener>);
-        EventListener* onchange() const;
-        void setOnchange(PassRefPtr<EventListener>);
-        EventListener* onclick() const;
-        void setOnclick(PassRefPtr<EventListener>);
-        EventListener* oncontextmenu() const;
-        void setOncontextmenu(PassRefPtr<EventListener>);
-        EventListener* ondblclick() const;
-        void setOndblclick(PassRefPtr<EventListener>);
-        EventListener* onerror() const;
-        void setOnerror(PassRefPtr<EventListener>);
-        EventListener* onfocus() const;
-        void setOnfocus(PassRefPtr<EventListener>);
-        EventListener* oninput() const;
-        void setOninput(PassRefPtr<EventListener>);
-        EventListener* onkeydown() const;
-        void setOnkeydown(PassRefPtr<EventListener>);
-        EventListener* onkeypress() const;
-        void setOnkeypress(PassRefPtr<EventListener>);
-        EventListener* onkeyup() const;
-        void setOnkeyup(PassRefPtr<EventListener>);
-        EventListener* onload() const;
-        void setOnload(PassRefPtr<EventListener>);
-        EventListener* onmousedown() const;
-        void setOnmousedown(PassRefPtr<EventListener>);
-        EventListener* onmousemove() const;
-        void setOnmousemove(PassRefPtr<EventListener>);
-        EventListener* onmouseout() const;
-        void setOnmouseout(PassRefPtr<EventListener>);
-        EventListener* onmouseover() const;
-        void setOnmouseover(PassRefPtr<EventListener>);
-        EventListener* onmouseup() const;
-        void setOnmouseup(PassRefPtr<EventListener>);
-        EventListener* onmousewheel() const;
-        void setOnmousewheel(PassRefPtr<EventListener>);
-        EventListener* onbeforecut() const;
-        void setOnbeforecut(PassRefPtr<EventListener>);
-        EventListener* oncut() const;
-        void setOncut(PassRefPtr<EventListener>);
-        EventListener* onbeforecopy() const;
-        void setOnbeforecopy(PassRefPtr<EventListener>);
-        EventListener* oncopy() const;
-        void setOncopy(PassRefPtr<EventListener>);
-        EventListener* onbeforepaste() const;
-        void setOnbeforepaste(PassRefPtr<EventListener>);
-        EventListener* onpaste() const;
-        void setOnpaste(PassRefPtr<EventListener>);
-        EventListener* ondragenter() const;
-        void setOndragenter(PassRefPtr<EventListener>);
-        EventListener* ondragover() const;
-        void setOndragover(PassRefPtr<EventListener>);
-        EventListener* ondragleave() const;
-        void setOndragleave(PassRefPtr<EventListener>);
-        EventListener* ondrop() const;
-        void setOndrop(PassRefPtr<EventListener>);
-        EventListener* ondragstart() const;
-        void setOndragstart(PassRefPtr<EventListener>);
-        EventListener* ondrag() const;
-        void setOndrag(PassRefPtr<EventListener>);
-        EventListener* ondragend() const;
-        void setOndragend(PassRefPtr<EventListener>);
-        EventListener* onreset() const;
-        void setOnreset(PassRefPtr<EventListener>);
-        EventListener* onresize() const;
-        void setOnresize(PassRefPtr<EventListener>);
-        EventListener* onscroll() const;
-        void setOnscroll(PassRefPtr<EventListener>);
-        EventListener* onsearch() const;
-        void setOnsearch(PassRefPtr<EventListener>);
-        EventListener* onselect() const;
-        void setOnselect(PassRefPtr<EventListener>);
-        EventListener* onselectstart() const;
-        void setOnselectstart(PassRefPtr<EventListener>);
-        EventListener* onsubmit() const;
-        void setOnsubmit(PassRefPtr<EventListener>);
-        EventListener* onunload() const;
-        void setOnunload(PassRefPtr<EventListener>);
+        DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), abort);
+        DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), blur);
+        DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), change);
+        DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), click);
+        DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), contextmenu);
+        DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), dblclick);
+        DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), error);
+        DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), focus);
+        DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), input);
+        DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), keydown);
+        DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), keypress);
+        DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), keyup);
+        DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), load);
+        DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), mousedown);
+        DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), mousemove);
+        DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), mouseout);
+        DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), mouseover);
+        DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), mouseup);
+        DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), mousewheel);
+        DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), beforecut);
+        DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), cut);
+        DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), beforecopy);
+        DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), copy);
+        DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), beforepaste);
+        DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), paste);
+        DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), dragenter);
+        DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), dragover);
+        DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), dragleave);
+        DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), drop);
+        DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), dragstart);
+        DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), drag);
+        DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), dragend);
+        DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), reset);
+        DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), resize);
+        DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), scroll);
+        DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), search);
+        DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), select);
+        DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), selectstart);
+        DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), submit);
+        DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), unload);
 
     private:
         friend class SVGUseElement;
@@ -189,6 +150,8 @@ namespace WebCore {
 
         virtual void refEventTarget() { ref(); }
         virtual void derefEventTarget() { deref(); }
+        virtual EventTargetData* eventTargetData();
+        virtual EventTargetData* ensureEventTargetData();
 
         bool m_needsUpdate : 1;
 
diff --git a/WebCore/svg/SVGImageLoader.cpp b/WebCore/svg/SVGImageLoader.cpp
index f8380f5..5d5d3bc 100644
--- a/WebCore/svg/SVGImageLoader.cpp
+++ b/WebCore/svg/SVGImageLoader.cpp
@@ -25,6 +25,7 @@
 #if ENABLE(SVG)
 #include "SVGImageLoader.h"
 
+#include "Event.h"
 #include "EventNames.h"
 #include "SVGImageElement.h"
 #include "RenderImage.h"
@@ -43,7 +44,7 @@ SVGImageLoader::~SVGImageLoader()
 void SVGImageLoader::dispatchLoadEvent()
 {
     if (image()->errorOccurred())
-        element()->dispatchEvent(eventNames().errorEvent, false, false);
+        element()->dispatchEvent(Event::create(eventNames().errorEvent, false, false));
     else {
         SVGImageElement* imageElement = static_cast<SVGImageElement*>(element());
         if (imageElement->externalResourcesRequiredBaseValue())
diff --git a/WebCore/svg/SVGScriptElement.cpp b/WebCore/svg/SVGScriptElement.cpp
index 2ecf912..587542c 100644
--- a/WebCore/svg/SVGScriptElement.cpp
+++ b/WebCore/svg/SVGScriptElement.cpp
@@ -26,6 +26,7 @@
 #include "SVGScriptElement.h"
 
 #include "Document.h"
+#include "Event.h"
 #include "EventNames.h"
 #include "MappedAttribute.h"
 #include "SVGNames.h"
@@ -209,7 +210,7 @@ void SVGScriptElement::dispatchLoadEvent()
 
 void SVGScriptElement::dispatchErrorEvent()
 {
-    dispatchEvent(eventNames().errorEvent, true, false);
+    dispatchEvent(Event::create(eventNames().errorEvent, true, false));
 }
 
 }
diff --git a/WebCore/svg/SVGUseElement.cpp b/WebCore/svg/SVGUseElement.cpp
index 9cb3024..4b66e03 100644
--- a/WebCore/svg/SVGUseElement.cpp
+++ b/WebCore/svg/SVGUseElement.cpp
@@ -768,18 +768,18 @@ void SVGUseElement::transferEventListenersToShadowTree(SVGElementInstance* targe
     ASSERT(originalElement);
 
     if (SVGElement* shadowTreeElement = target->shadowTreeElement()) {
-        const RegisteredEventListenerVector& listeners = originalElement->eventListeners();
-        size_t size = listeners.size();
-        for (size_t i = 0; i < size; ++i) {
-            const RegisteredEventListener& r = *listeners[i];
-            EventListener* listener = r.listener();
-            ASSERT(listener);
-
-            // Event listeners created from markup have already been transfered to the shadow tree during cloning!
-            if (listener->wasCreatedFromMarkup())
-                continue;
-
-            shadowTreeElement->addEventListener(r.eventType(), listener, r.useCapture());
+        if (EventTargetData* d = originalElement->eventTargetData()) {
+            EventListenerMap& map = d->eventListenerMap;
+            EventListenerMap::iterator end = map.end();
+            for (EventListenerMap::iterator it = map.begin(); it != end; ++it) {
+                EventListenerVector& entry = it->second;
+                for (size_t i = 0; i < entry.size(); ++i) {
+                    // Event listeners created from markup have already been transfered to the shadow tree during cloning.
+                    if (entry[i].listener->wasCreatedFromMarkup())
+                        continue;
+                    shadowTreeElement->addEventListener(it->first, entry[i].listener, entry[i].useCapture);
+                }
+            }
         }
     }
 
diff --git a/WebCore/svg/animation/SVGSMILElement.cpp b/WebCore/svg/animation/SVGSMILElement.cpp
index 982afd5..8ec9435 100644
--- a/WebCore/svg/animation/SVGSMILElement.cpp
+++ b/WebCore/svg/animation/SVGSMILElement.cpp
@@ -87,7 +87,7 @@ private:
         m_eventBase->addEventListener(m_condition->m_name, this, false);
     }
 
-    virtual void handleEvent(Event*, bool);
+    virtual void handleEvent(Event*);
 
     SVGSMILElement* m_animation;
     SVGSMILElement::Condition* m_condition;
@@ -103,7 +103,7 @@ bool ConditionEventListener::operator==(const EventListener& listener)
     return false;
 }
 
-void ConditionEventListener::handleEvent(Event* event, bool) 
+void ConditionEventListener::handleEvent(Event* event) 
 {
     m_animation->handleConditionEvent(event, m_condition);
 }
diff --git a/WebCore/websockets/WebSocket.cpp b/WebCore/websockets/WebSocket.cpp
index 8f90b1c..dd89c14 100644
--- a/WebCore/websockets/WebSocket.cpp
+++ b/WebCore/websockets/WebSocket.cpp
@@ -52,23 +52,23 @@ namespace WebCore {
 class ProcessWebSocketEventTask : public ScriptExecutionContext::Task {
 public:
     typedef void (WebSocket::*Method)(Event*);
-    static PassRefPtr<ProcessWebSocketEventTask> create(PassRefPtr<WebSocket> webSocket, Method method, PassRefPtr<Event> event)
+    static PassRefPtr<ProcessWebSocketEventTask> create(PassRefPtr<WebSocket> webSocket, PassRefPtr<Event> event)
     {
-        return adoptRef(new ProcessWebSocketEventTask(webSocket, method, event));
+        return adoptRef(new ProcessWebSocketEventTask(webSocket, event));
     }
     virtual void performTask(ScriptExecutionContext*)
     {
-        (m_webSocket.get()->*m_method)(m_event.get());
+        ExceptionCode ec = 0;
+        m_webSocket->dispatchEvent(m_event.get(), ec);
+        ASSERT(!ec);
     }
 
   private:
-    ProcessWebSocketEventTask(PassRefPtr<WebSocket> webSocket, Method method, PassRefPtr<Event> event)
+    ProcessWebSocketEventTask(PassRefPtr<WebSocket> webSocket, PassRefPtr<Event> event)
         : m_webSocket(webSocket)
-        , m_method(method)
         , m_event(event) { }
 
     RefPtr<WebSocket> m_webSocket;
-    Method m_method;
     RefPtr<Event> m_event;
 };
 
@@ -171,54 +171,6 @@ ScriptExecutionContext* WebSocket::scriptExecutionContext() const
     return ActiveDOMObject::scriptExecutionContext();
 }
 
-void WebSocket::addEventListener(const AtomicString& eventType, PassRefPtr<EventListener> eventListener, bool)
-{
-    EventListenersMap::iterator iter = m_eventListeners.find(eventType);
-    if (iter == m_eventListeners.end()) {
-        ListenerVector listeners;
-        listeners.append(eventListener);
-        m_eventListeners.add(eventType, listeners);
-    } else {
-        ListenerVector& listeners = iter->second;
-        for (ListenerVector::iterator listenerIter = listeners.begin(); listenerIter != listeners.end(); ++listenerIter)
-            if (*listenerIter == eventListener)
-                return;
-
-        listeners.append(eventListener);
-        m_eventListeners.add(eventType, listeners);
-    }
-}
-
-void WebSocket::removeEventListener(const AtomicString& eventType, EventListener* eventListener, bool)
-{
-    EventListenersMap::iterator iter = m_eventListeners.find(eventType);
-    if (iter == m_eventListeners.end())
-        return;
-
-    ListenerVector& listeners = iter->second;
-    for (ListenerVector::const_iterator listenerIter = listeners.begin(); listenerIter != listeners.end(); ++listenerIter)
-        if (*listenerIter == eventListener) {
-            listeners.remove(listenerIter - listeners.begin());
-            return;
-        }
-}
-
-bool WebSocket::dispatchEvent(PassRefPtr<Event> evt, ExceptionCode& ec)
-{
-    if (!evt || evt->type().isEmpty()) {
-        ec = EventException::UNSPECIFIED_EVENT_TYPE_ERR;
-        return true;
-    }
-
-    ListenerVector listenersCopy = m_eventListeners.get(evt->type());
-    for (ListenerVector::const_iterator listenerIter = listenersCopy.begin(); listenerIter != listenersCopy.end(); ++listenerIter) {
-        evt->setTarget(this);
-        evt->setCurrentTarget(this);
-        listenerIter->get()->handleEvent(evt.get(), false);
-    }
-    return !evt->defaultPrevented();
-}
-
 void WebSocket::didConnect()
 {
     LOG(Network, "WebSocket %p didConnect", this);
@@ -227,7 +179,7 @@ void WebSocket::didConnect()
         return;
     }
     m_state = OPEN;
-    scriptExecutionContext()->postTask(ProcessWebSocketEventTask::create(this, &WebSocket::dispatchOpenEvent, Event::create(eventNames().openEvent, false, false)));
+    scriptExecutionContext()->postTask(ProcessWebSocketEventTask::create(this, Event::create(eventNames().openEvent, false, false)));
 }
 
 void WebSocket::didReceiveMessage(const String& msg)
@@ -238,53 +190,24 @@ void WebSocket::didReceiveMessage(const String& msg)
     RefPtr<MessageEvent> evt = MessageEvent::create();
     // FIXME: origin, lastEventId, source, messagePort.
     evt->initMessageEvent(eventNames().messageEvent, false, false, msg, "", "", 0, 0);
-    scriptExecutionContext()->postTask(ProcessWebSocketEventTask::create(this, &WebSocket::dispatchMessageEvent, evt));
+    scriptExecutionContext()->postTask(ProcessWebSocketEventTask::create(this, evt));
 }
 
 void WebSocket::didClose()
 {
     LOG(Network, "WebSocket %p didClose", this);
     m_state = CLOSED;
-    scriptExecutionContext()->postTask(ProcessWebSocketEventTask::create(this, &WebSocket::dispatchCloseEvent, Event::create(eventNames().closeEvent, false, false)));
+    scriptExecutionContext()->postTask(ProcessWebSocketEventTask::create(this, Event::create(eventNames().closeEvent, false, false)));
 }
 
-void WebSocket::dispatchOpenEvent(Event* evt)
+EventTargetData* WebSocket::eventTargetData()
 {
-    if (m_onopen) {
-        evt->setTarget(this);
-        evt->setCurrentTarget(this);
-        m_onopen->handleEvent(evt, false);
-    }
-
-    ExceptionCode ec = 0;
-    dispatchEvent(evt, ec);
-    ASSERT(!ec);
+    return &m_eventTargetData;
 }
 
-void WebSocket::dispatchMessageEvent(Event* evt)
+EventTargetData* WebSocket::ensureEventTargetData()
 {
-    if (m_onmessage) {
-        evt->setTarget(this);
-        evt->setCurrentTarget(this);
-        m_onmessage->handleEvent(evt, false);
-    }
-
-    ExceptionCode ec = 0;
-    dispatchEvent(evt, ec);
-    ASSERT(!ec);
-}
-
-void WebSocket::dispatchCloseEvent(Event* evt)
-{
-    if (m_onclose) {
-        evt->setTarget(this);
-        evt->setCurrentTarget(this);
-        m_onclose->handleEvent(evt, false);
-    }
-
-    ExceptionCode ec = 0;
-    dispatchEvent(evt, ec);
-    ASSERT(!ec);
+    return &m_eventTargetData;
 }
 
 }  // namespace WebCore
diff --git a/WebCore/websockets/WebSocket.h b/WebCore/websockets/WebSocket.h
index 2be3445..c5b7ee7 100644
--- a/WebCore/websockets/WebSocket.h
+++ b/WebCore/websockets/WebSocket.h
@@ -36,6 +36,7 @@
 #include "ActiveDOMObject.h"
 #include "AtomicStringHash.h"
 #include "EventListener.h"
+#include "EventNames.h"
 #include "EventTarget.h"
 #include "KURL.h"
 #include "WebSocketChannelClient.h"
@@ -69,26 +70,15 @@ namespace WebCore {
         State readyState() const;
         unsigned long bufferedAmount() const;
 
-        void setOnopen(PassRefPtr<EventListener> eventListener) { m_onopen = eventListener; }
-        EventListener* onopen() const { return m_onopen.get(); }
-        void setOnmessage(PassRefPtr<EventListener> eventListener) { m_onmessage = eventListener; }
-        EventListener* onmessage() const { return m_onmessage.get(); }
-        void setOnclose(PassRefPtr<EventListener> eventListener) { m_onclose = eventListener; }
-        EventListener* onclose() const { return m_onclose.get(); }
+        DEFINE_ATTRIBUTE_EVENT_LISTENER(open);
+        DEFINE_ATTRIBUTE_EVENT_LISTENER(message);
+        DEFINE_ATTRIBUTE_EVENT_LISTENER(close);
 
         // EventTarget
         virtual WebSocket* toWebSocket() { return this; }
 
         virtual ScriptExecutionContext* scriptExecutionContext() const;
 
-        typedef Vector<RefPtr<EventListener> > ListenerVector;
-        typedef HashMap<AtomicString, ListenerVector> EventListenersMap;
-
-        virtual void addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture);
-        virtual void removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture);
-        virtual bool dispatchEvent(PassRefPtr<Event>, ExceptionCode&);
-        EventListenersMap& eventListeners() { return m_eventListeners; }
-
         // ActiveDOMObject
         //  virtual bool hasPendingActivity() const;
         // virtual void contextDestroyed();
@@ -110,6 +100,8 @@ namespace WebCore {
 
         virtual void refEventTarget() { ref(); }
         virtual void derefEventTarget() { deref(); }
+        virtual EventTargetData* eventTargetData();
+        virtual EventTargetData* ensureEventTargetData();
 
         void dispatchOpenEvent(Event*);
         void dispatchMessageEvent(Event*);
@@ -117,14 +109,10 @@ namespace WebCore {
 
         RefPtr<WebSocketChannel> m_channel;
 
-        RefPtr<EventListener> m_onopen;
-        RefPtr<EventListener> m_onmessage;
-        RefPtr<EventListener> m_onclose;
-        EventListenersMap m_eventListeners;
-
         State m_state;
         KURL m_url;
         String m_protocol;
+        EventTargetData m_eventTargetData;
     };
 
 }  // namespace WebCore
diff --git a/WebCore/websockets/WebSocket.idl b/WebCore/websockets/WebSocket.idl
index cdb916f..04606fe 100644
--- a/WebCore/websockets/WebSocket.idl
+++ b/WebCore/websockets/WebSocket.idl
@@ -31,9 +31,9 @@
 module websockets {
 
     interface [
-        CustomMarkFunction,
-        NoStaticTables,
-        Conditional=WEB_SOCKETS
+        Conditional=WEB_SOCKETS,
+        EventTarget,
+        NoStaticTables
     ] WebSocket {
         readonly attribute DOMString URL;
 
diff --git a/WebCore/workers/AbstractWorker.cpp b/WebCore/workers/AbstractWorker.cpp
index d28b011..6ba8922 100644
--- a/WebCore/workers/AbstractWorker.cpp
+++ b/WebCore/workers/AbstractWorker.cpp
@@ -52,90 +52,6 @@ AbstractWorker::~AbstractWorker()
 {
 }
 
-void AbstractWorker::addEventListener(const AtomicString& eventType, PassRefPtr<EventListener> eventListener, bool)
-{
-    EventListenersMap::iterator iter = m_eventListeners.find(eventType);
-    if (iter == m_eventListeners.end()) {
-        ListenerVector listeners;
-        listeners.append(eventListener);
-        m_eventListeners.add(eventType, listeners);
-    } else {
-        ListenerVector& listeners = iter->second;
-        for (ListenerVector::iterator listenerIter = listeners.begin(); listenerIter != listeners.end(); ++listenerIter) {
-            if (**listenerIter == *eventListener)
-                return;
-        }
-
-        listeners.append(eventListener);
-        m_eventListeners.add(eventType, listeners);
-    }
-}
-
-void AbstractWorker::removeEventListener(const AtomicString& eventType, EventListener* eventListener, bool)
-{
-    EventListenersMap::iterator iter = m_eventListeners.find(eventType);
-    if (iter == m_eventListeners.end())
-        return;
-
-    ListenerVector& listeners = iter->second;
-    for (ListenerVector::const_iterator listenerIter = listeners.begin(); listenerIter != listeners.end(); ++listenerIter) {
-        if (**listenerIter == *eventListener) {
-            listeners.remove(listenerIter - listeners.begin());
-            return;
-        }
-    }
-}
-
-bool AbstractWorker::dispatchEvent(PassRefPtr<Event> event, ExceptionCode& ec)
-{
-    if (!event || event->type().isEmpty()) {
-        ec = EventException::UNSPECIFIED_EVENT_TYPE_ERR;
-        return true;
-    }
-
-    ListenerVector listenersCopy = m_eventListeners.get(event->type());
-    for (ListenerVector::const_iterator listenerIter = listenersCopy.begin(); listenerIter != listenersCopy.end(); ++listenerIter) {
-        event->setTarget(this);
-        event->setCurrentTarget(this);
-        listenerIter->get()->handleEvent(event.get(), false);
-    }
-
-    return !event->defaultPrevented();
-}
-
-void AbstractWorker::dispatchLoadErrorEvent()
-{
-    RefPtr<Event> evt = Event::create(eventNames().errorEvent, false, true);
-    if (m_onErrorListener) {
-        evt->setTarget(this);
-        evt->setCurrentTarget(this);
-        m_onErrorListener->handleEvent(evt.get(), true);
-    }
-
-    ExceptionCode ec = 0;
-    dispatchEvent(evt.release(), ec);
-    ASSERT(!ec);
-}
-
-bool AbstractWorker::dispatchScriptErrorEvent(const String& message, const String& sourceURL, int lineNumber)
-{
-    bool handled = false;
-    RefPtr<ErrorEvent> event = ErrorEvent::create(message, sourceURL, static_cast<unsigned>(lineNumber));
-    if (m_onErrorListener) {
-        event->setTarget(this);
-        event->setCurrentTarget(this);
-        m_onErrorListener->handleEvent(event.get(), true);
-        if (event->defaultPrevented())
-            handled = true;
-    }
-
-    ExceptionCode ec = 0;
-    handled = !dispatchEvent(event.release(), ec);
-    ASSERT(!ec);
-
-    return handled;
-}
-
 KURL AbstractWorker::resolveURL(const String& url, ExceptionCode& ec)
 {
     if (url.isEmpty()) {
@@ -157,6 +73,16 @@ KURL AbstractWorker::resolveURL(const String& url, ExceptionCode& ec)
     return scriptURL;
 }
 
+EventTargetData* AbstractWorker::eventTargetData()
+{
+    return &m_eventTargetData;
+}
+
+EventTargetData* AbstractWorker::ensureEventTargetData()
+{
+    return &m_eventTargetData;
+}
+
 } // namespace WebCore
 
 #endif // ENABLE(WORKERS)
diff --git a/WebCore/workers/AbstractWorker.h b/WebCore/workers/AbstractWorker.h
index a882542..2209856 100644
--- a/WebCore/workers/AbstractWorker.h
+++ b/WebCore/workers/AbstractWorker.h
@@ -36,6 +36,7 @@
 #include "ActiveDOMObject.h"
 #include "AtomicStringHash.h"
 #include "EventListener.h"
+#include "EventNames.h"
 #include "EventTarget.h"
 #include <wtf/PassRefPtr.h>
 #include <wtf/RefCounted.h>
@@ -51,19 +52,7 @@ namespace WebCore {
         // EventTarget APIs
         virtual ScriptExecutionContext* scriptExecutionContext() const { return ActiveDOMObject::scriptExecutionContext(); }
 
-        virtual void addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture);
-        virtual void removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture);
-        virtual bool dispatchEvent(PassRefPtr<Event>, ExceptionCode&);
-
-        // Utility routines to generate appropriate error events for loading and script exceptions.
-        void dispatchLoadErrorEvent();
-        bool dispatchScriptErrorEvent(const String& errorMessage, const String& sourceURL, int);
-
-        void setOnerror(PassRefPtr<EventListener> eventListener) { m_onErrorListener = eventListener; }
-        EventListener* onerror() const { return m_onErrorListener.get(); }
-        typedef Vector<RefPtr<EventListener> > ListenerVector;
-        typedef HashMap<AtomicString, ListenerVector> EventListenersMap;
-        EventListenersMap& eventListeners() { return m_eventListeners; }
+        DEFINE_ATTRIBUTE_EVENT_LISTENER(error);
 
         using RefCounted<AbstractWorker>::ref;
         using RefCounted<AbstractWorker>::deref;
@@ -78,9 +67,10 @@ namespace WebCore {
     private:
         virtual void refEventTarget() { ref(); }
         virtual void derefEventTarget() { deref(); }
-
-        RefPtr<EventListener> m_onErrorListener;
-        EventListenersMap m_eventListeners;
+        virtual EventTargetData* eventTargetData();
+        virtual EventTargetData* ensureEventTargetData();
+        
+        EventTargetData m_eventTargetData;
     };
 
 } // namespace WebCore
diff --git a/WebCore/workers/AbstractWorker.idl b/WebCore/workers/AbstractWorker.idl
index ae7ebc6..00b8fbb 100644
--- a/WebCore/workers/AbstractWorker.idl
+++ b/WebCore/workers/AbstractWorker.idl
@@ -32,8 +32,8 @@ module threads {
 
     interface [
         Conditional=WORKERS,
-        CustomMarkFunction,
         CustomToJS,
+        EventTarget,
         GenerateConstructor
     ] AbstractWorker {
 
diff --git a/WebCore/workers/DedicatedWorkerContext.cpp b/WebCore/workers/DedicatedWorkerContext.cpp
index 8c5ee47..5206fd9 100644
--- a/WebCore/workers/DedicatedWorkerContext.cpp
+++ b/WebCore/workers/DedicatedWorkerContext.cpp
@@ -71,23 +71,6 @@ void DedicatedWorkerContext::postMessage(const String& message, const MessagePor
     thread()->workerObjectProxy().postMessageToWorkerObject(message, channels.release());
 }
 
-void DedicatedWorkerContext::dispatchMessage(const String& message, PassOwnPtr<MessagePortArray> ports)
-{
-    // Since close() stops the thread event loop, this should not ever get called while closing.
-    ASSERT(!isClosing());
-    RefPtr<Event> evt = MessageEvent::create(message, "", "", 0, ports);
-
-    if (m_onmessageListener.get()) {
-        evt->setTarget(this);
-        evt->setCurrentTarget(this);
-        m_onmessageListener->handleEvent(evt.get(), false);
-    }
-
-    ExceptionCode ec = 0;
-    dispatchEvent(evt.release(), ec);
-    ASSERT(!ec);
-}
-
 void DedicatedWorkerContext::importScripts(const Vector<String>& urls, const String& callerURL, int callerLine, ExceptionCode& ec)
 {
     Base::importScripts(urls, callerURL, callerLine, ec);
diff --git a/WebCore/workers/DedicatedWorkerContext.h b/WebCore/workers/DedicatedWorkerContext.h
index 3bc4aee..7609fcd 100644
--- a/WebCore/workers/DedicatedWorkerContext.h
+++ b/WebCore/workers/DedicatedWorkerContext.h
@@ -59,15 +59,12 @@ namespace WebCore {
         void postMessage(const String&, const MessagePortArray*, ExceptionCode&);
         // FIXME: remove this when we update the ObjC bindings (bug #28774).
         void postMessage(const String&, MessagePort*, ExceptionCode&);
-        void setOnmessage(PassRefPtr<EventListener> eventListener) { m_onmessageListener = eventListener; }
-        EventListener* onmessage() const { return m_onmessageListener.get(); }
 
-        void dispatchMessage(const String&, PassOwnPtr<MessagePortArray>);
+        DEFINE_ATTRIBUTE_EVENT_LISTENER(message);
 
         DedicatedWorkerThread* thread();
     private:
         DedicatedWorkerContext(const KURL&, const String&, DedicatedWorkerThread*);
-        RefPtr<EventListener> m_onmessageListener;
     };
 
 } // namespace WebCore
diff --git a/WebCore/workers/DedicatedWorkerContext.idl b/WebCore/workers/DedicatedWorkerContext.idl
index ef3ebfe..899bbae 100644
--- a/WebCore/workers/DedicatedWorkerContext.idl
+++ b/WebCore/workers/DedicatedWorkerContext.idl
@@ -32,7 +32,6 @@ module threads {
 
     interface [
         Conditional=WORKERS,
-        CustomMarkFunction,
         ExtendsDOMGlobalObject,
         IsWorkerContext,
         GenerateNativeConverter,
diff --git a/WebCore/workers/DefaultSharedWorkerRepository.cpp b/WebCore/workers/DefaultSharedWorkerRepository.cpp
index dd8c5ef..11106ee 100644
--- a/WebCore/workers/DefaultSharedWorkerRepository.cpp
+++ b/WebCore/workers/DefaultSharedWorkerRepository.cpp
@@ -37,6 +37,7 @@
 #include "ActiveDOMObject.h"
 #include "Document.h"
 #include "GenericWorkerTask.h"
+#include "MessageEvent.h"
 #include "MessagePort.h"
 #include "NotImplemented.h"
 #include "PlatformString.h"
@@ -232,8 +233,10 @@ private:
         port->entangle(m_channel.release());
         ASSERT(scriptContext->isWorkerContext());
         WorkerContext* workerContext = static_cast<WorkerContext*>(scriptContext);
+        // Since close() stops the thread event loop, this should not ever get called while closing.
+        ASSERT(!workerContext->isClosing());
         ASSERT(workerContext->isSharedWorkerContext());
-        workerContext->toSharedWorkerContext()->dispatchConnect(port);
+        workerContext->toSharedWorkerContext()->dispatchEvent(createConnectEvent(port));
     }
 
     OwnPtr<MessagePortChannel> m_channel;
@@ -272,18 +275,19 @@ void SharedWorkerScriptLoader::load(const KURL& url)
 
     // Stay alive until the load finishes.
     setPendingActivity(this);
+    m_worker->setPendingActivity(m_worker.get());
 }
 
 void SharedWorkerScriptLoader::notifyFinished()
 {
     // Hand off the just-loaded code to the repository to start up the worker thread.
     if (m_scriptLoader->failed())
-        m_worker->dispatchLoadErrorEvent();
+        m_worker->dispatchEvent(Event::create(eventNames().errorEvent, false, true));
     else
         DefaultSharedWorkerRepository::instance().workerScriptLoaded(*m_proxy, scriptExecutionContext()->userAgent(m_scriptLoader->url()), m_scriptLoader->script(), m_port.release());
 
-    // This frees this object - must be the last action in this function.
-    unsetPendingActivity(this);
+    m_worker->unsetPendingActivity(m_worker.get());
+    unsetPendingActivity(this); // This frees this object - must be the last action in this function.
 }
 
 DefaultSharedWorkerRepository& DefaultSharedWorkerRepository::instance()
diff --git a/WebCore/workers/SharedWorker.idl b/WebCore/workers/SharedWorker.idl
index 09475f7..9353f18 100644
--- a/WebCore/workers/SharedWorker.idl
+++ b/WebCore/workers/SharedWorker.idl
@@ -32,7 +32,6 @@ module threads {
 
     interface [
         Conditional=SHARED_WORKERS,
-        CustomMarkFunction,
         GenerateNativeConverter,
         GenerateToJS
     ] SharedWorker : AbstractWorker {
diff --git a/WebCore/workers/SharedWorkerContext.cpp b/WebCore/workers/SharedWorkerContext.cpp
index bebcc73..cd76e3b 100644
--- a/WebCore/workers/SharedWorkerContext.cpp
+++ b/WebCore/workers/SharedWorkerContext.cpp
@@ -42,6 +42,13 @@
 
 namespace WebCore {
 
+PassRefPtr<MessageEvent> createConnectEvent(PassRefPtr<MessagePort> port)
+{
+    RefPtr<MessageEvent> event = MessageEvent::create(new MessagePortArray(1, port));
+    event->initEvent(eventNames().connectEvent, false, false);
+    return event;
+}
+
 SharedWorkerContext::SharedWorkerContext(const String& name, const KURL& url, const String& userAgent, SharedWorkerThread* thread)
     : WorkerContext(url, userAgent, thread)
     , m_name(name)
@@ -52,27 +59,6 @@ SharedWorkerContext::~SharedWorkerContext()
 {
 }
 
-void SharedWorkerContext::dispatchConnect(PassRefPtr<MessagePort> port)
-{
-    // Since close() stops the thread event loop, this should not ever get called while closing.
-    ASSERT(!isClosing());
-    // The connect event uses the MessageEvent interface, but has the name "connect".
-    OwnPtr<MessagePortArray> portArray(new MessagePortArray());
-    portArray->append(port);
-    RefPtr<Event> event = MessageEvent::create("", "", "", 0, portArray.release());
-    event->initEvent(eventNames().connectEvent, false, false);
-
-    if (m_onconnectListener.get()) {
-        event->setTarget(this);
-        event->setCurrentTarget(this);
-        m_onconnectListener->handleEvent(event.get(), false);
-    }
-
-    ExceptionCode ec = 0;
-    dispatchEvent(event.release(), ec);
-    ASSERT(!ec);
-}
-
 SharedWorkerThread* SharedWorkerContext::thread()
 {
     return static_cast<SharedWorkerThread*>(Base::thread());
diff --git a/WebCore/workers/SharedWorkerContext.h b/WebCore/workers/SharedWorkerContext.h
index d6956cd..59a7605 100644
--- a/WebCore/workers/SharedWorkerContext.h
+++ b/WebCore/workers/SharedWorkerContext.h
@@ -37,6 +37,7 @@
 
 namespace WebCore {
 
+    class MessageEvent;
     class SharedWorkerThread;
 
     class SharedWorkerContext : public WorkerContext {
@@ -54,19 +55,17 @@ namespace WebCore {
         virtual SharedWorkerContext* toSharedWorkerContext() { return this; }
 
         // Setters/Getters for attributes in SharedWorkerContext.idl
-        void setOnconnect(PassRefPtr<EventListener> eventListener) { m_onconnectListener = eventListener; }
-        EventListener* onconnect() const { return m_onconnectListener.get(); }
+        DEFINE_ATTRIBUTE_EVENT_LISTENER(connect);
         String name() const { return m_name; }
 
-        void dispatchConnect(PassRefPtr<MessagePort>);
-
         SharedWorkerThread* thread();
     private:
         SharedWorkerContext(const String& name, const KURL&, const String&, SharedWorkerThread*);
-        RefPtr<EventListener> m_onconnectListener;
         String m_name;
     };
 
+    PassRefPtr<MessageEvent> createConnectEvent(PassRefPtr<MessagePort>);
+
 } // namespace WebCore
 
 #endif // ENABLE(SHARED_WORKERS)
diff --git a/WebCore/workers/SharedWorkerContext.idl b/WebCore/workers/SharedWorkerContext.idl
index 8e450e0..a48e5bd 100644
--- a/WebCore/workers/SharedWorkerContext.idl
+++ b/WebCore/workers/SharedWorkerContext.idl
@@ -32,7 +32,6 @@ module threads {
 
     interface [
         Conditional=SHARED_WORKERS,
-        CustomMarkFunction,
         ExtendsDOMGlobalObject,
         IsWorkerContext,
         GenerateNativeConverter,
diff --git a/WebCore/workers/Worker.cpp b/WebCore/workers/Worker.cpp
index 922cd33..c2c25c1 100644
--- a/WebCore/workers/Worker.cpp
+++ b/WebCore/workers/Worker.cpp
@@ -116,7 +116,7 @@ bool Worker::hasPendingActivity() const
 void Worker::notifyFinished()
 {
     if (m_scriptLoader->failed())
-        dispatchLoadErrorEvent();
+        dispatchEvent(Event::create(eventNames().errorEvent, false, true));
     else
         m_contextProxy->startWorkerContext(m_scriptLoader->url(), scriptExecutionContext()->userAgent(m_scriptLoader->url()), m_scriptLoader->script());
 
@@ -125,21 +125,6 @@ void Worker::notifyFinished()
     unsetPendingActivity(this);
 }
 
-void Worker::dispatchMessage(const String& message, PassOwnPtr<MessagePortArray> ports)
-{
-    RefPtr<Event> evt = MessageEvent::create(message, "", "", 0, ports);
-
-    if (m_onMessageListener.get()) {
-        evt->setTarget(this);
-        evt->setCurrentTarget(this);
-        m_onMessageListener->handleEvent(evt.get(), false);
-    }
-
-    ExceptionCode ec = 0;
-    dispatchEvent(evt.release(), ec);
-    ASSERT(!ec);
-}
-
 } // namespace WebCore
 
 #endif // ENABLE(WORKERS)
diff --git a/WebCore/workers/Worker.h b/WebCore/workers/Worker.h
index 6bc00c1..41d39a2 100644
--- a/WebCore/workers/Worker.h
+++ b/WebCore/workers/Worker.h
@@ -33,6 +33,7 @@
 #include "ActiveDOMObject.h"
 #include "AtomicStringHash.h"
 #include "EventListener.h"
+#include "EventNames.h"
 #include "EventTarget.h"
 #include "MessagePort.h"
 #include "WorkerScriptLoaderClient.h"
@@ -64,15 +65,11 @@ namespace WebCore {
 
         void terminate();
 
-        void dispatchMessage(const String&, PassOwnPtr<MessagePortArray>);
-        void dispatchErrorEvent();
-
         virtual bool canSuspend() const;
         virtual void stop();
         virtual bool hasPendingActivity() const;
-
-        void setOnmessage(PassRefPtr<EventListener> eventListener) { m_onMessageListener = eventListener; }
-        EventListener* onmessage() const { return m_onMessageListener.get(); }
+    
+        DEFINE_ATTRIBUTE_EVENT_LISTENER(message);
 
     private:
         Worker(const String&, ScriptExecutionContext*, ExceptionCode&);
@@ -83,10 +80,7 @@ namespace WebCore {
         virtual void derefEventTarget() { deref(); }
 
         OwnPtr<WorkerScriptLoader> m_scriptLoader;
-
         WorkerContextProxy* m_contextProxy; // The proxy outlives the worker to perform thread shutdown.
-
-        RefPtr<EventListener> m_onMessageListener;
     };
 
 } // namespace WebCore
diff --git a/WebCore/workers/Worker.idl b/WebCore/workers/Worker.idl
index 3b4a3ff..9c9342b 100644
--- a/WebCore/workers/Worker.idl
+++ b/WebCore/workers/Worker.idl
@@ -28,7 +28,6 @@ module threads {
 
     interface [
         Conditional=WORKERS,
-        CustomMarkFunction,
         GenerateNativeConverter,
         GenerateToJS
     ] Worker : AbstractWorker {
diff --git a/WebCore/workers/WorkerContext.cpp b/WebCore/workers/WorkerContext.cpp
index 12620f4..22e5b56 100644
--- a/WebCore/workers/WorkerContext.cpp
+++ b/WebCore/workers/WorkerContext.cpp
@@ -161,57 +161,6 @@ void WorkerContext::scriptImported(unsigned long, const String&)
     notImplemented();
 }
 
-void WorkerContext::addEventListener(const AtomicString& eventType, PassRefPtr<EventListener> eventListener, bool)
-{
-    EventListenersMap::iterator iter = m_eventListeners.find(eventType);
-    if (iter == m_eventListeners.end()) {
-        ListenerVector listeners;
-        listeners.append(eventListener);
-        m_eventListeners.add(eventType, listeners);
-    } else {
-        ListenerVector& listeners = iter->second;
-        for (ListenerVector::iterator listenerIter = listeners.begin(); listenerIter != listeners.end(); ++listenerIter) {
-            if (**listenerIter == *eventListener)
-                return;
-        }
-        
-        listeners.append(eventListener);
-        m_eventListeners.add(eventType, listeners);
-    }    
-}
-
-void WorkerContext::removeEventListener(const AtomicString& eventType, EventListener* eventListener, bool)
-{
-    EventListenersMap::iterator iter = m_eventListeners.find(eventType);
-    if (iter == m_eventListeners.end())
-        return;
-    
-    ListenerVector& listeners = iter->second;
-    for (ListenerVector::const_iterator listenerIter = listeners.begin(); listenerIter != listeners.end(); ++listenerIter) {
-        if (**listenerIter == *eventListener) {
-            listeners.remove(listenerIter - listeners.begin());
-            return;
-        }
-    }
-}
-
-bool WorkerContext::dispatchEvent(PassRefPtr<Event> event, ExceptionCode& ec)
-{
-    if (!event || event->type().isEmpty()) {
-        ec = EventException::UNSPECIFIED_EVENT_TYPE_ERR;
-        return true;
-    }
-    
-    ListenerVector listenersCopy = m_eventListeners.get(event->type());
-    for (ListenerVector::const_iterator listenerIter = listenersCopy.begin(); listenerIter != listenersCopy.end(); ++listenerIter) {
-        event->setTarget(this);
-        event->setCurrentTarget(this);
-        listenerIter->get()->handleEvent(event.get(), false);
-    }
-    
-    return !event->defaultPrevented();
-}
-
 void WorkerContext::postTask(PassRefPtr<Task> task)
 {
     thread()->runLoop().postTask(task);
@@ -304,6 +253,16 @@ NotificationCenter* WorkerContext::webkitNotifications() const
 }
 #endif
 
+EventTargetData* WorkerContext::eventTargetData()
+{
+    return &m_eventTargetData;
+}
+
+EventTargetData* WorkerContext::ensureEventTargetData()
+{
+    return &m_eventTargetData;
+}
+
 } // namespace WebCore
 
 #endif // ENABLE(WORKERS)
diff --git a/WebCore/workers/WorkerContext.h b/WebCore/workers/WorkerContext.h
index a3c3820..9725cf7 100644
--- a/WebCore/workers/WorkerContext.h
+++ b/WebCore/workers/WorkerContext.h
@@ -31,6 +31,7 @@
 
 #include "AtomicStringHash.h"
 #include "EventListener.h"
+#include "EventNames.h"
 #include "EventTarget.h"
 #include "ScriptExecutionContext.h"
 #include "WorkerScriptController.h"
@@ -79,8 +80,8 @@ namespace WebCore {
         WorkerContext* self() { return this; }
         WorkerLocation* location() const;
         void close();
-        void setOnerror(PassRefPtr<EventListener> eventListener) { m_onerrorListener = eventListener; }
-        EventListener* onerror() const { return m_onerrorListener.get(); }
+
+        DEFINE_ATTRIBUTE_EVENT_LISTENER(error);
 
         // WorkerUtils
         virtual void importScripts(const Vector<String>& urls, const String& callerURL, int callerLine, ExceptionCode&);
@@ -92,15 +93,6 @@ namespace WebCore {
         int setInterval(ScheduledAction*, int timeout);
         void clearInterval(int timeoutId);
 
-        // EventTarget
-        virtual void addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture);
-        virtual void removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture);
-        virtual bool dispatchEvent(PassRefPtr<Event>, ExceptionCode&);
-
-        typedef Vector<RefPtr<EventListener> > ListenerVector;
-        typedef HashMap<AtomicString, ListenerVector> EventListenersMap;
-        EventListenersMap& eventListeners() { return m_eventListeners; }
-
         // ScriptExecutionContext
         virtual void reportException(const String& errorMessage, int lineNumber, const String& sourceURL);
         virtual void addMessage(MessageDestination, MessageSource, MessageType, MessageLevel, const String& message, unsigned lineNumber, const String& sourceURL);
@@ -125,8 +117,11 @@ namespace WebCore {
     private:
         virtual void refScriptExecutionContext() { ref(); }
         virtual void derefScriptExecutionContext() { deref(); }
+
         virtual void refEventTarget() { ref(); }
         virtual void derefEventTarget() { deref(); }
+        virtual EventTargetData* eventTargetData();
+        virtual EventTargetData* ensureEventTargetData();
 
         virtual const KURL& virtualURL() const;
         virtual KURL virtualCompleteURL(const String&) const;
@@ -140,13 +135,11 @@ namespace WebCore {
         OwnPtr<WorkerScriptController> m_script;
         WorkerThread* m_thread;
 
-        RefPtr<EventListener> m_onerrorListener;
-        EventListenersMap m_eventListeners;
-
 #if ENABLE_NOTIFICATIONS
         mutable RefPtr<NotificationCenter> m_notifications;
 #endif
         bool m_closing;
+        EventTargetData m_eventTargetData;
     };
 
 } // namespace WebCore
diff --git a/WebCore/workers/WorkerContext.idl b/WebCore/workers/WorkerContext.idl
index 6a4a7fa..17bee55 100644
--- a/WebCore/workers/WorkerContext.idl
+++ b/WebCore/workers/WorkerContext.idl
@@ -30,6 +30,7 @@ module threads {
         Conditional=WORKERS,
         CustomMarkFunction,
         DelegatingGetOwnPropertySlot,
+        EventTarget,
         ExtendsDOMGlobalObject,
         IsWorkerContext,
         LegacyParent=JSWorkerContextBase,
diff --git a/WebCore/workers/WorkerMessagingProxy.cpp b/WebCore/workers/WorkerMessagingProxy.cpp
index 49c88c0..3d28f9e 100644
--- a/WebCore/workers/WorkerMessagingProxy.cpp
+++ b/WebCore/workers/WorkerMessagingProxy.cpp
@@ -35,6 +35,8 @@
 #include "DedicatedWorkerThread.h"
 #include "DOMWindow.h"
 #include "Document.h"
+#include "ErrorEvent.h"
+#include "ExceptionCode.h"
 #include "GenericWorkerTask.h"
 #include "MessageEvent.h"
 #include "ScriptExecutionContext.h"
@@ -61,7 +63,7 @@ private:
         ASSERT(scriptContext->isWorkerContext());
         DedicatedWorkerContext* context = static_cast<DedicatedWorkerContext*>(scriptContext);
         OwnPtr<MessagePortArray> ports = MessagePort::entanglePorts(*scriptContext, m_channels.release());
-        context->dispatchMessage(m_message, ports.release());
+        context->dispatchEvent(MessageEvent::create(ports.release(), m_message));
         context->thread()->workerObjectProxy().confirmMessageFromWorkerObject(context->hasPendingActivity());
     }
 
@@ -92,7 +94,7 @@ private:
             return;
 
         OwnPtr<MessagePortArray> ports = MessagePort::entanglePorts(*scriptContext, m_channels.release());
-        workerObject->dispatchMessage(m_message, ports.release());
+        workerObject->dispatchEvent(MessageEvent::create(ports.release(), m_message));
     }
 
 private:
@@ -126,8 +128,7 @@ private:
         // We don't bother checking the askedToTerminate() flag here, because exceptions should *always* be reported even if the thread is terminated.
         // This is intentionally different than the behavior in MessageWorkerTask, because terminated workers no longer deliver messages (section 4.6 of the WebWorker spec), but they do report exceptions.
 
-        bool errorHandled = workerObject->dispatchScriptErrorEvent(m_errorMessage, m_sourceURL, m_lineNumber);
-
+        bool errorHandled = !workerObject->dispatchEvent(ErrorEvent::create(m_errorMessage, m_sourceURL, m_lineNumber));
         if (!errorHandled)
             context->reportException(m_errorMessage, m_lineNumber, m_sourceURL);
     }
diff --git a/WebCore/xml/XMLHttpRequest.cpp b/WebCore/xml/XMLHttpRequest.cpp
index ddff331..45abf30 100644
--- a/WebCore/xml/XMLHttpRequest.cpp
+++ b/WebCore/xml/XMLHttpRequest.cpp
@@ -235,56 +235,6 @@ XMLHttpRequestUpload* XMLHttpRequest::upload()
     return m_upload.get();
 }
 
-void XMLHttpRequest::addEventListener(const AtomicString& eventType, PassRefPtr<EventListener> eventListener, bool)
-{
-    EventListenersMap::iterator iter = m_eventListeners.find(eventType);
-    if (iter == m_eventListeners.end()) {
-        ListenerVector listeners;
-        listeners.append(eventListener);
-        m_eventListeners.add(eventType, listeners);
-    } else {
-        ListenerVector& listeners = iter->second;
-        for (ListenerVector::iterator listenerIter = listeners.begin(); listenerIter != listeners.end(); ++listenerIter)
-            if (**listenerIter == *eventListener)
-                return;
-
-        listeners.append(eventListener);
-        m_eventListeners.add(eventType, listeners);
-    }
-}
-
-void XMLHttpRequest::removeEventListener(const AtomicString& eventType, EventListener* eventListener, bool)
-{
-    EventListenersMap::iterator iter = m_eventListeners.find(eventType);
-    if (iter == m_eventListeners.end())
-        return;
-
-    ListenerVector& listeners = iter->second;
-    for (ListenerVector::const_iterator listenerIter = listeners.begin(); listenerIter != listeners.end(); ++listenerIter)
-        if (**listenerIter == *eventListener) {
-            listeners.remove(listenerIter - listeners.begin());
-            return;
-        }
-}
-
-bool XMLHttpRequest::dispatchEvent(PassRefPtr<Event> evt, ExceptionCode& ec)
-{
-    // FIXME: check for other error conditions enumerated in the spec.
-    if (!evt || evt->type().isEmpty()) {
-        ec = EventException::UNSPECIFIED_EVENT_TYPE_ERR;
-        return true;
-    }
-
-    ListenerVector listenersCopy = m_eventListeners.get(evt->type());
-    for (ListenerVector::const_iterator listenerIter = listenersCopy.begin(); listenerIter != listenersCopy.end(); ++listenerIter) {
-        evt->setTarget(this);
-        evt->setCurrentTarget(this);
-        listenerIter->get()->handleEvent(evt.get(), false);
-    }
-
-    return !evt->defaultPrevented();
-}
-
 void XMLHttpRequest::changeState(State newState)
 {
     if (m_state != newState) {
@@ -298,10 +248,10 @@ void XMLHttpRequest::callReadyStateChangeListener()
     if (!scriptExecutionContext())
         return;
 
-    dispatchReadyStateChangeEvent();
+    dispatchEvent(XMLHttpRequestProgressEvent::create(eventNames().readystatechangeEvent));
 
     if (m_state == DONE && !m_error)
-        dispatchLoadEvent();
+        dispatchEvent(XMLHttpRequestProgressEvent::create(eventNames().loadEvent));
 }
 
 void XMLHttpRequest::setWithCredentials(bool value, ExceptionCode& ec)
@@ -479,10 +429,10 @@ void XMLHttpRequest::createRequest(ExceptionCode& ec)
     // Also, only async requests support upload progress events.
     bool forcePreflight = false;
     if (m_async) {
-        dispatchLoadStartEvent();
+        dispatchEvent(XMLHttpRequestProgressEvent::create(eventNames().loadstartEvent));
         if (m_requestEntityBody && m_upload) {
-            forcePreflight = m_upload->hasListeners();
-            m_upload->dispatchLoadStartEvent();
+            forcePreflight = m_upload->hasEventListeners();
+            m_upload->dispatchEvent(XMLHttpRequestProgressEvent::create(eventNames().loadstartEvent));
         }
     }
 
@@ -571,11 +521,11 @@ void XMLHttpRequest::abort()
         m_state = UNSENT;
     }
 
-    dispatchAbortEvent();
+    dispatchEvent(XMLHttpRequestProgressEvent::create(eventNames().abortEvent));
     if (!m_uploadComplete) {
         m_uploadComplete = true;
         if (m_upload && m_uploadEventsAllowed)
-            m_upload->dispatchAbortEvent();
+            m_upload->dispatchEvent(XMLHttpRequestProgressEvent::create(eventNames().abortEvent));
     }
 }
 
@@ -625,11 +575,11 @@ void XMLHttpRequest::genericError()
 void XMLHttpRequest::networkError()
 {
     genericError();
-    dispatchErrorEvent();
+    dispatchEvent(XMLHttpRequestProgressEvent::create(eventNames().errorEvent));
     if (!m_uploadComplete) {
         m_uploadComplete = true;
         if (m_upload && m_uploadEventsAllowed)
-            m_upload->dispatchErrorEvent();
+            m_upload->dispatchEvent(XMLHttpRequestProgressEvent::create(eventNames().errorEvent));
     }
     internalAbort();
 }
@@ -637,11 +587,11 @@ void XMLHttpRequest::networkError()
 void XMLHttpRequest::abortError()
 {
     genericError();
-    dispatchAbortEvent();
+    dispatchEvent(XMLHttpRequestProgressEvent::create(eventNames().abortEvent));
     if (!m_uploadComplete) {
         m_uploadComplete = true;
         if (m_upload && m_uploadEventsAllowed)
-            m_upload->dispatchAbortEvent();
+            m_upload->dispatchEvent(XMLHttpRequestProgressEvent::create(eventNames().abortEvent));
     }
 }
 
@@ -889,12 +839,12 @@ void XMLHttpRequest::didSendData(unsigned long long bytesSent, unsigned long lon
         return;
 
     if (m_uploadEventsAllowed)
-        m_upload->dispatchProgressEvent(bytesSent, totalBytesToBeSent);
+        m_upload->dispatchEvent(XMLHttpRequestProgressEvent::create(eventNames().progressEvent, true, bytesSent, totalBytesToBeSent));
 
     if (bytesSent == totalBytesToBeSent && !m_uploadComplete) {
         m_uploadComplete = true;
         if (m_uploadEventsAllowed)
-            m_upload->dispatchLoadEvent();
+            m_upload->dispatchEvent(XMLHttpRequestProgressEvent::create(eventNames().loadEvent));
     }
 }
 
@@ -942,7 +892,12 @@ void XMLHttpRequest::didReceiveData(const char* data, int len)
     m_responseText += m_decoder->decode(data, len);
 
     if (!m_error) {
-        updateAndDispatchOnProgress(len);
+        long long expectedLength = m_response.expectedContentLength();
+        m_receivedLength += len;
+
+        // FIXME: the spec requires that we dispatch the event according to the least
+        // frequent method between every 350ms (+/-200ms) and for every byte received.
+        dispatchEvent(XMLHttpRequestProgressEvent::create(eventNames().progressEvent, expectedLength && m_receivedLength <= expectedLength, m_receivedLength, expectedLength));
 
         if (m_state != LOADING)
             changeState(LOADING);
@@ -952,70 +907,6 @@ void XMLHttpRequest::didReceiveData(const char* data, int len)
     }
 }
 
-void XMLHttpRequest::updateAndDispatchOnProgress(unsigned int len)
-{
-    long long expectedLength = m_response.expectedContentLength();
-    m_receivedLength += len;
-
-    // FIXME: the spec requires that we dispatch the event according to the least
-    // frequent method between every 350ms (+/-200ms) and for every byte received.
-    dispatchProgressEvent(expectedLength);
-}
-
-void XMLHttpRequest::dispatchReadyStateChangeEvent()
-{
-    RefPtr<Event> evt = Event::create(eventNames().readystatechangeEvent, false, false);
-    if (m_onReadyStateChangeListener) {
-        evt->setTarget(this);
-        evt->setCurrentTarget(this);
-        m_onReadyStateChangeListener->handleEvent(evt.get(), false);
-    }
-
-    ExceptionCode ec = 0;
-    dispatchEvent(evt.release(), ec);
-    ASSERT(!ec);
-}
-
-void XMLHttpRequest::dispatchXMLHttpRequestProgressEvent(EventListener* listener, const AtomicString& type, bool lengthComputable, unsigned loaded, unsigned total)
-{
-    RefPtr<XMLHttpRequestProgressEvent> evt = XMLHttpRequestProgressEvent::create(type, lengthComputable, loaded, total);
-    if (listener) {
-        evt->setTarget(this);
-        evt->setCurrentTarget(this);
-        listener->handleEvent(evt.get(), false);
-    }
-
-    ExceptionCode ec = 0;
-    dispatchEvent(evt.release(), ec);
-    ASSERT(!ec);
-}
-
-void XMLHttpRequest::dispatchAbortEvent()
-{
-    dispatchXMLHttpRequestProgressEvent(m_onAbortListener.get(), eventNames().abortEvent, false, 0, 0);
-}
-
-void XMLHttpRequest::dispatchErrorEvent()
-{
-    dispatchXMLHttpRequestProgressEvent(m_onErrorListener.get(), eventNames().errorEvent, false, 0, 0);
-}
-
-void XMLHttpRequest::dispatchLoadEvent()
-{
-    dispatchXMLHttpRequestProgressEvent(m_onLoadListener.get(), eventNames().loadEvent, false, 0, 0);
-}
-
-void XMLHttpRequest::dispatchLoadStartEvent()
-{
-    dispatchXMLHttpRequestProgressEvent(m_onLoadStartListener.get(), eventNames().loadstartEvent, false, 0, 0);
-}
-
-void XMLHttpRequest::dispatchProgressEvent(long long expectedLength)
-{
-    dispatchXMLHttpRequestProgressEvent(m_onProgressListener.get(), eventNames().progressEvent, expectedLength && m_receivedLength <= expectedLength,
-                                        static_cast<unsigned>(m_receivedLength), static_cast<unsigned>(expectedLength));
-}
-
 bool XMLHttpRequest::canSuspend() const
 {
     return !m_loader;
@@ -1037,4 +928,14 @@ ScriptExecutionContext* XMLHttpRequest::scriptExecutionContext() const
     return ActiveDOMObject::scriptExecutionContext();
 }
 
+EventTargetData* XMLHttpRequest::eventTargetData()
+{
+    return &m_eventTargetData;
+}
+
+EventTargetData* XMLHttpRequest::ensureEventTargetData()
+{
+    return &m_eventTargetData;
+}
+
 } // namespace WebCore
diff --git a/WebCore/xml/XMLHttpRequest.h b/WebCore/xml/XMLHttpRequest.h
index aa33b8b..30744a0 100644
--- a/WebCore/xml/XMLHttpRequest.h
+++ b/WebCore/xml/XMLHttpRequest.h
@@ -23,6 +23,7 @@
 #include "ActiveDOMObject.h"
 #include "AtomicStringHash.h"
 #include "EventListener.h"
+#include "EventNames.h"
 #include "EventTarget.h"
 #include "FormData.h"
 #include "ResourceResponse.h"
@@ -85,32 +86,12 @@ public:
     XMLHttpRequestUpload* upload();
     XMLHttpRequestUpload* optionalUpload() const { return m_upload.get(); }
 
-    void setOnreadystatechange(PassRefPtr<EventListener> eventListener) { m_onReadyStateChangeListener = eventListener; }
-    EventListener* onreadystatechange() const { return m_onReadyStateChangeListener.get(); }
-
-    void setOnabort(PassRefPtr<EventListener> eventListener) { m_onAbortListener = eventListener; }
-    EventListener* onabort() const { return m_onAbortListener.get(); }
-
-    void setOnerror(PassRefPtr<EventListener> eventListener) { m_onErrorListener = eventListener; }
-    EventListener* onerror() const { return m_onErrorListener.get(); }
-
-    void setOnload(PassRefPtr<EventListener> eventListener) { m_onLoadListener = eventListener; }
-    EventListener* onload() const { return m_onLoadListener.get(); }
-
-    void setOnloadstart(PassRefPtr<EventListener> eventListener) { m_onLoadStartListener = eventListener; }
-    EventListener* onloadstart() const { return m_onLoadStartListener.get(); }
-
-    void setOnprogress(PassRefPtr<EventListener> eventListener) { m_onProgressListener = eventListener; }
-    EventListener* onprogress() const { return m_onProgressListener.get(); }
-
-    typedef Vector<RefPtr<EventListener> > ListenerVector;
-    typedef HashMap<AtomicString, ListenerVector> EventListenersMap;
-
-    // useCapture is not used, even for add/remove pairing (for Firefox compatibility).
-    virtual void addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture);
-    virtual void removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture);
-    virtual bool dispatchEvent(PassRefPtr<Event>, ExceptionCode&);
-    EventListenersMap& eventListeners() { return m_eventListeners; }
+    DEFINE_ATTRIBUTE_EVENT_LISTENER(readystatechange);
+    DEFINE_ATTRIBUTE_EVENT_LISTENER(abort);
+    DEFINE_ATTRIBUTE_EVENT_LISTENER(error);
+    DEFINE_ATTRIBUTE_EVENT_LISTENER(load);
+    DEFINE_ATTRIBUTE_EVENT_LISTENER(loadstart);
+    DEFINE_ATTRIBUTE_EVENT_LISTENER(progress);
 
     using RefCounted<XMLHttpRequest>::ref;
     using RefCounted<XMLHttpRequest>::deref;
@@ -120,6 +101,8 @@ private:
 
     virtual void refEventTarget() { ref(); }
     virtual void derefEventTarget() { deref(); }
+    virtual EventTargetData* eventTargetData();
+    virtual EventTargetData* ensureEventTargetData();
 
     Document* document() const;
 
@@ -135,8 +118,6 @@ private:
     virtual void didFailRedirectCheck();
     virtual void didReceiveAuthenticationCancellation(const ResourceResponse&);
 
-    void updateAndDispatchOnProgress(unsigned int len);
-
     String responseMIMEType() const;
     bool responseIsXML() const;
 
@@ -159,22 +140,6 @@ private:
     void networkError();
     void abortError();
 
-    void dispatchReadyStateChangeEvent();
-    void dispatchXMLHttpRequestProgressEvent(EventListener* listener, const AtomicString& type, bool lengthComputable, unsigned loaded, unsigned total);
-    void dispatchAbortEvent();
-    void dispatchErrorEvent();
-    void dispatchLoadEvent();
-    void dispatchLoadStartEvent();
-    void dispatchProgressEvent(long long expectedLength);
-
-    RefPtr<EventListener> m_onReadyStateChangeListener;
-    RefPtr<EventListener> m_onAbortListener;
-    RefPtr<EventListener> m_onErrorListener;
-    RefPtr<EventListener> m_onLoadListener;
-    RefPtr<EventListener> m_onLoadStartListener;
-    RefPtr<EventListener> m_onProgressListener;
-    EventListenersMap m_eventListeners;
-
     RefPtr<XMLHttpRequestUpload> m_upload;
 
     KURL m_url;
@@ -217,6 +182,8 @@ private:
     unsigned m_lastSendLineNumber;
     String m_lastSendURL;
     ExceptionCode m_exceptionCode;
+    
+    EventTargetData m_eventTargetData;
 };
 
 } // namespace WebCore
diff --git a/WebCore/xml/XMLHttpRequest.idl b/WebCore/xml/XMLHttpRequest.idl
index 79005e2..89d9c7f 100644
--- a/WebCore/xml/XMLHttpRequest.idl
+++ b/WebCore/xml/XMLHttpRequest.idl
@@ -30,6 +30,7 @@ module xml {
 
     interface [
         CustomMarkFunction,
+        EventTarget,
         NoStaticTables
     ] XMLHttpRequest {
         // From XMLHttpRequestEventTarget
diff --git a/WebCore/xml/XMLHttpRequestProgressEvent.h b/WebCore/xml/XMLHttpRequestProgressEvent.h
index 02bfdea..27f3b8c 100644
--- a/WebCore/xml/XMLHttpRequestProgressEvent.h
+++ b/WebCore/xml/XMLHttpRequestProgressEvent.h
@@ -37,7 +37,7 @@ namespace WebCore {
         {
             return adoptRef(new XMLHttpRequestProgressEvent);
         }
-        static PassRefPtr<XMLHttpRequestProgressEvent> create(const AtomicString& type, bool lengthComputable, unsigned loaded, unsigned total)
+        static PassRefPtr<XMLHttpRequestProgressEvent> create(const AtomicString& type, bool lengthComputable = false, unsigned loaded = 0, unsigned total = 0)
         {
             return adoptRef(new XMLHttpRequestProgressEvent(type, lengthComputable, loaded, total));
         }
diff --git a/WebCore/xml/XMLHttpRequestUpload.cpp b/WebCore/xml/XMLHttpRequestUpload.cpp
index 0fe329d..9d0fafc 100644
--- a/WebCore/xml/XMLHttpRequestUpload.cpp
+++ b/WebCore/xml/XMLHttpRequestUpload.cpp
@@ -41,11 +41,6 @@ XMLHttpRequestUpload::XMLHttpRequestUpload(XMLHttpRequest* xmlHttpRequest)
 {
 }
 
-bool XMLHttpRequestUpload::hasListeners() const
-{
-    return m_onAbortListener || m_onErrorListener || m_onLoadListener || m_onLoadStartListener || m_onProgressListener || !m_eventListeners.isEmpty();
-}
-
 ScriptExecutionContext* XMLHttpRequestUpload::scriptExecutionContext() const
 {
     XMLHttpRequest* xmlHttpRequest = associatedXMLHttpRequest();
@@ -54,95 +49,14 @@ ScriptExecutionContext* XMLHttpRequestUpload::scriptExecutionContext() const
     return xmlHttpRequest->scriptExecutionContext();
 }
 
-void XMLHttpRequestUpload::addEventListener(const AtomicString& eventType, PassRefPtr<EventListener> eventListener, bool)
-{
-    EventListenersMap::iterator iter = m_eventListeners.find(eventType);
-    if (iter == m_eventListeners.end()) {
-        ListenerVector listeners;
-        listeners.append(eventListener);
-        m_eventListeners.add(eventType, listeners);
-    } else {
-        ListenerVector& listeners = iter->second;
-        for (ListenerVector::iterator listenerIter = listeners.begin(); listenerIter != listeners.end(); ++listenerIter) {
-            if (**listenerIter == *eventListener)
-                return;
-        }
-        
-        listeners.append(eventListener);
-        m_eventListeners.add(eventType, listeners);
-    }
-}
-
-void XMLHttpRequestUpload::removeEventListener(const AtomicString& eventType, EventListener* eventListener, bool)
-{
-    EventListenersMap::iterator iter = m_eventListeners.find(eventType);
-    if (iter == m_eventListeners.end())
-        return;
-
-    ListenerVector& listeners = iter->second;
-    for (ListenerVector::const_iterator listenerIter = listeners.begin(); listenerIter != listeners.end(); ++listenerIter) {
-        if (**listenerIter == *eventListener) {
-            listeners.remove(listenerIter - listeners.begin());
-            return;
-        }
-    }
-}
-
-bool XMLHttpRequestUpload::dispatchEvent(PassRefPtr<Event> evt, ExceptionCode& ec)
-{
-    // FIXME: check for other error conditions enumerated in the spec.
-    if (!evt || evt->type().isEmpty()) {
-        ec = EventException::UNSPECIFIED_EVENT_TYPE_ERR;
-        return true;
-    }
-
-    ListenerVector listenersCopy = m_eventListeners.get(evt->type());
-    for (ListenerVector::const_iterator listenerIter = listenersCopy.begin(); listenerIter != listenersCopy.end(); ++listenerIter) {
-        evt->setTarget(this);
-        evt->setCurrentTarget(this);
-        listenerIter->get()->handleEvent(evt.get(), false);
-    }
-
-    return !evt->defaultPrevented();
-}
-
-void XMLHttpRequestUpload::dispatchXMLHttpRequestProgressEvent(EventListener* listener, const AtomicString& type, bool lengthComputable, unsigned loaded, unsigned total)
-{
-    RefPtr<XMLHttpRequestProgressEvent> evt = XMLHttpRequestProgressEvent::create(type, lengthComputable, loaded, total);
-    if (listener) {
-        evt->setTarget(this);
-        evt->setCurrentTarget(this);
-        listener->handleEvent(evt.get(), false);
-    }
-
-    ExceptionCode ec = 0;
-    dispatchEvent(evt.release(), ec);
-    ASSERT(!ec);
-}
-
-void XMLHttpRequestUpload::dispatchAbortEvent()
-{
-    dispatchXMLHttpRequestProgressEvent(m_onAbortListener.get(), eventNames().abortEvent, false, 0, 0);
-}
-
-void XMLHttpRequestUpload::dispatchErrorEvent()
-{
-    dispatchXMLHttpRequestProgressEvent(m_onErrorListener.get(), eventNames().errorEvent, false, 0, 0);
-}
-
-void XMLHttpRequestUpload::dispatchLoadEvent()
-{
-    dispatchXMLHttpRequestProgressEvent(m_onLoadListener.get(), eventNames().loadEvent, false, 0, 0);
-}
-
-void XMLHttpRequestUpload::dispatchLoadStartEvent()
+EventTargetData* XMLHttpRequestUpload::eventTargetData()
 {
-    dispatchXMLHttpRequestProgressEvent(m_onLoadStartListener.get(), eventNames().loadstartEvent, false, 0, 0);
+    return &m_eventTargetData;
 }
 
-void XMLHttpRequestUpload::dispatchProgressEvent(long long bytesSent, long long totalBytesToBeSent)
+EventTargetData* XMLHttpRequestUpload::ensureEventTargetData()
 {
-    dispatchXMLHttpRequestProgressEvent(m_onProgressListener.get(), eventNames().progressEvent, true, static_cast<unsigned>(bytesSent), static_cast<unsigned>(totalBytesToBeSent));
+    return &m_eventTargetData;
 }
 
 } // namespace WebCore
diff --git a/WebCore/xml/XMLHttpRequestUpload.h b/WebCore/xml/XMLHttpRequestUpload.h
index b4f40e0..7640643 100644
--- a/WebCore/xml/XMLHttpRequestUpload.h
+++ b/WebCore/xml/XMLHttpRequestUpload.h
@@ -28,6 +28,7 @@
 
 #include "AtomicStringHash.h"
 #include "EventListener.h"
+#include "EventNames.h"
 #include "EventTarget.h"
 #include <wtf/HashMap.h>
 #include <wtf/RefCounted.h>
@@ -48,8 +49,6 @@ namespace WebCore {
             return adoptRef(new XMLHttpRequestUpload(xmlHttpRequest));
         }
 
-        bool hasListeners() const;
-
         virtual XMLHttpRequestUpload* toXMLHttpRequestUpload() { return this; }
 
         XMLHttpRequest* associatedXMLHttpRequest() const { return m_xmlHttpRequest; }
@@ -57,34 +56,11 @@ namespace WebCore {
 
         ScriptExecutionContext* scriptExecutionContext() const;
 
-        void dispatchAbortEvent();
-        void dispatchErrorEvent();
-        void dispatchLoadEvent();
-        void dispatchLoadStartEvent();
-        void dispatchProgressEvent(long long bytesSent, long long totalBytesToBeSent);
-
-        void setOnabort(PassRefPtr<EventListener> eventListener) { m_onAbortListener = eventListener; }
-        EventListener* onabort() const { return m_onAbortListener.get(); }
-
-        void setOnerror(PassRefPtr<EventListener> eventListener) { m_onErrorListener = eventListener; }
-        EventListener* onerror() const { return m_onErrorListener.get(); }
-
-        void setOnload(PassRefPtr<EventListener> eventListener) { m_onLoadListener = eventListener; }
-        EventListener* onload() const { return m_onLoadListener.get(); }
-
-        void setOnloadstart(PassRefPtr<EventListener> eventListener) { m_onLoadStartListener = eventListener; }
-        EventListener* onloadstart() const { return m_onLoadStartListener.get(); }
-
-        void setOnprogress(PassRefPtr<EventListener> eventListener) { m_onProgressListener = eventListener; }
-        EventListener* onprogress() const { return m_onProgressListener.get(); }
-
-        typedef Vector<RefPtr<EventListener> > ListenerVector;
-        typedef HashMap<AtomicString, ListenerVector> EventListenersMap;
-
-        virtual void addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture);
-        virtual void removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture);
-        virtual bool dispatchEvent(PassRefPtr<Event>, ExceptionCode&);
-        EventListenersMap& eventListeners() { return m_eventListeners; }
+        DEFINE_ATTRIBUTE_EVENT_LISTENER(abort);
+        DEFINE_ATTRIBUTE_EVENT_LISTENER(error);
+        DEFINE_ATTRIBUTE_EVENT_LISTENER(load);
+        DEFINE_ATTRIBUTE_EVENT_LISTENER(loadstart);
+        DEFINE_ATTRIBUTE_EVENT_LISTENER(progress);
 
         using RefCounted<XMLHttpRequestUpload>::ref;
         using RefCounted<XMLHttpRequestUpload>::deref;
@@ -92,19 +68,13 @@ namespace WebCore {
     private:
         XMLHttpRequestUpload(XMLHttpRequest*);
 
-        void dispatchXMLHttpRequestProgressEvent(EventListener*, const AtomicString& type, bool lengthComputable, unsigned loaded, unsigned total);
-
         virtual void refEventTarget() { ref(); }
         virtual void derefEventTarget() { deref(); }
-
-        RefPtr<EventListener> m_onAbortListener;
-        RefPtr<EventListener> m_onErrorListener;
-        RefPtr<EventListener> m_onLoadListener;
-        RefPtr<EventListener> m_onLoadStartListener;
-        RefPtr<EventListener> m_onProgressListener;
-        EventListenersMap m_eventListeners;
+        virtual EventTargetData* eventTargetData();
+        virtual EventTargetData* ensureEventTargetData();
 
         XMLHttpRequest* m_xmlHttpRequest;
+        EventTargetData m_eventTargetData;
     };
     
 } // namespace WebCore
diff --git a/WebCore/xml/XMLHttpRequestUpload.idl b/WebCore/xml/XMLHttpRequestUpload.idl
index 3172f68..901b47c 100644
--- a/WebCore/xml/XMLHttpRequestUpload.idl
+++ b/WebCore/xml/XMLHttpRequestUpload.idl
@@ -29,8 +29,9 @@
 module xml {
 
     interface [
-        GenerateConstructor,
         CustomMarkFunction,
+        EventTarget,
+        GenerateConstructor,
         NoStaticTables
     ] XMLHttpRequestUpload {
         // From XMLHttpRequestEventTarget
diff --git a/WebKit/mac/ChangeLog b/WebKit/mac/ChangeLog
index d157ddb..c54a78e 100644
--- a/WebKit/mac/ChangeLog
+++ b/WebKit/mac/ChangeLog
@@ -1,3 +1,12 @@
+2009-09-23  Geoffrey Garen  <ggaren at apple.com>
+
+        Reviewed by Sam Weinig.
+
+        Updated for a WebCore rename.
+
+        * WebView/WebFrame.mm:
+        (-[WebFrame _cacheabilityDictionary]):
+
 2009-09-23  Darin Adler  <darin at apple.com>
 
         Reviewed by Dan Bernstein.
diff --git a/WebKit/mac/WebView/WebFrame.mm b/WebKit/mac/WebView/WebFrame.mm
index c03ef58..95a76e2 100644
--- a/WebKit/mac/WebView/WebFrame.mm
+++ b/WebKit/mac/WebView/WebFrame.mm
@@ -1174,7 +1174,7 @@ static inline WebDataSource *dataSource(DocumentLoader* loader)
         [result setObject:[NSNumber numberWithBool:YES] forKey:WebFrameHasPlugins];
     
     if (DOMWindow* domWindow = _private->coreFrame->domWindow()) {
-        if (domWindow->hasEventListener(eventNames().unloadEvent))
+        if (domWindow->hasEventListeners(eventNames().unloadEvent))
             [result setObject:[NSNumber numberWithBool:YES] forKey:WebFrameHasUnloadListener];
             
         if (domWindow->optionalApplicationCache())

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list