Bug 822399 - Make Event to use Paris bindings, r=peterv
authorOlli Pettay <Olli.Pettay@helsinki.fi>
Sat, 09 Mar 2013 13:34:29 +0200
changeset 135508 eaff1533257994b4cd479bc33e4024162addef46
parent 135507 e38c5c3468409bdfcdf8381f6af07f55c413d0e8
child 135509 0df8261e828f7fdf72f3ebc369ecb9fdad8ff616
push id336
push userakeybl@mozilla.com
push dateMon, 17 Jun 2013 22:53:19 +0000
treeherdermozilla-release@574a39cdf657 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerspeterv
bugs822399
milestone22.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 822399 - Make Event to use Paris bindings, r=peterv
browser/base/content/browser.js
content/base/public/nsIDocument.h
content/base/src/EventSource.cpp
content/base/src/FileIOObject.cpp
content/base/src/WebSocket.cpp
content/base/src/nsDOMAttribute.cpp
content/base/src/nsDOMDataChannel.cpp
content/base/src/nsDocument.cpp
content/base/src/nsINode.cpp
content/base/src/nsXMLHttpRequest.cpp
content/base/src/nsXMLHttpRequest.h
content/events/public/EventTarget.h
content/events/public/nsEventDispatcher.h
content/events/src/DOMWheelEvent.cpp
content/events/src/DOMWheelEvent.h
content/events/src/nsAsyncDOMEvent.cpp
content/events/src/nsDOMAnimationEvent.cpp
content/events/src/nsDOMAnimationEvent.h
content/events/src/nsDOMBeforeUnloadEvent.cpp
content/events/src/nsDOMBeforeUnloadEvent.h
content/events/src/nsDOMCommandEvent.cpp
content/events/src/nsDOMCommandEvent.h
content/events/src/nsDOMCompositionEvent.cpp
content/events/src/nsDOMCompositionEvent.h
content/events/src/nsDOMDataContainerEvent.cpp
content/events/src/nsDOMDataContainerEvent.h
content/events/src/nsDOMDeviceMotionEvent.cpp
content/events/src/nsDOMDeviceMotionEvent.h
content/events/src/nsDOMDragEvent.cpp
content/events/src/nsDOMDragEvent.h
content/events/src/nsDOMEvent.cpp
content/events/src/nsDOMEvent.h
content/events/src/nsDOMEventTargetHelper.cpp
content/events/src/nsDOMEventTargetHelper.h
content/events/src/nsDOMKeyboardEvent.cpp
content/events/src/nsDOMKeyboardEvent.h
content/events/src/nsDOMMessageEvent.cpp
content/events/src/nsDOMMessageEvent.h
content/events/src/nsDOMMouseEvent.cpp
content/events/src/nsDOMMouseEvent.h
content/events/src/nsDOMMouseScrollEvent.cpp
content/events/src/nsDOMMouseScrollEvent.h
content/events/src/nsDOMMutationEvent.cpp
content/events/src/nsDOMMutationEvent.h
content/events/src/nsDOMNotifyAudioAvailableEvent.cpp
content/events/src/nsDOMNotifyAudioAvailableEvent.h
content/events/src/nsDOMNotifyPaintEvent.cpp
content/events/src/nsDOMNotifyPaintEvent.h
content/events/src/nsDOMScrollAreaEvent.cpp
content/events/src/nsDOMScrollAreaEvent.h
content/events/src/nsDOMSimpleGestureEvent.cpp
content/events/src/nsDOMSimpleGestureEvent.h
content/events/src/nsDOMTextEvent.cpp
content/events/src/nsDOMTextEvent.h
content/events/src/nsDOMTouchEvent.cpp
content/events/src/nsDOMTouchEvent.h
content/events/src/nsDOMTransitionEvent.cpp
content/events/src/nsDOMTransitionEvent.h
content/events/src/nsDOMUIEvent.cpp
content/events/src/nsDOMUIEvent.h
content/events/src/nsDOMXULCommandEvent.cpp
content/events/src/nsDOMXULCommandEvent.h
content/events/src/nsEventDispatcher.cpp
content/events/src/nsEventListenerManager.cpp
content/events/src/nsEventStateManager.cpp
content/html/content/src/nsHTMLInputElement.cpp
content/html/document/src/nsHTMLDocument.h
content/smil/nsDOMTimeEvent.cpp
content/smil/nsDOMTimeEvent.h
content/svg/content/src/nsDOMSVGEvent.cpp
content/svg/content/src/nsDOMSVGEvent.h
content/svg/content/src/nsDOMSVGZoomEvent.cpp
content/svg/content/src/nsDOMSVGZoomEvent.h
dom/base/DOMRequest.cpp
dom/base/nsDOMClassInfo.cpp
dom/base/nsDOMClassInfo.h
dom/base/nsDOMClassInfoID.h
dom/base/nsGlobalWindow.cpp
dom/bindings/BindingUtils.h
dom/bindings/Bindings.conf
dom/bluetooth/BluetoothAdapter.cpp
dom/browser-element/BrowserElementParent.cpp
dom/cellbroadcast/src/CellBroadcast.cpp
dom/devicestorage/nsDeviceStorage.cpp
dom/file/FileRequest.cpp
dom/file/LockedFile.cpp
dom/icc/src/IccManager.cpp
dom/icc/src/StkCommandEvent.cpp
dom/icc/src/StkCommandEvent.h
dom/imptests/failures/webapps/DOMCore/tests/approved/test_interfaces.html.json
dom/imptests/failures/webapps/DOMCore/tests/submissions/Ms2ger/Makefile.in
dom/imptests/failures/webapps/DOMCore/tests/submissions/Ms2ger/test_Event-constructors.html.json
dom/indexedDB/AsyncConnectionHelper.cpp
dom/indexedDB/AsyncConnectionHelper.h
dom/indexedDB/IDBEvents.cpp
dom/indexedDB/IDBEvents.h
dom/indexedDB/IDBTransaction.cpp
dom/indexedDB/OpenDatabaseHelper.cpp
dom/indexedDB/ipc/IndexedDBChild.cpp
dom/interfaces/events/nsIDOMEvent.idl
dom/ipc/TabChild.cpp
dom/ipc/TabMessageUtils.cpp
dom/ipc/TabMessageUtils.h
dom/ipc/TabParent.cpp
dom/mobilemessage/src/SmsManager.cpp
dom/mobilemessage/src/SmsRequest.cpp
dom/network/src/MobileConnection.cpp
dom/src/events/nsJSEventListener.cpp
dom/src/notification/nsDesktopNotification.cpp
dom/src/offline/nsDOMOfflineResourceList.cpp
dom/src/storage/nsDOMStorage.cpp
dom/system/nsDeviceSensors.cpp
dom/system/nsDeviceSensors.h
dom/telephony/Telephony.cpp
dom/telephony/TelephonyCall.cpp
dom/tests/mochitest/bugs/test_bug484775.html
dom/voicemail/Voicemail.cpp
dom/webidl/Event.webidl
dom/webidl/EventListener.webidl
dom/webidl/EventTarget.webidl
dom/webidl/WebIDL.mk
dom/workers/EventTarget.h
js/xpconnect/src/event_impl_gen.py
js/xpconnect/src/nsDOMQS.h
layout/base/nsPresContext.cpp
layout/xul/base/src/nsMenuFrame.cpp
security/manager/ssl/src/nsNSSComponent.cpp
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -196,24 +196,24 @@ XPCOMUtils.defineLazyGetter(this, "PageM
   Cu.import("resource://gre/modules/PageMenu.jsm", tmp);
   return new tmp.PageMenu();
 });
 
 /**
 * We can avoid adding multiple load event listeners and save some time by adding
 * one listener that calls all real handlers.
 */
-function pageShowEventHandlers(event) {
+function pageShowEventHandlers(persisted) {
   charsetLoadListener();
   XULBrowserWindow.asyncUpdateUI();
 
   // The PluginClickToPlay events are not fired when navigating using the
-  // BF cache. |event.persisted| is true when the page is loaded from the
+  // BF cache. |persisted| is true when the page is loaded from the
   // BF cache, so this code reshows the notification if necessary.
-  if (event.persisted)
+  if (persisted)
     gPluginHandler.reshowClickToPlayNotification();
 }
 
 function UpdateBackForwardCommands(aWebNavigation) {
   var backBroadcaster = document.getElementById("Browser:Back");
   var forwardBroadcaster = document.getElementById("Browser:Forward");
 
   // Avoid setting attributes on broadcasters if the value hasn't changed!
@@ -1394,17 +1394,17 @@ var gBrowserInit = {
     gFormSubmitObserver.init();
     SocialUI.init();
     AddonManager.addAddonListener(AddonsMgrListener);
     WebrtcIndicator.init();
 
     gBrowser.addEventListener("pageshow", function(event) {
       // Filter out events that are not about the document load we are interested in
       if (content && event.target == content.document)
-        setTimeout(pageShowEventHandlers, 0, event);
+        setTimeout(pageShowEventHandlers, 0, event.persisted);
     }, true);
 
     // Ensure login manager is up and running.
     Services.logins;
 
     if (mustLoadSidebar) {
       let sidebar = document.getElementById("sidebar");
       let sidebarBox = document.getElementById("sidebar-box");
--- a/content/base/public/nsIDocument.h
+++ b/content/base/public/nsIDocument.h
@@ -71,16 +71,17 @@ class nsRange;
 class nsScriptLoader;
 class nsSMILAnimationController;
 class nsStyleSet;
 class nsTextNode;
 class nsWindowSizes;
 class nsSmallVoidArray;
 class nsDOMCaretPosition;
 class nsViewportInfo;
+class nsDOMEvent;
 
 namespace mozilla {
 class ErrorResult;
 
 namespace css {
 class Loader;
 class ImageLoader;
 } // namespace css
@@ -1938,18 +1939,18 @@ public:
   already_AddRefed<mozilla::dom::Comment>
     CreateComment(const nsAString& aData, mozilla::ErrorResult& rv) const;
   already_AddRefed<mozilla::dom::ProcessingInstruction>
     CreateProcessingInstruction(const nsAString& target, const nsAString& data,
                                 mozilla::ErrorResult& rv) const;
   already_AddRefed<nsINode>
     ImportNode(nsINode& aNode, bool aDeep, mozilla::ErrorResult& rv) const;
   nsINode* AdoptNode(nsINode& aNode, mozilla::ErrorResult& rv);
-  already_AddRefed<nsIDOMEvent> CreateEvent(const nsAString& aEventType,
-                                            mozilla::ErrorResult& rv) const;
+  already_AddRefed<nsDOMEvent> CreateEvent(const nsAString& aEventType,
+                                           mozilla::ErrorResult& rv) const;
   already_AddRefed<nsRange> CreateRange(mozilla::ErrorResult& rv);
   already_AddRefed<mozilla::dom::NodeIterator>
     CreateNodeIterator(nsINode& aRoot, uint32_t aWhatToShow,
                        mozilla::dom::NodeFilter* aFilter,
                        mozilla::ErrorResult& rv) const;
   already_AddRefed<mozilla::dom::NodeIterator>
     CreateNodeIterator(nsINode& aRoot, uint32_t aWhatToShow,
                        const mozilla::dom::NodeFilterHolder& aFilter,
--- a/content/base/src/EventSource.cpp
+++ b/content/base/src/EventSource.cpp
@@ -790,17 +790,17 @@ EventSource::AnnounceConnection()
   mReadyState = OPEN;
 
   nsresult rv = CheckInnerWindowCorrectness();
   if (NS_FAILED(rv)) {
     return;
   }
 
   nsCOMPtr<nsIDOMEvent> event;
-  rv = NS_NewDOMEvent(getter_AddRefs(event), nullptr, nullptr);
+  rv = NS_NewDOMEvent(getter_AddRefs(event), this, nullptr, nullptr);
   if (NS_FAILED(rv)) {
     NS_WARNING("Failed to create the open event!!!");
     return;
   }
 
   // it doesn't bubble, and it isn't cancelable
   rv = event->InitEvent(NS_LITERAL_STRING("open"), false, false);
   if (NS_FAILED(rv)) {
@@ -860,17 +860,17 @@ EventSource::ReestablishConnection()
   }
 
   rv = CheckInnerWindowCorrectness();
   if (NS_FAILED(rv)) {
     return;
   }
 
   nsCOMPtr<nsIDOMEvent> event;
-  rv = NS_NewDOMEvent(getter_AddRefs(event), nullptr, nullptr);
+  rv = NS_NewDOMEvent(getter_AddRefs(event), this, nullptr, nullptr);
   if (NS_FAILED(rv)) {
     NS_WARNING("Failed to create the error event!!!");
     return;
   }
 
   // it doesn't bubble, and it isn't cancelable
   rv = event->InitEvent(NS_LITERAL_STRING("error"), false, false);
   if (NS_FAILED(rv)) {
@@ -1016,17 +1016,17 @@ EventSource::FailConnection()
   Close(); // it sets mReadyState to CLOSED
 
   rv = CheckInnerWindowCorrectness();
   if (NS_FAILED(rv)) {
     return;
   }
 
   nsCOMPtr<nsIDOMEvent> event;
-  rv = NS_NewDOMEvent(getter_AddRefs(event), nullptr, nullptr);
+  rv = NS_NewDOMEvent(getter_AddRefs(event), this, nullptr, nullptr);
   if (NS_FAILED(rv)) {
     NS_WARNING("Failed to create the error event!!!");
     return;
   }
 
   // it doesn't bubble, and it isn't cancelable
   rv = event->InitEvent(NS_LITERAL_STRING("error"), false, false);
   if (NS_FAILED(rv)) {
@@ -1246,17 +1246,17 @@ EventSource::DispatchAllMessageEvents()
 
       jsData = STRING_TO_JSVAL(jsString);
     }
 
     // create an event that uses the MessageEvent interface,
     // which does not bubble, is not cancelable, and has no default action
 
     nsCOMPtr<nsIDOMEvent> event;
-    rv = NS_NewDOMMessageEvent(getter_AddRefs(event), nullptr, nullptr);
+    rv = NS_NewDOMMessageEvent(getter_AddRefs(event), this, nullptr, nullptr);
     if (NS_FAILED(rv)) {
       NS_WARNING("Failed to create the message event!!!");
       return;
     }
 
     nsCOMPtr<nsIDOMMessageEvent> messageEvent = do_QueryInterface(event);
     rv = messageEvent->InitMessageEvent(message->mEventName,
                                         false, false,
--- a/content/base/src/FileIOObject.cpp
+++ b/content/base/src/FileIOObject.cpp
@@ -99,17 +99,17 @@ FileIOObject::DispatchError(nsresult rv,
   DispatchProgressEvent(NS_LITERAL_STRING(ERROR_STR));
   DispatchProgressEvent(finalEvent);
 }
 
 nsresult
 FileIOObject::DispatchProgressEvent(const nsAString& aType)
 {
   nsCOMPtr<nsIDOMEvent> event;
-  nsresult rv = NS_NewDOMProgressEvent(getter_AddRefs(event),
+  nsresult rv = NS_NewDOMProgressEvent(getter_AddRefs(event), this,
                                        nullptr, nullptr);
   NS_ENSURE_SUCCESS(rv, rv);
 
   event->SetTrusted(true);
   nsCOMPtr<nsIDOMProgressEvent> progress = do_QueryInterface(event);
   NS_ENSURE_TRUE(progress, NS_ERROR_UNEXPECTED);
 
   bool known;
--- a/content/base/src/WebSocket.cpp
+++ b/content/base/src/WebSocket.cpp
@@ -847,17 +847,17 @@ WebSocket::CreateAndDispatchSimpleEvent(
   NS_ABORT_IF_FALSE(NS_IsMainThread(), "Not running on main thread");
 
   nsresult rv = CheckInnerWindowCorrectness();
   if (NS_FAILED(rv)) {
     return NS_OK;
   }
 
   nsCOMPtr<nsIDOMEvent> event;
-  rv = NS_NewDOMEvent(getter_AddRefs(event), nullptr, nullptr);
+  rv = NS_NewDOMEvent(getter_AddRefs(event), this, nullptr, nullptr);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // it doesn't bubble, and it isn't cancelable
   rv = event->InitEvent(aName, false, false);
   NS_ENSURE_SUCCESS(rv, rv);
 
   event->SetTrusted(true);
 
@@ -911,17 +911,17 @@ WebSocket::CreateAndDispatchMessageEvent
       jsData = STRING_TO_JSVAL(jsString);
     }
   }
 
   // create an event that uses the MessageEvent interface,
   // which does not bubble, is not cancelable, and has no default action
 
   nsCOMPtr<nsIDOMEvent> event;
-  rv = NS_NewDOMMessageEvent(getter_AddRefs(event), nullptr, nullptr);
+  rv = NS_NewDOMMessageEvent(getter_AddRefs(event), this, nullptr, nullptr);
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsCOMPtr<nsIDOMMessageEvent> messageEvent = do_QueryInterface(event);
   rv = messageEvent->InitMessageEvent(NS_LITERAL_STRING("message"),
                                       false, false,
                                       jsData,
                                       mUTF16Origin,
                                       EmptyString(), nullptr);
@@ -943,17 +943,17 @@ WebSocket::CreateAndDispatchCloseEvent(b
   if (NS_FAILED(rv)) {
     return NS_OK;
   }
 
   // create an event that uses the CloseEvent interface,
   // which does not bubble, is not cancelable, and has no default action
 
   nsCOMPtr<nsIDOMEvent> event;
-  rv = NS_NewDOMCloseEvent(getter_AddRefs(event), nullptr, nullptr);
+  rv = NS_NewDOMCloseEvent(getter_AddRefs(event), this, nullptr, nullptr);
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsCOMPtr<nsIDOMCloseEvent> closeEvent = do_QueryInterface(event);
   rv = closeEvent->InitCloseEvent(NS_LITERAL_STRING("close"),
                                   false, false,
                                   aWasClean, aCode, aReason);
   NS_ENSURE_SUCCESS(rv, rv);
 
--- a/content/base/src/nsDOMAttribute.cpp
+++ b/content/base/src/nsDOMAttribute.cpp
@@ -63,18 +63,18 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(ns
   nsINode::Unlink(tmp);
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 DOMCI_NODE_DATA(Attr, nsDOMAttribute)
 
 // QueryInterface implementation for nsDOMAttribute
 NS_INTERFACE_TABLE_HEAD(nsDOMAttribute)
   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
-  NS_NODE_INTERFACE_TABLE4(nsDOMAttribute, nsIDOMAttr, nsIAttribute, nsIDOMNode,
-                           nsIDOMEventTarget)
+  NS_NODE_INTERFACE_TABLE5(nsDOMAttribute, nsIDOMAttr, nsIAttribute, nsIDOMNode,
+                           nsIDOMEventTarget, EventTarget)
   NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION(nsDOMAttribute)
   NS_INTERFACE_MAP_ENTRY_TEAROFF(nsISupportsWeakReference,
                                  new nsNodeSupportsWeakRefTearoff(this))
   NS_INTERFACE_MAP_ENTRY_TEAROFF(nsIDOMXPathNSResolver,
                                  new nsNode3Tearoff(this))
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(Attr)
 NS_INTERFACE_MAP_END
 
--- a/content/base/src/nsDOMDataChannel.cpp
+++ b/content/base/src/nsDOMDataChannel.cpp
@@ -418,17 +418,17 @@ nsDOMDataChannel::DoOnMessageAvailable(c
     NS_ConvertUTF8toUTF16 utf16data(aData);
     JSString* jsString = JS_NewUCStringCopyN(cx, utf16data.get(), utf16data.Length());
     NS_ENSURE_TRUE(jsString, NS_ERROR_FAILURE);
 
     jsData = STRING_TO_JSVAL(jsString);
   }
 
   nsCOMPtr<nsIDOMEvent> event;
-  rv = NS_NewDOMMessageEvent(getter_AddRefs(event), nullptr, nullptr);
+  rv = NS_NewDOMMessageEvent(getter_AddRefs(event), this, nullptr, nullptr);
   NS_ENSURE_SUCCESS(rv,rv);
 
   nsCOMPtr<nsIDOMMessageEvent> messageEvent = do_QueryInterface(event);
   rv = messageEvent->InitMessageEvent(NS_LITERAL_STRING("message"),
                                       false, false,
                                       jsData, mOrigin, EmptyString(),
                                       nullptr);
   NS_ENSURE_SUCCESS(rv,rv);
@@ -464,17 +464,17 @@ nsDOMDataChannel::OnSimpleEvent(nsISuppo
   MOZ_ASSERT(NS_IsMainThread());
 
   nsresult rv = CheckInnerWindowCorrectness();
   if (NS_FAILED(rv)) {
     return NS_OK;
   }
 
   nsCOMPtr<nsIDOMEvent> event;
-  rv = NS_NewDOMEvent(getter_AddRefs(event), nullptr, nullptr);
+  rv = NS_NewDOMEvent(getter_AddRefs(event), this, nullptr, nullptr);
   NS_ENSURE_SUCCESS(rv,rv);
 
   rv = event->InitEvent(aName, false, false);
   NS_ENSURE_SUCCESS(rv,rv);
 
   event->SetTrusted(true);
 
   return DispatchDOMEvent(nullptr, event, nullptr, nullptr);
--- a/content/base/src/nsDocument.cpp
+++ b/content/base/src/nsDocument.cpp
@@ -191,16 +191,17 @@
 #include "mozilla/dom/WebComponentsBinding.h"
 #include "mozilla/dom/HTMLBodyElement.h"
 #include "mozilla/dom/NodeFilterBinding.h"
 #include "mozilla/dom/UndoManager.h"
 #include "nsFrame.h"
 #include "nsDOMCaretPosition.h"
 #include "nsIDOMHTMLTextAreaElement.h"
 #include "nsViewportInfo.h"
+#include "nsDOMEvent.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 typedef nsTArray<Link*> LinkArray;
 
 #ifdef PR_LOGGING
 static PRLogModuleInfo* gDocumentLeakPRLog;
@@ -6886,33 +6887,35 @@ NS_IMETHODIMP
 nsDocument::CreateEvent(const nsAString& aEventType, nsIDOMEvent** aReturn)
 {
   NS_ENSURE_ARG_POINTER(aReturn);
   ErrorResult rv;
   *aReturn = nsIDocument::CreateEvent(aEventType, rv).get();
   return rv.ErrorCode();
 }
 
-already_AddRefed<nsIDOMEvent>
+already_AddRefed<nsDOMEvent>
 nsIDocument::CreateEvent(const nsAString& aEventType, ErrorResult& rv) const
 {
   nsIPresShell *shell = GetShell();
 
   nsPresContext *presContext = nullptr;
 
   if (shell) {
     // Retrieve the context
     presContext = shell->GetPresContext();
   }
 
   // Create event even without presContext.
   nsCOMPtr<nsIDOMEvent> ev;
-  rv = nsEventDispatcher::CreateEvent(presContext, nullptr,
-                                      aEventType, getter_AddRefs(ev));
-  return ev.forget();
+  rv =
+    nsEventDispatcher::CreateEvent(const_cast<nsIDocument*>(this),
+                                   presContext, nullptr, aEventType,
+                                   getter_AddRefs(ev));
+  return ev ? ev.forget().get()->InternalDOMEvent() : nullptr;
 }
 
 void
 nsDocument::FlushPendingNotifications(mozFlushType aType)
 {
   nsDocumentOnStack dos(this);
 
   // We need to flush the sink for non-HTML documents (because the XML
--- a/content/base/src/nsINode.cpp
+++ b/content/base/src/nsINode.cpp
@@ -101,16 +101,17 @@
 #include "xpcpublic.h"
 #include "nsCSSRuleProcessor.h"
 #include "nsCSSParser.h"
 #include "HTMLLegendElement.h"
 #include "nsWrapperCacheInlines.h"
 #include "WrapperFactory.h"
 #include "DocumentType.h"
 #include <algorithm>
+#include "nsDOMEvent.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 nsINode::nsSlots::~nsSlots()
 {
   if (mChildNodes) {
     mChildNodes->DropReference();
@@ -2414,8 +2415,17 @@ nsresult
 nsINode::GetAttributes(nsIDOMNamedNodeMap** aAttributes)
 {
   if (!IsElement()) {
     *aAttributes = nullptr;
     return NS_OK;
   }
   return CallQueryInterface(GetAttributes(), aAttributes);
 }
+
+bool
+EventTarget::DispatchEvent(nsDOMEvent& aEvent,
+                           ErrorResult& aRv)
+{
+  bool result = false;
+  aRv = DispatchEvent(&aEvent, &result);
+  return result;
+}
--- a/content/base/src/nsXMLHttpRequest.cpp
+++ b/content/base/src/nsXMLHttpRequest.cpp
@@ -1400,17 +1400,17 @@ nsXMLHttpRequest::GetLoadGroup() const
   }
 
   return nullptr;
 }
 
 nsresult
 nsXMLHttpRequest::CreateReadystatechangeEvent(nsIDOMEvent** aDOMEvent)
 {
-  nsresult rv = nsEventDispatcher::CreateEvent(nullptr, nullptr,
+  nsresult rv = nsEventDispatcher::CreateEvent(this, nullptr, nullptr,
                                                NS_LITERAL_STRING("Events"),
                                                aDOMEvent);
   if (NS_FAILED(rv)) {
     return rv;
   }
 
   (*aDOMEvent)->InitEvent(NS_LITERAL_STRING(READYSTATE_STR),
                           false, false);
@@ -1436,17 +1436,17 @@ nsXMLHttpRequest::DispatchProgressEvent(
   }
 
   bool dispatchLoadend = aType.EqualsLiteral(LOAD_STR) ||
                          aType.EqualsLiteral(ERROR_STR) ||
                          aType.EqualsLiteral(TIMEOUT_STR) ||
                          aType.EqualsLiteral(ABORT_STR);
 
   nsCOMPtr<nsIDOMEvent> event;
-  nsresult rv = NS_NewDOMProgressEvent(getter_AddRefs(event),
+  nsresult rv = NS_NewDOMProgressEvent(getter_AddRefs(event), this,
                                        nullptr, nullptr);
   if (NS_FAILED(rv)) {
     return;
   }
 
   nsCOMPtr<nsIDOMProgressEvent> progress = do_QueryInterface(event);
   if (!progress) {
     return;
--- a/content/base/src/nsXMLHttpRequest.h
+++ b/content/base/src/nsXMLHttpRequest.h
@@ -441,17 +441,17 @@ public:
     return mChannel;
   }
 
   // We need a GetInterface callable from JS for chrome JS
   JS::Value GetInterface(JSContext* aCx, nsIJSID* aIID, ErrorResult& aRv);
 
   // This creates a trusted readystatechange event, which is not cancelable and
   // doesn't bubble.
-  static nsresult CreateReadystatechangeEvent(nsIDOMEvent** aDOMEvent);
+  nsresult CreateReadystatechangeEvent(nsIDOMEvent** aDOMEvent);
   void DispatchProgressEvent(nsDOMEventTargetHelper* aTarget,
                              const nsAString& aType,
                              bool aLengthComputable,
                              uint64_t aLoaded, uint64_t aTotal);
 
   // Dispatch the "progress" event on the XHR or XHR.upload object if we've
   // received data since the last "progress" event. Also dispatches
   // "uploadprogress" as needed.
--- a/content/events/public/EventTarget.h
+++ b/content/events/public/EventTarget.h
@@ -7,16 +7,17 @@
 #define mozilla_dom_EventTarget_h_
 
 #include "nsIDOMEventTarget.h"
 #include "nsWrapperCache.h"
 #include "nsIDOMEventListener.h"
 #include "mozilla/ErrorResult.h"
 #include "mozilla/dom/Nullable.h"
 #include "nsIDOMEvent.h"
+class nsDOMEvent;
 
 namespace mozilla {
 namespace dom {
 
 // IID for the dom::EventTarget interface
 #define NS_EVENTTARGET_IID \
 { 0x0a5aed21, 0x0bab, 0x48b3, \
  { 0xbe, 0x4b, 0xd4, 0xf9, 0xd4, 0xea, 0xc7, 0xdb } }
@@ -41,22 +42,17 @@ public:
                            aWantsUntrusted.IsNull() ? 1 : 2);
   }
   void RemoveEventListener(const nsAString& aType,
                            nsIDOMEventListener* aCallback,
                            bool aCapture, mozilla::ErrorResult& aRv)
   {
     aRv = RemoveEventListener(aType, aCallback, aCapture);
   }
-  bool DispatchEvent(nsIDOMEvent* aEvent, mozilla::ErrorResult& aRv)
-  {
-    bool result = false;
-    aRv = DispatchEvent(aEvent, &result);
-    return result;
-  }
+  bool DispatchEvent(nsDOMEvent& aEvent, ErrorResult& aRv);
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(EventTarget, NS_EVENTTARGET_IID)
 
 } // namespace dom
 } // namespace mozilla
 
 #endif // mozilla_dom_EventTarget_h_
--- a/content/events/public/nsEventDispatcher.h
+++ b/content/events/public/nsEventDispatcher.h
@@ -11,16 +11,21 @@
 #include "nsEvent.h"
 
 class nsPresContext;
 class nsIDOMEvent;
 class nsIScriptGlobalObject;
 class nsIDOMEventTarget;
 class nsEventTargetChainItem;
 template<class E> class nsCOMArray;
+namespace mozilla {
+namespace dom {
+class EventTarget;
+}
+}
 
 /**
  * About event dispatching:
  * When either nsEventDispatcher::Dispatch or
  * nsEventDispatcher::DispatchDOMEvent is called an event target chain is
  * created. nsEventDispatcher creates the chain by calling PreHandleEvent 
  * on each event target and the creation continues until either the mCanHandle
  * member of the nsEventChainPreVisitor object is false or the mParentTarget
@@ -236,17 +241,18 @@ public:
   static nsresult DispatchDOMEvent(nsISupports* aTarget,
                                    nsEvent* aEvent, nsIDOMEvent* aDOMEvent,
                                    nsPresContext* aPresContext,
                                    nsEventStatus* aEventStatus);
 
   /**
    * Creates a DOM Event.
    */
-  static nsresult CreateEvent(nsPresContext* aPresContext,
+  static nsresult CreateEvent(mozilla::dom::EventTarget* aOwner,
+                              nsPresContext* aPresContext,
                               nsEvent* aEvent,
                               const nsAString& aEventType,
                               nsIDOMEvent** aDOMEvent);
 
 };
 
 #endif
 #endif
--- a/content/events/src/DOMWheelEvent.cpp
+++ b/content/events/src/DOMWheelEvent.cpp
@@ -11,20 +11,22 @@
 #include "DictionaryHelpers.h"
 #include "nsDOMClassInfoID.h"
 
 DOMCI_DATA(WheelEvent, mozilla::dom::DOMWheelEvent)
 
 namespace mozilla {
 namespace dom {
 
-DOMWheelEvent::DOMWheelEvent(nsPresContext* aPresContext,
+DOMWheelEvent::DOMWheelEvent(EventTarget* aOwner,
+                             nsPresContext* aPresContext,
                              widget::WheelEvent* aWheelEvent)
-  : nsDOMMouseEvent(aPresContext, aWheelEvent ? aWheelEvent :
-                                    new widget::WheelEvent(false, 0, nullptr))
+  : nsDOMMouseEvent(aOwner, aPresContext,
+                    aWheelEvent ? aWheelEvent :
+                                  new widget::WheelEvent(false, 0, nullptr))
 {
   if (aWheelEvent) {
     mEventIsInternal = false;
   } else {
     mEventIsInternal = true;
     mEvent->time = PR_Now();
     mEvent->refPoint.x = mEvent->refPoint.y = 0;
     static_cast<widget::WheelEvent*>(mEvent)->inputSource =
@@ -163,14 +165,15 @@ DOMWheelEvent::InitFromCtor(const nsAStr
 }
 
 } // namespace dom
 } // namespace mozilla
 
 using namespace mozilla;
 
 nsresult NS_NewDOMWheelEvent(nsIDOMEvent** aInstancePtrResult,
+                             mozilla::dom::EventTarget* aOwner,
                              nsPresContext* aPresContext,
                              widget::WheelEvent *aEvent)
 {
-  dom::DOMWheelEvent* it = new dom::DOMWheelEvent(aPresContext, aEvent);
+  dom::DOMWheelEvent* it = new dom::DOMWheelEvent(aOwner, aPresContext, aEvent);
   return CallQueryInterface(it, aInstancePtrResult);
 }
--- a/content/events/src/DOMWheelEvent.h
+++ b/content/events/src/DOMWheelEvent.h
@@ -12,17 +12,18 @@
 
 namespace mozilla {
 namespace dom {
 
 class DOMWheelEvent : public nsDOMMouseEvent,
                       public nsIDOMWheelEvent
 {
 public:
-  DOMWheelEvent(nsPresContext* aPresContext,
+  DOMWheelEvent(mozilla::dom::EventTarget* aOwner,
+                nsPresContext* aPresContext,
                 widget::WheelEvent* aWheelEvent);
   virtual ~DOMWheelEvent();
 
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIDOMWheelEvent Interface
   NS_DECL_NSIDOMWHEELEVENT
   
--- a/content/events/src/nsAsyncDOMEvent.cpp
+++ b/content/events/src/nsAsyncDOMEvent.cpp
@@ -8,29 +8,26 @@
 #include "nsIDOMEventTarget.h"
 #include "nsContentUtils.h"
 #include "nsEventDispatcher.h"
 #include "nsGUIEvent.h"
 
 nsAsyncDOMEvent::nsAsyncDOMEvent(nsINode *aEventNode, nsEvent &aEvent)
   : mEventNode(aEventNode), mDispatchChromeOnly(false)
 {
-  nsEventDispatcher::CreateEvent(nullptr, &aEvent, EmptyString(),
+  MOZ_ASSERT(mEventNode);
+  nsEventDispatcher::CreateEvent(aEventNode, nullptr, &aEvent, EmptyString(),
                                  getter_AddRefs(mEvent));
   NS_ASSERTION(mEvent, "Should never fail to create an event");
   mEvent->DuplicatePrivateData();
   mEvent->SetTrusted(aEvent.mFlags.mIsTrusted);
 }
 
 NS_IMETHODIMP nsAsyncDOMEvent::Run()
 {
-  if (!mEventNode) {
-    return NS_OK;
-  }
-
   if (mEvent) {
     NS_ASSERTION(!mDispatchChromeOnly, "Can't do that");
     nsCOMPtr<nsIDOMEventTarget> target = do_QueryInterface(mEventNode);
     bool defaultActionEnabled; // This is not used because the caller is async
     target->DispatchEvent(mEvent, &defaultActionEnabled);
   } else {
     nsIDocument* doc = mEventNode->OwnerDoc();
     if (mDispatchChromeOnly) {
--- a/content/events/src/nsDOMAnimationEvent.cpp
+++ b/content/events/src/nsDOMAnimationEvent.cpp
@@ -4,22 +4,23 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsDOMAnimationEvent.h"
 #include "nsGUIEvent.h"
 #include "nsDOMClassInfoID.h"
 #include "nsIClassInfo.h"
 #include "nsIXPCScriptable.h"
 
-nsDOMAnimationEvent::nsDOMAnimationEvent(nsPresContext *aPresContext,
+nsDOMAnimationEvent::nsDOMAnimationEvent(mozilla::dom::EventTarget* aOwner,
+                                         nsPresContext *aPresContext,
                                          nsAnimationEvent *aEvent)
-  : nsDOMEvent(aPresContext, aEvent ? aEvent
-                                    : new nsAnimationEvent(false, 0,
-                                                           EmptyString(),
-                                                           0.0))
+  : nsDOMEvent(aOwner, aPresContext,
+               aEvent ? aEvent : new nsAnimationEvent(false, 0,
+                                                      EmptyString(),
+                                                      0.0))
 {
   if (aEvent) {
     mEventIsInternal = false;
   }
   else {
     mEventIsInternal = true;
     mEvent->time = PR_Now();
   }
@@ -70,14 +71,16 @@ nsDOMAnimationEvent::InitAnimationEvent(
   AnimationEvent()->animationName = animationNameArg;
   AnimationEvent()->elapsedTime = elapsedTimeArg;
 
   return NS_OK;
 }
 
 nsresult
 NS_NewDOMAnimationEvent(nsIDOMEvent **aInstancePtrResult,
+                        mozilla::dom::EventTarget* aOwner,
                         nsPresContext *aPresContext,
                         nsAnimationEvent *aEvent)
 {
-  nsDOMAnimationEvent *it = new nsDOMAnimationEvent(aPresContext, aEvent);
+  nsDOMAnimationEvent* it =
+    new nsDOMAnimationEvent(aOwner, aPresContext, aEvent);
   return CallQueryInterface(it, aInstancePtrResult);
 }
--- a/content/events/src/nsDOMAnimationEvent.h
+++ b/content/events/src/nsDOMAnimationEvent.h
@@ -10,17 +10,18 @@
 #include "nsString.h"
 
 class nsAnimationEvent;
 
 class nsDOMAnimationEvent : public nsDOMEvent,
                             public nsIDOMAnimationEvent
 {
 public:
-  nsDOMAnimationEvent(nsPresContext *aPresContext,
+  nsDOMAnimationEvent(mozilla::dom::EventTarget* aOwner,
+                      nsPresContext *aPresContext,
                       nsAnimationEvent *aEvent);
   ~nsDOMAnimationEvent();
 
   NS_DECL_ISUPPORTS_INHERITED
   NS_FORWARD_TO_NSDOMEVENT
   NS_DECL_NSIDOMANIMATIONEVENT
 
 private:
--- a/content/events/src/nsDOMBeforeUnloadEvent.cpp
+++ b/content/events/src/nsDOMBeforeUnloadEvent.cpp
@@ -26,19 +26,20 @@ nsDOMBeforeUnloadEvent::SetReturnValue(c
 NS_IMETHODIMP
 nsDOMBeforeUnloadEvent::GetReturnValue(nsAString& aReturnValue)
 {
   aReturnValue = mText;
   return NS_OK;  // Don't throw an exception
 }
 
 nsresult NS_NewDOMBeforeUnloadEvent(nsIDOMEvent** aInstancePtrResult,
+                                    mozilla::dom::EventTarget* aOwner,
                                     nsPresContext* aPresContext,
                                     nsEvent *aEvent) 
 {
   nsDOMBeforeUnloadEvent* it =
-    new nsDOMBeforeUnloadEvent(aPresContext, aEvent);
+    new nsDOMBeforeUnloadEvent(aOwner, aPresContext, aEvent);
   if (!it) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
   return CallQueryInterface(it, aInstancePtrResult);
 }
--- a/content/events/src/nsDOMBeforeUnloadEvent.h
+++ b/content/events/src/nsDOMBeforeUnloadEvent.h
@@ -8,18 +8,19 @@
 
 #include "nsIDOMBeforeUnloadEvent.h"
 #include "nsDOMEvent.h"
 
 class nsDOMBeforeUnloadEvent : public nsDOMEvent,
                                public nsIDOMBeforeUnloadEvent
 {
 public:
-  nsDOMBeforeUnloadEvent(nsPresContext* aPresContext, nsEvent* aEvent)
-  : nsDOMEvent(aPresContext, aEvent) {}
+  nsDOMBeforeUnloadEvent(mozilla::dom::EventTarget* aOwner,
+                         nsPresContext* aPresContext, nsEvent* aEvent)
+  : nsDOMEvent(aOwner, aPresContext, aEvent) {}
 
   NS_DECL_ISUPPORTS_INHERITED
 
   // Forward to nsDOMEvent
   NS_FORWARD_TO_NSDOMEVENT
 
   // nsIDOMBeforeUnloadEvent Interface
   NS_DECL_NSIDOMBEFOREUNLOADEVENT
--- a/content/events/src/nsDOMCommandEvent.cpp
+++ b/content/events/src/nsDOMCommandEvent.cpp
@@ -1,19 +1,20 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsDOMClassInfoID.h"
 #include "nsDOMCommandEvent.h"
 
-nsDOMCommandEvent::nsDOMCommandEvent(nsPresContext* aPresContext,
+nsDOMCommandEvent::nsDOMCommandEvent(mozilla::dom::EventTarget* aOwner,
+                                     nsPresContext* aPresContext,
                                      nsCommandEvent* aEvent)
-  : nsDOMEvent(aPresContext, aEvent ? aEvent :
+  : nsDOMEvent(aOwner, aPresContext, aEvent ? aEvent :
                new nsCommandEvent(false, nullptr, nullptr, nullptr))
 {
   mEvent->time = PR_Now();
   if (aEvent) {
     mEventIsInternal = false;
   } else {
     mEventIsInternal = true;
   }
@@ -58,18 +59,19 @@ nsDOMCommandEvent::InitCommandEvent(cons
   nsresult rv = nsDOMEvent::InitEvent(aTypeArg, aCanBubbleArg, aCancelableArg);
   NS_ENSURE_SUCCESS(rv, rv);
 
   static_cast<nsCommandEvent*>(mEvent)->command = do_GetAtom(aCommand);
   return NS_OK;
 }
 
 nsresult NS_NewDOMCommandEvent(nsIDOMEvent** aInstancePtrResult,
+                               mozilla::dom::EventTarget* aOwner,
                                nsPresContext* aPresContext,
                                nsCommandEvent* aEvent)
 {
-  nsDOMCommandEvent* it = new nsDOMCommandEvent(aPresContext, aEvent);
+  nsDOMCommandEvent* it = new nsDOMCommandEvent(aOwner, aPresContext, aEvent);
   if (nullptr == it) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
   return CallQueryInterface(it, aInstancePtrResult);
 }
--- a/content/events/src/nsDOMCommandEvent.h
+++ b/content/events/src/nsDOMCommandEvent.h
@@ -8,17 +8,18 @@
 
 #include "nsIDOMCommandEvent.h"
 #include "nsDOMEvent.h"
 
 class nsDOMCommandEvent : public nsDOMEvent,
                           public nsIDOMCommandEvent
 {
 public:
-  nsDOMCommandEvent(nsPresContext* aPresContext,
+  nsDOMCommandEvent(mozilla::dom::EventTarget* aOwner,
+                    nsPresContext* aPresContext,
                     nsCommandEvent* aEvent);
   virtual ~nsDOMCommandEvent();
 
   NS_DECL_ISUPPORTS_INHERITED
 
   NS_DECL_NSIDOMCOMMANDEVENT
 
   // Forward to base class
--- a/content/events/src/nsDOMCompositionEvent.cpp
+++ b/content/events/src/nsDOMCompositionEvent.cpp
@@ -2,19 +2,20 @@
 /* vim: set ts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsDOMCompositionEvent.h"
 #include "nsDOMClassInfoID.h"
 
-nsDOMCompositionEvent::nsDOMCompositionEvent(nsPresContext* aPresContext,
+nsDOMCompositionEvent::nsDOMCompositionEvent(mozilla::dom::EventTarget* aOwner,
+                                             nsPresContext* aPresContext,
                                              nsCompositionEvent* aEvent)
-  : nsDOMUIEvent(aPresContext, aEvent ? aEvent :
+  : nsDOMUIEvent(aOwner, aPresContext, aEvent ? aEvent :
                  new nsCompositionEvent(false, 0, nullptr))
 {
   NS_ASSERTION(mEvent->eventStructType == NS_COMPOSITION_EVENT,
                "event type mismatch");
 
   if (aEvent) {
     mEventIsInternal = false;
   } else {
@@ -77,15 +78,16 @@ nsDOMCompositionEvent::InitCompositionEv
 
   mData = aData;
   mLocale = aLocale;
   return NS_OK;
 }
 
 nsresult
 NS_NewDOMCompositionEvent(nsIDOMEvent** aInstancePtrResult,
+                          mozilla::dom::EventTarget* aOwner,
                           nsPresContext* aPresContext,
                           nsCompositionEvent *aEvent)
 {
   nsDOMCompositionEvent* event =
-    new nsDOMCompositionEvent(aPresContext, aEvent);
+    new nsDOMCompositionEvent(aOwner, aPresContext, aEvent);
   return CallQueryInterface(event, aInstancePtrResult);
 }
--- a/content/events/src/nsDOMCompositionEvent.h
+++ b/content/events/src/nsDOMCompositionEvent.h
@@ -9,17 +9,18 @@
 
 #include "nsDOMUIEvent.h"
 #include "nsIDOMCompositionEvent.h"
 
 class nsDOMCompositionEvent : public nsDOMUIEvent,
                               public nsIDOMCompositionEvent
 {
 public:
-  nsDOMCompositionEvent(nsPresContext* aPresContext,
+  nsDOMCompositionEvent(mozilla::dom::EventTarget* aOwner,
+                        nsPresContext* aPresContext,
                         nsCompositionEvent* aEvent);
   virtual ~nsDOMCompositionEvent();
 
   NS_DECL_ISUPPORTS_INHERITED
   NS_FORWARD_TO_NSDOMUIEVENT
   NS_DECL_NSIDOMCOMPOSITIONEVENT
 
 protected:
--- a/content/events/src/nsDOMDataContainerEvent.cpp
+++ b/content/events/src/nsDOMDataContainerEvent.cpp
@@ -1,19 +1,21 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsDOMDataContainerEvent.h"
 #include "nsDOMClassInfoID.h"
 
-nsDOMDataContainerEvent::nsDOMDataContainerEvent(nsPresContext *aPresContext,
-                                                 nsEvent *aEvent)
-  : nsDOMEvent(aPresContext, aEvent)
+nsDOMDataContainerEvent::nsDOMDataContainerEvent(
+                                             mozilla::dom::EventTarget* aOwner,
+                                             nsPresContext* aPresContext,
+                                             nsEvent* aEvent)
+  : nsDOMEvent(aOwner, aPresContext, aEvent)
 {
   mData.Init();
 }
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsDOMDataContainerEvent,
                                                 nsDOMEvent)
   if (tmp->mData.IsInitialized())
     tmp->mData.Clear();
@@ -54,21 +56,22 @@ nsDOMDataContainerEvent::SetData(const n
   NS_ENSURE_STATE(!mEvent->mFlags.mIsBeingDispatched);
   NS_ENSURE_STATE(mData.IsInitialized());
   mData.Put(aKey, aData);
   return NS_OK;
 }
 
 nsresult
 NS_NewDOMDataContainerEvent(nsIDOMEvent** aInstancePtrResult,
-                   nsPresContext* aPresContext,
-                   nsEvent* aEvent)
+                            mozilla::dom::EventTarget* aOwner,
+                            nsPresContext* aPresContext,
+                            nsEvent* aEvent)
 {
   nsDOMDataContainerEvent* it =
-    new nsDOMDataContainerEvent(aPresContext, aEvent);
+    new nsDOMDataContainerEvent(aOwner, aPresContext, aEvent);
   NS_ENSURE_TRUE(it, NS_ERROR_OUT_OF_MEMORY);
 
   return CallQueryInterface(it, aInstancePtrResult);
 }
 
 PLDHashOperator
 nsDOMDataContainerEvent::TraverseEntry(const nsAString& aKey,
                                        nsIVariant *aDataItem,
--- a/content/events/src/nsDOMDataContainerEvent.h
+++ b/content/events/src/nsDOMDataContainerEvent.h
@@ -9,17 +9,18 @@
 #include "nsIDOMDataContainerEvent.h"
 #include "nsDOMEvent.h"
 #include "nsInterfaceHashtable.h"
 
 class nsDOMDataContainerEvent : public nsDOMEvent,
                                 public nsIDOMDataContainerEvent
 {
 public:
-  nsDOMDataContainerEvent(nsPresContext* aPresContext, nsEvent* aEvent);
+  nsDOMDataContainerEvent(mozilla::dom::EventTarget* aOwner,
+                          nsPresContext* aPresContext, nsEvent* aEvent);
 
   NS_DECL_ISUPPORTS_INHERITED
 
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsDOMDataContainerEvent, nsDOMEvent)
 
   NS_FORWARD_TO_NSDOMEVENT
 
   NS_DECL_NSIDOMDATACONTAINEREVENT
--- a/content/events/src/nsDOMDeviceMotionEvent.cpp
+++ b/content/events/src/nsDOMDeviceMotionEvent.cpp
@@ -18,17 +18,16 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_ADDREF_INHERITED(nsDOMDeviceMotionEvent, nsDOMEvent)
 NS_IMPL_RELEASE_INHERITED(nsDOMDeviceMotionEvent, nsDOMEvent)
 
 DOMCI_DATA(DeviceMotionEvent, nsDOMDeviceMotionEvent)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsDOMDeviceMotionEvent)
-  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMDeviceMotionEvent)
   NS_INTERFACE_MAP_ENTRY(nsIDOMDeviceMotionEvent)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(DeviceMotionEvent)
 NS_INTERFACE_MAP_END_INHERITING(nsDOMEvent)
 
 NS_IMETHODIMP
 nsDOMDeviceMotionEvent::InitDeviceMotionEvent(const nsAString & aEventTypeArg,
                                               bool aCanBubbleArg,
                                               bool aCancelableArg,
@@ -81,22 +80,24 @@ nsDOMDeviceMotionEvent::GetInterval(doub
 
   *aInterval = mInterval;
   return NS_OK;
 }
 
 
 nsresult
 NS_NewDOMDeviceMotionEvent(nsIDOMEvent** aInstancePtrResult,
+                           mozilla::dom::EventTarget* aOwner,
                            nsPresContext* aPresContext,
                            nsEvent *aEvent) 
 {
   NS_ENSURE_ARG_POINTER(aInstancePtrResult);
 
-  nsDOMDeviceMotionEvent* it = new nsDOMDeviceMotionEvent(aPresContext, aEvent);
+  nsDOMDeviceMotionEvent* it =
+    new nsDOMDeviceMotionEvent(aOwner, aPresContext, aEvent);
   return CallQueryInterface(it, aInstancePtrResult);
 }
 
 
 DOMCI_DATA(DeviceAcceleration, nsDOMDeviceAcceleration)
 
 NS_INTERFACE_MAP_BEGIN(nsDOMDeviceAcceleration)
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMDeviceAcceleration)
--- a/content/events/src/nsDOMDeviceMotionEvent.h
+++ b/content/events/src/nsDOMDeviceMotionEvent.h
@@ -39,18 +39,19 @@ protected:
   double mX, mY, mZ;
 };
 
 class nsDOMDeviceMotionEvent MOZ_FINAL : public nsDOMEvent,
                                          public nsIDOMDeviceMotionEvent
 {
 public:
 
-  nsDOMDeviceMotionEvent(nsPresContext* aPresContext, nsEvent* aEvent)
-  : nsDOMEvent(aPresContext, aEvent)
+  nsDOMDeviceMotionEvent(mozilla::dom::EventTarget* aOwner,
+                         nsPresContext* aPresContext, nsEvent* aEvent)
+  : nsDOMEvent(aOwner, aPresContext, aEvent)
   {}
 
   NS_DECL_ISUPPORTS_INHERITED
 
   // Forward to nsDOMEvent
   NS_FORWARD_TO_NSDOMEVENT
 
   // nsIDOMDeviceMotionEvent Interface
--- a/content/events/src/nsDOMDragEvent.cpp
+++ b/content/events/src/nsDOMDragEvent.cpp
@@ -6,19 +6,20 @@
 #include "nsDOMDragEvent.h"
 #include "nsIServiceManager.h"
 #include "nsGUIEvent.h"
 #include "nsContentUtils.h"
 #include "nsDOMDataTransfer.h"
 #include "nsIDragService.h"
 #include "nsDOMClassInfoID.h"
 
-nsDOMDragEvent::nsDOMDragEvent(nsPresContext* aPresContext,
+nsDOMDragEvent::nsDOMDragEvent(mozilla::dom::EventTarget* aOwner,
+                               nsPresContext* aPresContext,
                                nsInputEvent* aEvent)
-  : nsDOMMouseEvent(aPresContext, aEvent ? aEvent :
+  : nsDOMMouseEvent(aOwner, aPresContext, aEvent ? aEvent :
                     new nsDragEvent(false, 0, nullptr))
 {
   if (aEvent) {
     mEventIsInternal = false;
   }
   else {
     mEventIsInternal = true;
     mEvent->time = PR_Now();
@@ -92,14 +93,15 @@ nsDOMDragEvent::GetDataTransfer(nsIDOMDa
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   NS_IF_ADDREF(*aDataTransfer = dragEvent->dataTransfer);
   return NS_OK;
 }
 
 nsresult NS_NewDOMDragEvent(nsIDOMEvent** aInstancePtrResult,
+                            mozilla::dom::EventTarget* aOwner,
                             nsPresContext* aPresContext,
                             nsDragEvent *aEvent) 
 {
-  nsDOMDragEvent* event = new nsDOMDragEvent(aPresContext, aEvent);
+  nsDOMDragEvent* event = new nsDOMDragEvent(aOwner, aPresContext, aEvent);
   return CallQueryInterface(event, aInstancePtrResult);
 }
--- a/content/events/src/nsDOMDragEvent.h
+++ b/content/events/src/nsDOMDragEvent.h
@@ -10,23 +10,25 @@
 #include "nsDOMMouseEvent.h"
 
 class nsEvent;
 
 class nsDOMDragEvent : public nsDOMMouseEvent,
                        public nsIDOMDragEvent
 {
 public:
-  nsDOMDragEvent(nsPresContext* aPresContext, nsInputEvent* aEvent);
+  nsDOMDragEvent(mozilla::dom::EventTarget* aOwner,
+                 nsPresContext* aPresContext, nsInputEvent* aEvent);
   virtual ~nsDOMDragEvent();
 
   NS_DECL_ISUPPORTS_INHERITED
 
   NS_DECL_NSIDOMDRAGEVENT
   
   NS_FORWARD_TO_NSDOMMOUSEEVENT
 };
 
 nsresult NS_NewDOMDragEvent(nsIDOMEvent** aInstancePtrResult,
+                            mozilla::dom::EventTarget* aOwner,
                             nsPresContext* aPresContext,
                             nsDragEvent* aEvent);
 
 #endif // nsDOMDragEvent_h__
--- a/content/events/src/nsDOMEvent.cpp
+++ b/content/events/src/nsDOMEvent.cpp
@@ -27,24 +27,29 @@
 #include "nsIScriptSecurityManager.h"
 #include "nsIScriptError.h"
 #include "mozilla/Preferences.h"
 #include "nsJSUtils.h"
 #include "DictionaryHelpers.h"
 #include "nsLayoutUtils.h"
 #include "nsIScrollableFrame.h"
 #include "nsDOMClassInfoID.h"
+#include "nsDOMEventTargetHelper.h"
+#include "nsPIWindowRoot.h"
 
 using namespace mozilla;
 
 static char *sPopupAllowedEvents;
 
 
-nsDOMEvent::nsDOMEvent(nsPresContext* aPresContext, nsEvent* aEvent)
+nsDOMEvent::nsDOMEvent(mozilla::dom::EventTarget* aOwner,
+                       nsPresContext* aPresContext, nsEvent* aEvent)
 {
+  SetOwner(aOwner);
+
   mPrivateDataDuplicated = false;
 
   if (aEvent) {
     mEvent = aEvent;
     mEventIsInternal = false;
   }
   else {
     mEventIsInternal = true;
@@ -101,25 +106,30 @@ nsDOMEvent::~nsDOMEvent()
   if (mEventIsInternal && mEvent) {
     delete mEvent;
   }
 }
 
 DOMCI_DATA(Event, nsDOMEvent)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsDOMEvent)
+  NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMEvent)
   NS_INTERFACE_MAP_ENTRY(nsIDOMEvent)
   NS_INTERFACE_MAP_ENTRY(nsIJSNativeInitializer)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(Event)
 NS_INTERFACE_MAP_END
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsDOMEvent)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsDOMEvent)
 
+NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsDOMEvent)
+  NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
+NS_IMPL_CYCLE_COLLECTION_TRACE_END
+
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsDOMEvent)
   if (tmp->mEventIsInternal) {
     tmp->mEvent->target = nullptr;
     tmp->mEvent->currentTarget = nullptr;
     tmp->mEvent->originalTarget = nullptr;
     switch (tmp->mEvent->eventStructType) {
       case NS_MOUSE_EVENT:
       case NS_MOUSE_SCROLL_EVENT:
@@ -135,16 +145,18 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(ns
         static_cast<nsMutationEvent*>(tmp->mEvent)->mRelatedNode = nullptr;
         break;
       default:
         break;
     }
   }
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mPresContext);
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mExplicitOriginalTarget);
+  NS_IMPL_CYCLE_COLLECTION_UNLINK(mOwner);
+  NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsDOMEvent)
   if (tmp->mEventIsInternal) {
     NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mEvent->target)
     NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mEvent->currentTarget)
     NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mEvent->originalTarget)
     switch (tmp->mEvent->eventStructType) {
@@ -170,16 +182,18 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(
           static_cast<nsMutationEvent*>(tmp->mEvent)->mRelatedNode);
         break;
       default:
         break;
     }
   }
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPresContext)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mExplicitOriginalTarget)
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOwner)
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 // nsIDOMEventInterface
 NS_METHOD nsDOMEvent::GetType(nsAString& aType)
 {
   if (!mCachedType.IsEmpty()) {
     aType = mCachedType;
     return NS_OK;
@@ -284,16 +298,20 @@ nsDOMEvent::Initialize(nsISupports* aOwn
       trusted = nsContentUtils::IsChromeDoc(d);
       nsIPresShell* s = d->GetShell();
       if (s) {
         InitPresContextData(s->GetPresContext());
       }
     }
   }
 
+  if (!mOwner) {
+    mOwner = w;
+  }
+
   JSAutoRequest ar(aCx);
   JSString* jsstr = JS_ValueToString(aCx, aArgv[0]);
   if (!jsstr) {
     return NS_ERROR_DOM_SYNTAX_ERR;
   }
 
   JS::Anchor<JSString*> deleteProtector(jsstr);
 
@@ -312,16 +330,43 @@ nsDOMEvent::InitFromCtor(const nsAString
                          JSContext* aCx, jsval* aVal)
 {
   mozilla::idl::EventInit d;
   nsresult rv = d.Init(aCx, aVal);
   NS_ENSURE_SUCCESS(rv, rv);
   return InitEvent(aType, d.bubbles, d.cancelable);
 }
 
+//static
+already_AddRefed<nsDOMEvent>
+nsDOMEvent::Constructor(const mozilla::dom::GlobalObject& aGlobal,
+                        const nsAString& aType,
+                        const mozilla::dom::EventInit& aParam,
+                        mozilla::ErrorResult& aRv)
+{
+  nsCOMPtr<mozilla::dom::EventTarget> t = do_QueryInterface(aGlobal.Get());
+  nsRefPtr<nsDOMEvent> e = nsDOMEvent::CreateEvent(t, nullptr, nullptr);
+
+  bool trusted = false;
+  nsCOMPtr<nsPIDOMWindow> w = do_QueryInterface(t);
+  if (w) {
+    nsCOMPtr<nsIDocument> d = do_QueryInterface(w->GetExtantDocument());
+    if (d) {
+      trusted = nsContentUtils::IsChromeDoc(d);
+      nsIPresShell* s = d->GetShell();
+      if (s) {
+        e->InitPresContextData(s->GetPresContext());
+      }
+    }
+  }
+  aRv = e->InitEvent(aType, aParam.mBubbles, aParam.mCancelable);
+  e->SetTrusted(trusted);
+  return e.forget();
+}
+
 NS_IMETHODIMP
 nsDOMEvent::GetEventPhase(uint16_t* aEventPhase)
 {
   // Note, remember to check that this works also
   // if or when Bug 235441 is fixed.
   if ((mEvent->currentTarget &&
        mEvent->currentTarget == mEvent->target) ||
        mEvent->mFlags.InTargetPhase()) {
@@ -815,16 +860,22 @@ nsDOMEvent::IsDispatchStopped()
 }
 
 NS_IMETHODIMP_(nsEvent*)
 nsDOMEvent::GetInternalNSEvent()
 {
   return mEvent;
 }
 
+NS_IMETHODIMP_(nsDOMEvent*)
+nsDOMEvent::InternalDOMEvent()
+{
+  return this;
+}
+
 // return true if eventName is contained within events, delimited by
 // spaces
 static bool
 PopupAllowedForEvent(const char *eventName)
 {
   if (!sPopupAllowedEvents) {
     nsDOMEvent::PopupAllowedEventsChanged();
 
@@ -1194,20 +1245,54 @@ nsDOMEvent::Deserialize(const IPC::Messa
 
   nsresult rv = InitEvent(type, bubbles, cancelable);
   NS_ENSURE_SUCCESS(rv, false);
   SetTrusted(trusted);
 
   return true;
 }
 
+NS_IMETHODIMP_(void)
+nsDOMEvent::SetOwner(mozilla::dom::EventTarget* aOwner)
+{
+  mOwner = nullptr;
+
+  if (!aOwner) {
+    return;
+  }
+
+  nsCOMPtr<nsINode> n = do_QueryInterface(aOwner);
+  if (n) {
+    mOwner = do_QueryInterface(n->OwnerDoc()->GetScopeObject());
+    return;
+  }
+
+  nsCOMPtr<nsPIDOMWindow> w = do_QueryInterface(aOwner);
+  if (w) {
+    if (w->IsOuterWindow()) {
+      mOwner = w->GetCurrentInnerWindow();
+    } else {
+      mOwner.swap(w);
+    }
+    return;
+  }
+
+  nsCOMPtr<nsDOMEventTargetHelper> eth = do_QueryInterface(aOwner);
+  if (eth) {
+    mOwner = eth->GetOwner();
+    return;
+  }
+
+#ifdef DEBUG
+  nsCOMPtr<nsPIWindowRoot> root = do_QueryInterface(aOwner);
+  MOZ_ASSERT(root, "Unexpected EventTarget!");
+#endif
+}
 
 nsresult NS_NewDOMEvent(nsIDOMEvent** aInstancePtrResult,
+                        mozilla::dom::EventTarget* aOwner,
                         nsPresContext* aPresContext,
                         nsEvent *aEvent) 
 {
-  nsDOMEvent* it = new nsDOMEvent(aPresContext, aEvent);
-  if (nullptr == it) {
-    return NS_ERROR_OUT_OF_MEMORY;
-  }
-
+  nsRefPtr<nsDOMEvent> it =
+    nsDOMEvent::CreateEvent(aOwner, aPresContext, aEvent);
   return CallQueryInterface(it, aInstancePtrResult);
 }
--- a/content/events/src/nsDOMEvent.h
+++ b/content/events/src/nsDOMEvent.h
@@ -11,32 +11,83 @@
 #include "nsCOMPtr.h"
 #include "nsIDOMEventTarget.h"
 #include "nsPIDOMWindow.h"
 #include "nsPoint.h"
 #include "nsGUIEvent.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsAutoPtr.h"
 #include "nsIJSNativeInitializer.h"
+#include "mozilla/dom/EventTarget.h"
+#include "mozilla/dom/EventBinding.h"
+#include "mozilla/dom/BindingUtils.h"
+#include "nsIScriptGlobalObject.h"
 
 class nsIContent;
 class nsPresContext;
 struct JSContext;
 class JSObject;
- 
+
 class nsDOMEvent : public nsIDOMEvent,
-                   public nsIJSNativeInitializer
+                   public nsIJSNativeInitializer,
+                   public nsWrapperCache
 {
+protected:
+  nsDOMEvent(mozilla::dom::EventTarget* aOwner, nsPresContext* aPresContext,
+             nsEvent* aEvent);
+  virtual ~nsDOMEvent();
 public:
+  void GetParentObject(nsIScriptGlobalObject** aParentObject)
+  {
+    if (mOwner) {
+      CallQueryInterface(mOwner, aParentObject);
+    } else {
+      *aParentObject = nullptr;
+    }
+  }
 
-  nsDOMEvent(nsPresContext* aPresContext, nsEvent* aEvent);
-  virtual ~nsDOMEvent();
+  static nsDOMEvent* FromSupports(nsISupports* aSupports)
+  {
+    nsIDOMEvent* event =
+      static_cast<nsIDOMEvent*>(aSupports);
+#ifdef DEBUG
+    {
+      nsCOMPtr<nsIDOMEvent> target_qi =
+        do_QueryInterface(aSupports);
+
+      // If this assertion fires the QI implementation for the object in
+      // question doesn't use the nsIDOMEvent pointer as the
+      // nsISupports pointer. That must be fixed, or we'll crash...
+      MOZ_ASSERT(target_qi == event, "Uh, fix QI!");
+    }
+#endif
+    return static_cast<nsDOMEvent*>(event);
+  }
+
+  static already_AddRefed<nsDOMEvent> CreateEvent(mozilla::dom::EventTarget* aOwner,
+                                                  nsPresContext* aPresContext,
+                                                  nsEvent* aEvent)
+  {
+    nsRefPtr<nsDOMEvent> e = new nsDOMEvent(aOwner, aPresContext, aEvent);
+    e->SetIsDOMBinding();
+    return e.forget();
+  }
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
-  NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsDOMEvent, nsIDOMEvent)
+  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsDOMEvent, nsIDOMEvent)
+
+  nsISupports* GetParentObject()
+  {
+    return mOwner;
+  }
+
+  virtual JSObject* WrapObject(JSContext* aCx, JSObject* aScope, bool* aTriedToWrap)
+  {
+    return mozilla::dom::EventBinding::Wrap(aCx, aScope, this, aTriedToWrap);
+  }
 
   // nsIDOMEvent Interface
   NS_DECL_NSIDOMEVENT
 
   // nsIJSNativeInitializer
   NS_IMETHOD Initialize(nsISupports* aOwner, JSContext* aCx, JSObject* aObj,
                         uint32_t aArgc, jsval* aArgv);
 
@@ -58,25 +109,131 @@ public:
                                     nsIntPoint aDefaultPoint);
   static nsIntPoint GetPageCoords(nsPresContext* aPresContext,
                                   nsEvent* aEvent,
                                   nsIntPoint aPoint,
                                   nsIntPoint aDefaultPoint);
   static nsIntPoint GetScreenCoords(nsPresContext* aPresContext,
                                     nsEvent* aEvent,
                                     nsIntPoint aPoint);
+
+  static already_AddRefed<nsDOMEvent> Constructor(const mozilla::dom::GlobalObject& aGlobal,
+                                                  const nsAString& aType,
+                                                  const mozilla::dom::EventInit& aParam,
+                                                  mozilla::ErrorResult& aRv);
+
+  // Implemented as xpidl method
+  // void GetType(nsString& aRetval) {}
+
+  already_AddRefed<mozilla::dom::EventTarget> GetTarget()
+  {
+    nsCOMPtr<nsIDOMEventTarget> t;
+    GetTarget(getter_AddRefs(t));
+    nsCOMPtr<mozilla::dom::EventTarget> et = do_QueryInterface(t);
+    return et.forget();
+  }
+
+  already_AddRefed<mozilla::dom::EventTarget> GetCurrentTarget()
+  {
+    nsCOMPtr<nsIDOMEventTarget> t;
+    GetCurrentTarget(getter_AddRefs(t));
+    nsCOMPtr<mozilla::dom::EventTarget> et = do_QueryInterface(t);
+    return et.forget();
+  }
+
+  uint16_t EventPhase()
+  {
+    uint16_t p;
+    GetEventPhase(&p);
+    return p;
+  }
+
+  // xpidl implementation
+  // void StopPropagation();
+
+  // xpidl implementation
+  // void StopImmediatePropagation();
+
+  bool Bubbles()
+  {
+    bool b;
+    GetBubbles(&b);
+    return b;
+  }
+
+  bool Cancelable()
+  {
+    bool c;
+    GetCancelable(&c);
+    return c;
+  }
+
+  // xpidl implementation
+  // void PreventDefault();
+
+  bool DefaultPrevented()
+  {
+    bool d;
+    GetDefaultPrevented(&d);
+    return d;
+  }
+
+  bool IsTrusted()
+  {
+    bool i;
+    GetIsTrusted(&i);
+    return i;
+  }
+
+  uint64_t TimeStamp()
+  {
+    uint64_t t;
+    GetTimeStamp(&t);
+    return t;
+  }
+
+  void InitEvent(const nsAString& aType, bool aBubbles, bool aCancelable,
+                 mozilla::ErrorResult& aRv)
+  {
+    aRv = InitEvent(aType, aBubbles, aCancelable);
+  }
+
+  already_AddRefed<mozilla::dom::EventTarget> GetOriginalTarget()
+  {
+    nsCOMPtr<nsIDOMEventTarget> t;
+    GetOriginalTarget(getter_AddRefs(t));
+    nsCOMPtr<mozilla::dom::EventTarget> et = do_QueryInterface(t);
+    return et.forget();
+  }
+
+  already_AddRefed<mozilla::dom::EventTarget> GetExplicitOriginalTarget()
+  {
+    nsCOMPtr<nsIDOMEventTarget> t;
+    GetExplicitOriginalTarget(getter_AddRefs(t));
+    nsCOMPtr<mozilla::dom::EventTarget> et = do_QueryInterface(t);
+    return et.forget();
+  }
+
+  bool GetPreventDefault()
+  {
+    bool d;
+    GetDefaultPrevented(&d);
+    return d;
+  }
+
 protected:
 
   // Internal helper functions
   void SetEventType(const nsAString& aEventTypeArg);
   already_AddRefed<nsIContent> GetTargetFromFrame();
 
   nsEvent*                    mEvent;
   nsRefPtr<nsPresContext>     mPresContext;
   nsCOMPtr<nsIDOMEventTarget> mExplicitOriginalTarget;
+  nsCOMPtr<nsPIDOMWindow>     mOwner; // nsPIDOMWindow for now.
   nsString                    mCachedType;
   bool                        mEventIsInternal;
   bool                        mPrivateDataDuplicated;
 };
 
 #define NS_FORWARD_TO_NSDOMEVENT \
   NS_FORWARD_NSIDOMEVENT(nsDOMEvent::)
 
@@ -97,14 +254,28 @@ protected:
   NS_IMETHOD GetExplicitOriginalTarget(nsIDOMEventTarget** aExplicitOriginalTarget) { return _to GetExplicitOriginalTarget(aExplicitOriginalTarget); } \
   NS_IMETHOD PreventBubble() { return _to PreventBubble(); } \
   NS_IMETHOD PreventCapture() { return _to PreventCapture(); } \
   NS_IMETHOD GetPreventDefault(bool* aRetval) { return _to GetPreventDefault(aRetval); } \
   NS_IMETHOD GetIsTrusted(bool* aIsTrusted) { return _to GetIsTrusted(aIsTrusted); } \
   NS_IMETHOD SetTarget(nsIDOMEventTarget *aTarget) { return _to SetTarget(aTarget); } \
   NS_IMETHOD_(bool) IsDispatchStopped(void) { return _to IsDispatchStopped(); } \
   NS_IMETHOD_(nsEvent *) GetInternalNSEvent(void) { return _to GetInternalNSEvent(); } \
-  NS_IMETHOD_(void) SetTrusted(bool aTrusted) { _to SetTrusted(aTrusted); }
+  NS_IMETHOD_(void) SetTrusted(bool aTrusted) { _to SetTrusted(aTrusted); } \
+  NS_IMETHOD_(void) SetOwner(mozilla::dom::EventTarget* aOwner) { _to SetOwner(aOwner); } \
+  NS_IMETHOD_(nsDOMEvent *) InternalDOMEvent(void) { return _to InternalDOMEvent(); }
 
 #define NS_FORWARD_TO_NSDOMEVENT_NO_SERIALIZATION_NO_DUPLICATION \
   NS_FORWARD_NSIDOMEVENT_NO_SERIALIZATION_NO_DUPLICATION(nsDOMEvent::)
 
+inline nsISupports*
+ToSupports(nsDOMEvent* e)
+{
+  return static_cast<nsIDOMEvent*>(e);
+}
+
+inline nsISupports*
+ToCanonicalSupports(nsDOMEvent* e)
+{
+  return static_cast<nsIDOMEvent*>(e);
+}
+
 #endif // nsDOMEvent_h__
--- a/content/events/src/nsDOMEventTargetHelper.cpp
+++ b/content/events/src/nsDOMEventTargetHelper.cpp
@@ -62,16 +62,17 @@ NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_B
   return tmp->IsBlack();
 NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_END
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsDOMEventTargetHelper)
   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
   NS_INTERFACE_MAP_ENTRY(nsISupports)
   NS_INTERFACE_MAP_ENTRY(nsIDOMEventTarget)
   NS_INTERFACE_MAP_ENTRY(mozilla::dom::EventTarget)
+  NS_INTERFACE_MAP_ENTRY(nsDOMEventTargetHelper)
 NS_INTERFACE_MAP_END
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsDOMEventTargetHelper)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsDOMEventTargetHelper)
 
 NS_IMPL_DOMTARGET_DEFAULTS(nsDOMEventTargetHelper)
 
 nsDOMEventTargetHelper::~nsDOMEventTargetHelper()
@@ -205,17 +206,18 @@ nsDOMEventTargetHelper::DispatchEvent(ns
 
   *aRetVal = (status != nsEventStatus_eConsumeNoDefault);
   return rv;
 }
 
 nsresult
 nsDOMEventTargetHelper::DispatchTrustedEvent(const nsAString& aEventName)
 {
-  nsRefPtr<nsDOMEvent> event = new nsDOMEvent(nullptr, nullptr);
+  nsCOMPtr<nsIDOMEvent> event;
+  NS_NewDOMEvent(getter_AddRefs(event), this, nullptr, nullptr);
   nsresult rv = event->InitEvent(aEventName, false, false);
   NS_ENSURE_SUCCESS(rv, rv);
 
   return DispatchTrustedEvent(event);
 }
 
 nsresult
 nsDOMEventTargetHelper::DispatchTrustedEvent(nsIDOMEvent* event)
--- a/content/events/src/nsDOMEventTargetHelper.h
+++ b/content/events/src/nsDOMEventTargetHelper.h
@@ -13,26 +13,32 @@
 #include "nsIScriptGlobalObject.h"
 #include "nsEventListenerManager.h"
 #include "nsIScriptContext.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/dom/EventTarget.h"
 
 class nsDOMEvent;
 
+#define NS_DOMEVENTTARGETHELPER_IID \
+{ 0xda0e6d40, 0xc17b, 0x4937, \
+  { 0x8e, 0xa2, 0x99, 0xca, 0x1c, 0x81, 0xea, 0xbe } }
+
 class nsDOMEventTargetHelper : public mozilla::dom::EventTarget
 {
 public:
   nsDOMEventTargetHelper() : mOwner(nullptr), mHasOrHasHadOwner(false) {}
   virtual ~nsDOMEventTargetHelper();
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS(nsDOMEventTargetHelper)
 
   NS_DECL_NSIDOMEVENTTARGET
 
+  NS_DECLARE_STATIC_IID_ACCESSOR(NS_DOMEVENTTARGETHELPER_IID)
+
   void GetParentObject(nsIScriptGlobalObject **aParentObject)
   {
     if (mOwner) {
       CallQueryInterface(mOwner, aParentObject);
     }
     else {
       *aParentObject = nullptr;
     }
@@ -107,16 +113,19 @@ protected:
   // Make |event| trusted and dispatch |aEvent| to |this|.
   nsresult DispatchTrustedEvent(nsIDOMEvent* aEvent);
 private:
   // These may be null (native callers or xpcshell).
   nsPIDOMWindow*             mOwner; // Inner window.
   bool                       mHasOrHasHadOwner;
 };
 
+NS_DEFINE_STATIC_IID_ACCESSOR(nsDOMEventTargetHelper,
+                              NS_DOMEVENTTARGETHELPER_IID)
+
 // XPIDL event handlers
 #define NS_IMPL_EVENT_HANDLER(_class, _event)                                 \
     NS_IMETHODIMP _class::GetOn##_event(JSContext* aCx, JS::Value* aValue)    \
     {                                                                         \
       GetEventHandler(nsGkAtoms::on##_event, aCx, aValue);                    \
       return NS_OK;                                                           \
     }                                                                         \
     NS_IMETHODIMP _class::SetOn##_event(JSContext* aCx,                       \
--- a/content/events/src/nsDOMKeyboardEvent.cpp
+++ b/content/events/src/nsDOMKeyboardEvent.cpp
@@ -1,19 +1,20 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsDOMKeyboardEvent.h"
 #include "nsDOMClassInfoID.h"
 
-nsDOMKeyboardEvent::nsDOMKeyboardEvent(nsPresContext* aPresContext,
+nsDOMKeyboardEvent::nsDOMKeyboardEvent(mozilla::dom::EventTarget* aOwner,
+                                       nsPresContext* aPresContext,
                                        nsKeyEvent* aEvent)
-  : nsDOMUIEvent(aPresContext, aEvent ? aEvent :
+  : nsDOMUIEvent(aOwner, aPresContext, aEvent ? aEvent :
                  new nsKeyEvent(false, 0, nullptr))
 {
   NS_ASSERTION(mEvent->eventStructType == NS_KEY_EVENT, "event type mismatch");
 
   if (aEvent) {
     mEventIsInternal = false;
   }
   else {
@@ -173,14 +174,15 @@ nsDOMKeyboardEvent::InitKeyEvent(const n
   keyEvent->InitBasicModifiers(aCtrlKey, aAltKey, aShiftKey, aMetaKey);
   keyEvent->keyCode = aKeyCode;
   keyEvent->charCode = aCharCode;
 
   return NS_OK;
 }
 
 nsresult NS_NewDOMKeyboardEvent(nsIDOMEvent** aInstancePtrResult,
+                                mozilla::dom::EventTarget* aOwner,
                                 nsPresContext* aPresContext,
                                 nsKeyEvent *aEvent)
 {
-  nsDOMKeyboardEvent* it = new nsDOMKeyboardEvent(aPresContext, aEvent);
+  nsDOMKeyboardEvent* it = new nsDOMKeyboardEvent(aOwner, aPresContext, aEvent);
   return CallQueryInterface(it, aInstancePtrResult);
 }
--- a/content/events/src/nsDOMKeyboardEvent.h
+++ b/content/events/src/nsDOMKeyboardEvent.h
@@ -8,17 +8,18 @@
 
 #include "nsIDOMKeyEvent.h"
 #include "nsDOMUIEvent.h"
 
 class nsDOMKeyboardEvent : public nsDOMUIEvent,
                            public nsIDOMKeyEvent
 {
 public:
-  nsDOMKeyboardEvent(nsPresContext* aPresContext, nsKeyEvent* aEvent);
+  nsDOMKeyboardEvent(mozilla::dom::EventTarget* aOwner,
+                     nsPresContext* aPresContext, nsKeyEvent* aEvent);
   virtual ~nsDOMKeyboardEvent();
 
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIDOMKeyEvent Interface
   NS_DECL_NSIDOMKEYEVENT
 
   // Forward to base class
--- a/content/events/src/nsDOMMessageEvent.cpp
+++ b/content/events/src/nsDOMMessageEvent.cpp
@@ -11,37 +11,37 @@
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsDOMMessageEvent, nsDOMEvent)
   if (tmp->mDataRooted) {
     tmp->UnrootData();
   }
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mSource)
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsDOMMessageEvent, nsDOMEvent)
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSource)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
-NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsDOMMessageEvent)
+NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(nsDOMMessageEvent, nsDOMEvent)
   NS_IMPL_CYCLE_COLLECTION_TRACE_JSVAL_MEMBER_CALLBACK(mData)
 NS_IMPL_CYCLE_COLLECTION_TRACE_END
 
 DOMCI_DATA(MessageEvent, nsDOMMessageEvent)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsDOMMessageEvent)
   NS_INTERFACE_MAP_ENTRY(nsIDOMMessageEvent)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(MessageEvent)
 NS_INTERFACE_MAP_END_INHERITING(nsDOMEvent)
 
 NS_IMPL_ADDREF_INHERITED(nsDOMMessageEvent, nsDOMEvent)
 NS_IMPL_RELEASE_INHERITED(nsDOMMessageEvent, nsDOMEvent)
 
-nsDOMMessageEvent::nsDOMMessageEvent(nsPresContext* aPresContext,
+nsDOMMessageEvent::nsDOMMessageEvent(mozilla::dom::EventTarget* aOwner,
+                                     nsPresContext* aPresContext,
                                      nsEvent* aEvent)
-  : nsDOMEvent(aPresContext, aEvent),
+  : nsDOMEvent(aOwner, aPresContext, aEvent),
     mData(JSVAL_VOID),
     mDataRooted(false)
 {
 }
 
 nsDOMMessageEvent::~nsDOMMessageEvent()
 {
   if (mDataRooted)
@@ -117,15 +117,16 @@ nsDOMMessageEvent::InitMessageEvent(cons
   mLastEventId = aLastEventId;
   mSource = aSource;
 
   return NS_OK;
 }
 
 nsresult
 NS_NewDOMMessageEvent(nsIDOMEvent** aInstancePtrResult,
+                      mozilla::dom::EventTarget* aOwner,
                       nsPresContext* aPresContext,
                       nsEvent* aEvent) 
 {
-  nsDOMMessageEvent* it = new nsDOMMessageEvent(aPresContext, aEvent);
+  nsDOMMessageEvent* it = new nsDOMMessageEvent(aOwner, aPresContext, aEvent);
 
   return CallQueryInterface(it, aInstancePtrResult);
 }
--- a/content/events/src/nsDOMMessageEvent.h
+++ b/content/events/src/nsDOMMessageEvent.h
@@ -17,17 +17,18 @@
  *
  * See http://www.whatwg.org/specs/web-apps/current-work/#messageevent for
  * further details.
  */
 class nsDOMMessageEvent : public nsDOMEvent,
                           public nsIDOMMessageEvent
 {
 public:
-  nsDOMMessageEvent(nsPresContext* aPresContext, nsEvent* aEvent);
+  nsDOMMessageEvent(mozilla::dom::EventTarget* aOwner,
+                    nsPresContext* aPresContext, nsEvent* aEvent);
   ~nsDOMMessageEvent();
                      
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(nsDOMMessageEvent,
                                                          nsDOMEvent)
 
   NS_DECL_NSIDOMMESSAGEEVENT
 
--- a/content/events/src/nsDOMMouseEvent.cpp
+++ b/content/events/src/nsDOMMouseEvent.cpp
@@ -7,19 +7,20 @@
 #include "nsGUIEvent.h"
 #include "nsIContent.h"
 #include "nsContentUtils.h"
 #include "DictionaryHelpers.h"
 #include "nsDOMClassInfoID.h"
 
 using namespace mozilla;
 
-nsDOMMouseEvent::nsDOMMouseEvent(nsPresContext* aPresContext,
+nsDOMMouseEvent::nsDOMMouseEvent(mozilla::dom::EventTarget* aOwner,
+                                 nsPresContext* aPresContext,
                                  nsInputEvent* aEvent)
-  : nsDOMUIEvent(aPresContext, aEvent ? aEvent :
+  : nsDOMUIEvent(aOwner, aPresContext, aEvent ? aEvent :
                  new nsMouseEvent(false, 0, nullptr,
                                   nsMouseEvent::eReal))
 {
   // There's no way to make this class' ctor allocate an nsMouseScrollEvent.
   // It's not that important, though, since a scroll event is not a real
   // DOM event.
   
   if (aEvent) {
@@ -398,14 +399,15 @@ NS_IMETHODIMP
 nsDOMMouseEvent::GetMozInputSource(uint16_t* aInputSource)
 {
   NS_ENSURE_ARG_POINTER(aInputSource);
   *aInputSource = static_cast<nsMouseEvent_base*>(mEvent)->inputSource;
   return NS_OK;
 }
 
 nsresult NS_NewDOMMouseEvent(nsIDOMEvent** aInstancePtrResult,
+                             mozilla::dom::EventTarget* aOwner,
                              nsPresContext* aPresContext,
-                             nsInputEvent *aEvent) 
+                             nsInputEvent *aEvent)
 {
-  nsDOMMouseEvent* it = new nsDOMMouseEvent(aPresContext, aEvent);
+  nsDOMMouseEvent* it = new nsDOMMouseEvent(aOwner, aPresContext, aEvent);
   return CallQueryInterface(it, aInstancePtrResult);
 }
--- a/content/events/src/nsDOMMouseEvent.h
+++ b/content/events/src/nsDOMMouseEvent.h
@@ -10,17 +10,18 @@
 #include "nsDOMUIEvent.h"
 
 class nsEvent;
 
 class nsDOMMouseEvent : public nsDOMUIEvent,
                         public nsIDOMMouseEvent
 {
 public:
-  nsDOMMouseEvent(nsPresContext* aPresContext, nsInputEvent* aEvent);
+  nsDOMMouseEvent(mozilla::dom::EventTarget* aOwner,
+                  nsPresContext* aPresContext, nsInputEvent* aEvent);
   virtual ~nsDOMMouseEvent();
 
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIDOMMouseEvent Interface
   NS_DECL_NSIDOMMOUSEEVENT
 
   // Forward to base class
--- a/content/events/src/nsDOMMouseScrollEvent.cpp
+++ b/content/events/src/nsDOMMouseScrollEvent.cpp
@@ -1,20 +1,21 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsDOMMouseScrollEvent.h"
 #include "nsDOMClassInfoID.h"
 
-nsDOMMouseScrollEvent::nsDOMMouseScrollEvent(nsPresContext* aPresContext,
+nsDOMMouseScrollEvent::nsDOMMouseScrollEvent(mozilla::dom::EventTarget* aOwner,
+                                             nsPresContext* aPresContext,
                                              nsInputEvent* aEvent)
-  : nsDOMMouseEvent(aPresContext, aEvent ? aEvent :
-                                  new nsMouseScrollEvent(false, 0, nullptr))
+  : nsDOMMouseEvent(aOwner, aPresContext,
+                    aEvent ? aEvent : new nsMouseScrollEvent(false, 0, nullptr))
 {
   if (aEvent) {
     mEventIsInternal = false;
   } else {
     mEventIsInternal = true;
     mEvent->time = PR_Now();
     mEvent->refPoint.x = mEvent->refPoint.y = 0;
     static_cast<nsMouseEvent*>(mEvent)->inputSource = nsIDOMMouseEvent::MOZ_SOURCE_UNKNOWN;
@@ -84,14 +85,16 @@ nsDOMMouseScrollEvent::GetAxis(int32_t* 
                  static_cast<int32_t>(VERTICAL_AXIS);
   } else {
     *aResult = 0;
   }
   return NS_OK;
 }
 
 nsresult NS_NewDOMMouseScrollEvent(nsIDOMEvent** aInstancePtrResult,
+                                   mozilla::dom::EventTarget* aOwner,
                                    nsPresContext* aPresContext,
                                    nsInputEvent *aEvent) 
 {
-  nsDOMMouseScrollEvent* it = new nsDOMMouseScrollEvent(aPresContext, aEvent);
+  nsDOMMouseScrollEvent* it =
+    new nsDOMMouseScrollEvent(aOwner, aPresContext, aEvent);
   return CallQueryInterface(it, aInstancePtrResult);
 }
--- a/content/events/src/nsDOMMouseScrollEvent.h
+++ b/content/events/src/nsDOMMouseScrollEvent.h
@@ -8,17 +8,18 @@
 
 #include "nsIDOMMouseScrollEvent.h"
 #include "nsDOMMouseEvent.h"
 
 class nsDOMMouseScrollEvent : public nsDOMMouseEvent,
                               public nsIDOMMouseScrollEvent
 {
 public:
-  nsDOMMouseScrollEvent(nsPresContext* aPresContext, nsInputEvent* aEvent);
+  nsDOMMouseScrollEvent(mozilla::dom::EventTarget* aOwner,
+                        nsPresContext* aPresContext, nsInputEvent* aEvent);
   virtual ~nsDOMMouseScrollEvent();
 
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIDOMMouseScrollEvent Interface
   NS_DECL_NSIDOMMOUSESCROLLEVENT
   
   // Forward to base class
--- a/content/events/src/nsDOMMutationEvent.cpp
+++ b/content/events/src/nsDOMMutationEvent.cpp
@@ -6,20 +6,21 @@
 #include "nsCOMPtr.h"
 #include "nsDOMClassInfoID.h"
 #include "nsDOMMutationEvent.h"
 #include "nsMutationEvent.h"
 
 
 class nsPresContext;
 
-nsDOMMutationEvent::nsDOMMutationEvent(nsPresContext* aPresContext,
+nsDOMMutationEvent::nsDOMMutationEvent(mozilla::dom::EventTarget* aOwner,
+                                       nsPresContext* aPresContext,
                                        nsMutationEvent* aEvent)
-  : nsDOMEvent(aPresContext, aEvent ? aEvent :
-               new nsMutationEvent(false, 0))
+  : nsDOMEvent(aOwner, aPresContext,
+               aEvent ? aEvent : new nsMutationEvent(false, 0))
 {
   mEventIsInternal = (aEvent == nullptr);
 }
 
 nsDOMMutationEvent::~nsDOMMutationEvent()
 {
   if (mEventIsInternal) {
     nsMutationEvent* mutation = static_cast<nsMutationEvent*>(mEvent);
@@ -101,18 +102,19 @@ nsDOMMutationEvent::InitMutationEvent(co
     mutation->mAttrName = do_GetAtom(aAttrNameArg);
   }
   mutation->mAttrChange = aAttrChangeArg;
     
   return NS_OK;
 }
 
 nsresult NS_NewDOMMutationEvent(nsIDOMEvent** aInstancePtrResult,
+                                mozilla::dom::EventTarget* aOwner,
                                 nsPresContext* aPresContext,
                                 nsMutationEvent *aEvent) 
 {
-  nsDOMMutationEvent* it = new nsDOMMutationEvent(aPresContext, aEvent);
+  nsDOMMutationEvent* it = new nsDOMMutationEvent(aOwner, aPresContext, aEvent);
   if (nullptr == it) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
   return CallQueryInterface(it, aInstancePtrResult);
 }
--- a/content/events/src/nsDOMMutationEvent.h
+++ b/content/events/src/nsDOMMutationEvent.h
@@ -8,17 +8,18 @@
 
 #include "nsIDOMMutationEvent.h"
 #include "nsDOMEvent.h"
 
 class nsDOMMutationEvent : public nsDOMEvent,
                            public nsIDOMMutationEvent
 {
 public:
-  nsDOMMutationEvent(nsPresContext* aPresContext, nsMutationEvent* aEvent);
+  nsDOMMutationEvent(mozilla::dom::EventTarget* aOwner,
+                     nsPresContext* aPresContext, nsMutationEvent* aEvent);
 
   virtual ~nsDOMMutationEvent();
                      
   NS_DECL_ISUPPORTS_INHERITED
 
   NS_DECL_NSIDOMMUTATIONEVENT
 
   // Forward to base class
--- a/content/events/src/nsDOMNotifyAudioAvailableEvent.cpp
+++ b/content/events/src/nsDOMNotifyAudioAvailableEvent.cpp
@@ -5,23 +5,24 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsError.h"
 #include "nsDOMNotifyAudioAvailableEvent.h"
 #include "nsDOMClassInfoID.h" // DOMCI_DATA, NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO
 #include "nsContentUtils.h" // NS_DROP_JS_OBJECTS
 #include "jsfriendapi.h"
 
-nsDOMNotifyAudioAvailableEvent::nsDOMNotifyAudioAvailableEvent(nsPresContext* aPresContext,
+nsDOMNotifyAudioAvailableEvent::nsDOMNotifyAudioAvailableEvent(mozilla::dom::EventTarget* aOwner,
+                                                               nsPresContext* aPresContext,
                                                                nsEvent* aEvent,
                                                                uint32_t aEventType,
                                                                float* aFrameBuffer,
                                                                uint32_t aFrameBufferLength,
                                                                float aTime)
-  : nsDOMEvent(aPresContext, aEvent),
+  : nsDOMEvent(aOwner, aPresContext, aEvent),
     mFrameBuffer(aFrameBuffer),
     mFrameBufferLength(aFrameBufferLength),
     mTime(aTime),
     mCachedArray(nullptr),
     mAllowAudioData(false)
 {
   MOZ_COUNT_CTOR(nsDOMNotifyAudioAvailableEvent);
   if (mEvent) {
@@ -37,20 +38,19 @@ NS_IMPL_RELEASE_INHERITED(nsDOMNotifyAud
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsDOMNotifyAudioAvailableEvent, nsDOMEvent)
   if (tmp->mCachedArray) {
     tmp->mCachedArray = nullptr;
     NS_DROP_JS_OBJECTS(tmp, nsDOMNotifyAudioAvailableEvent);
   }
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsDOMNotifyAudioAvailableEvent, nsDOMEvent)
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
-NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsDOMNotifyAudioAvailableEvent)
+NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(nsDOMNotifyAudioAvailableEvent, nsDOMEvent)
   NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mCachedArray)
 NS_IMPL_CYCLE_COLLECTION_TRACE_END
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsDOMNotifyAudioAvailableEvent)
   NS_INTERFACE_MAP_ENTRY(nsIDOMNotifyAudioAvailableEvent)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(NotifyAudioAvailableEvent)
 NS_INTERFACE_MAP_END_INHERITING(nsDOMEvent)
 
@@ -116,20 +116,21 @@ nsDOMNotifyAudioAvailableEvent::InitAudi
   mFrameBuffer = frameBuffer.forget();
   mFrameBufferLength = aFrameBufferLength;
   mTime = aTime;
   mAllowAudioData = aAllowAudioData;
   return NS_OK;
 }
 
 nsresult NS_NewDOMAudioAvailableEvent(nsIDOMEvent** aInstancePtrResult,
+                                      mozilla::dom::EventTarget* aOwner,
                                       nsPresContext* aPresContext,
                                       nsEvent *aEvent,
                                       uint32_t aEventType,
                                       float* aFrameBuffer,
                                       uint32_t aFrameBufferLength,
                                       float aTime)
 {
   nsDOMNotifyAudioAvailableEvent* it =
-    new nsDOMNotifyAudioAvailableEvent(aPresContext, aEvent, aEventType,
+    new nsDOMNotifyAudioAvailableEvent(aOwner, aPresContext, aEvent, aEventType,
                                        aFrameBuffer, aFrameBufferLength, aTime);
   return CallQueryInterface(it, aInstancePtrResult);
 }
--- a/content/events/src/nsDOMNotifyAudioAvailableEvent.h
+++ b/content/events/src/nsDOMNotifyAudioAvailableEvent.h
@@ -11,28 +11,30 @@
 #include "nsDOMEvent.h"
 #include "nsPresContext.h"
 #include "nsCycleCollectionParticipant.h"
 
 class nsDOMNotifyAudioAvailableEvent : public nsDOMEvent,
                                        public nsIDOMNotifyAudioAvailableEvent
 {
 public:
-  nsDOMNotifyAudioAvailableEvent(nsPresContext* aPresContext, nsEvent* aEvent,
+  nsDOMNotifyAudioAvailableEvent(mozilla::dom::EventTarget* aOwner,
+                                 nsPresContext* aPresContext, nsEvent* aEvent,
                                  uint32_t aEventType, float * aFrameBuffer,
                                  uint32_t aFrameBufferLength, float aTime);
 
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(nsDOMNotifyAudioAvailableEvent,
                                                          nsDOMEvent)
 
   NS_DECL_NSIDOMNOTIFYAUDIOAVAILABLEEVENT
   NS_FORWARD_NSIDOMEVENT(nsDOMEvent::)
 
   nsresult NS_NewDOMAudioAvailableEvent(nsIDOMEvent** aInstancePtrResult,
+                                        mozilla::dom::EventTarget* aOwner,
                                         nsPresContext* aPresContext,
                                         nsEvent *aEvent,
                                         uint32_t aEventType,
                                         float * aFrameBuffer,
                                         uint32_t aFrameBufferLength,
                                         float aTime);
 
   ~nsDOMNotifyAudioAvailableEvent();
--- a/content/events/src/nsDOMNotifyPaintEvent.cpp
+++ b/content/events/src/nsDOMNotifyPaintEvent.cpp
@@ -7,21 +7,22 @@
 #include "ipc/IPCMessageUtils.h"
 #include "nsDOMNotifyPaintEvent.h"
 #include "nsContentUtils.h"
 #include "nsClientRect.h"
 #include "nsPaintRequest.h"
 #include "nsIFrame.h"
 #include "nsDOMClassInfoID.h"
 
-nsDOMNotifyPaintEvent::nsDOMNotifyPaintEvent(nsPresContext* aPresContext,
+nsDOMNotifyPaintEvent::nsDOMNotifyPaintEvent(mozilla::dom::EventTarget* aOwner,
+                                             nsPresContext* aPresContext,
                                              nsEvent* aEvent,
                                              uint32_t aEventType,
                                              nsInvalidateRequestList* aInvalidateRequests)
-: nsDOMEvent(aPresContext, aEvent)
+: nsDOMEvent(aOwner, aPresContext, aEvent)
 {
   if (mEvent) {
     mEvent->message = aEventType;
   }
   if (aInvalidateRequests) {
     mInvalidateRequests.MoveElementsFrom(aInvalidateRequests->mRequests);
   }
 }
@@ -152,22 +153,23 @@ nsDOMNotifyPaintEvent::Deserialize(const
     NS_ENSURE_TRUE(IPC::ReadParam(aMsg, aIter, &req.mFlags), false);
     mInvalidateRequests.AppendElement(req);
   }
 
   return true;
 }
 
 nsresult NS_NewDOMNotifyPaintEvent(nsIDOMEvent** aInstancePtrResult,
+                                   mozilla::dom::EventTarget* aOwner,
                                    nsPresContext* aPresContext,
                                    nsEvent *aEvent,
                                    uint32_t aEventType,
                                    nsInvalidateRequestList* aInvalidateRequests) 
 {
   nsDOMNotifyPaintEvent* it =
-    new nsDOMNotifyPaintEvent(aPresContext, aEvent, aEventType,
+    new nsDOMNotifyPaintEvent(aOwner, aPresContext, aEvent, aEventType,
                               aInvalidateRequests);
   if (nullptr == it) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
   return CallQueryInterface(it, aInstancePtrResult);
 }
--- a/content/events/src/nsDOMNotifyPaintEvent.h
+++ b/content/events/src/nsDOMNotifyPaintEvent.h
@@ -11,17 +11,18 @@
 #include "nsPresContext.h"
 
 class nsPaintRequestList;
 
 class nsDOMNotifyPaintEvent : public nsDOMEvent,
                               public nsIDOMNotifyPaintEvent
 {
 public:
-  nsDOMNotifyPaintEvent(nsPresContext*           aPresContext,
+  nsDOMNotifyPaintEvent(mozilla::dom::EventTarget* aOwner,
+                        nsPresContext*           aPresContext,
                         nsEvent*                 aEvent,
                         uint32_t                 aEventType,
                         nsInvalidateRequestList* aInvalidateRequests);
 
   NS_DECL_ISUPPORTS_INHERITED
 
   NS_DECL_NSIDOMNOTIFYPAINTEVENT
 
--- a/content/events/src/nsDOMScrollAreaEvent.cpp
+++ b/content/events/src/nsDOMScrollAreaEvent.cpp
@@ -8,19 +8,20 @@
 
 #include "nsDOMScrollAreaEvent.h"
 #include "nsGUIEvent.h"
 #include "nsClientRect.h"
 #include "nsDOMClassInfoID.h"
 #include "nsIClassInfo.h"
 #include "nsIXPCScriptable.h"
 
-nsDOMScrollAreaEvent::nsDOMScrollAreaEvent(nsPresContext *aPresContext,
+nsDOMScrollAreaEvent::nsDOMScrollAreaEvent(mozilla::dom::EventTarget* aOwner,
+                                           nsPresContext *aPresContext,
                                            nsScrollAreaEvent *aEvent)
-  : nsDOMUIEvent(aPresContext, aEvent)
+  : nsDOMUIEvent(aOwner, aPresContext, aEvent)
 {
   mClientArea.SetLayoutRect(aEvent ? aEvent->mArea : nsRect());
 }
 
 nsDOMScrollAreaEvent::~nsDOMScrollAreaEvent()
 {
   if (mEventIsInternal && mEvent) {
     if (mEvent->eventStructType == NS_SCROLLAREA_EVENT) {
@@ -115,14 +116,16 @@ nsDOMScrollAreaEvent::Deserialize(const 
   NS_ENSURE_TRUE(IPC::ReadParam(aMsg, aIter, &height), false);
   mClientArea.SetRect(x, y, width, height);
 
   return true;
 }
 
 nsresult
 NS_NewDOMScrollAreaEvent(nsIDOMEvent **aInstancePtrResult,
+                         mozilla::dom::EventTarget* aOwner,
                          nsPresContext *aPresContext,
                          nsScrollAreaEvent *aEvent)
 {
-  nsDOMScrollAreaEvent *ev = new nsDOMScrollAreaEvent(aPresContext, aEvent);
+  nsDOMScrollAreaEvent* ev =
+    new nsDOMScrollAreaEvent(aOwner, aPresContext, aEvent);
   return CallQueryInterface(ev, aInstancePtrResult);
 }
--- a/content/events/src/nsDOMScrollAreaEvent.h
+++ b/content/events/src/nsDOMScrollAreaEvent.h
@@ -11,17 +11,18 @@
 
 #include "nsGUIEvent.h"
 #include "nsClientRect.h"
 
 class nsDOMScrollAreaEvent : public nsDOMUIEvent,
                              public nsIDOMScrollAreaEvent
 {
 public:
-  nsDOMScrollAreaEvent(nsPresContext *aPresContext,
+  nsDOMScrollAreaEvent(mozilla::dom::EventTarget* aOwner,
+                       nsPresContext *aPresContext,
                        nsScrollAreaEvent *aEvent);
   virtual ~nsDOMScrollAreaEvent();
 
   NS_DECL_ISUPPORTS_INHERITED
 
   NS_DECL_NSIDOMSCROLLAREAEVENT
 
   NS_FORWARD_NSIDOMUIEVENT(nsDOMUIEvent::)
--- a/content/events/src/nsDOMSimpleGestureEvent.cpp
+++ b/content/events/src/nsDOMSimpleGestureEvent.cpp
@@ -1,18 +1,21 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsDOMClassInfoID.h"
 #include "nsDOMSimpleGestureEvent.h"
 
-nsDOMSimpleGestureEvent::nsDOMSimpleGestureEvent(nsPresContext* aPresContext, nsSimpleGestureEvent* aEvent)
-  : nsDOMMouseEvent(aPresContext, aEvent ? aEvent : new nsSimpleGestureEvent(false, 0, nullptr, 0, 0.0))
+nsDOMSimpleGestureEvent::nsDOMSimpleGestureEvent(mozilla::dom::EventTarget* aOwner,
+                                                 nsPresContext* aPresContext,
+                                                 nsSimpleGestureEvent* aEvent)
+  : nsDOMMouseEvent(aOwner, aPresContext,
+                    aEvent ? aEvent : new nsSimpleGestureEvent(false, 0, nullptr, 0, 0.0))
 {
   NS_ASSERTION(mEvent->eventStructType == NS_SIMPLE_GESTURE_EVENT, "event type mismatch");
 
   if (aEvent) {
     mEventIsInternal = false;
   } else {
     mEventIsInternal = true;
     mEvent->time = PR_Now();
@@ -107,17 +110,16 @@ nsDOMSimpleGestureEvent::InitSimpleGestu
   simpleGestureEvent->direction = aDirectionArg;
   simpleGestureEvent->delta = aDeltaArg;
   simpleGestureEvent->clickCount = aClickCountArg;
 
   return NS_OK;
 }
 
 nsresult NS_NewDOMSimpleGestureEvent(nsIDOMEvent** aInstancePtrResult,
+                                     mozilla::dom::EventTarget* aOwner,
                                      nsPresContext* aPresContext,
                                      nsSimpleGestureEvent *aEvent)
 {
-  nsDOMSimpleGestureEvent *it = new nsDOMSimpleGestureEvent(aPresContext, aEvent);
-  if (nullptr == it) {
-    return NS_ERROR_OUT_OF_MEMORY;
-  }
+  nsDOMSimpleGestureEvent* it =
+    new nsDOMSimpleGestureEvent(aOwner, aPresContext, aEvent);
   return CallQueryInterface(it, aInstancePtrResult);
 }
--- a/content/events/src/nsDOMSimpleGestureEvent.h
+++ b/content/events/src/nsDOMSimpleGestureEvent.h
@@ -9,17 +9,18 @@
 #include "nsDOMMouseEvent.h"
 
 class nsPresContext;
 
 class nsDOMSimpleGestureEvent : public nsDOMMouseEvent,
                                 public nsIDOMSimpleGestureEvent
 {
 public:
-  nsDOMSimpleGestureEvent(nsPresContext*, nsSimpleGestureEvent*);
+  nsDOMSimpleGestureEvent(mozilla::dom::EventTarget* aOwner,
+                          nsPresContext*, nsSimpleGestureEvent*);
   virtual ~nsDOMSimpleGestureEvent();
 
   NS_DECL_ISUPPORTS_INHERITED
 
   NS_DECL_NSIDOMSIMPLEGESTUREEVENT
 
   // Forward to base class
   NS_FORWARD_TO_NSDOMMOUSEEVENT
--- a/content/events/src/nsDOMTextEvent.cpp
+++ b/content/events/src/nsDOMTextEvent.cpp
@@ -2,20 +2,21 @@
 /* vim: set ts=2 sw=2 et tw=78: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsDOMTextEvent.h"
 #include "nsPrivateTextRange.h"
 
-nsDOMTextEvent::nsDOMTextEvent(nsPresContext* aPresContext,
+nsDOMTextEvent::nsDOMTextEvent(mozilla::dom::EventTarget* aOwner,
+                               nsPresContext* aPresContext,
                                nsTextEvent* aEvent)
-  : nsDOMUIEvent(aPresContext, aEvent ? aEvent :
-                 new nsTextEvent(false, 0, nullptr))
+  : nsDOMUIEvent(aOwner, aPresContext,
+                 aEvent ? aEvent : new nsTextEvent(false, 0, nullptr))
 {
   NS_ASSERTION(mEvent->eventStructType == NS_TEXT_EVENT, "event type mismatch");
 
   if (aEvent) {
     mEventIsInternal = false;
   }
   else {
     mEventIsInternal = true;
@@ -68,18 +69,15 @@ NS_METHOD_(already_AddRefed<nsIPrivateTe
     nsPrivateTextRangeList *textRangePtr = nullptr;
     textRange.swap(textRangePtr);
     return textRangePtr;
   }
   return nullptr;
 }
 
 nsresult NS_NewDOMTextEvent(nsIDOMEvent** aInstancePtrResult,
+                            mozilla::dom::EventTarget* aOwner,
                             nsPresContext* aPresContext,
                             nsTextEvent *aEvent)
 {
-  nsDOMTextEvent* it = new nsDOMTextEvent(aPresContext, aEvent);
-  if (nullptr == it) {
-    return NS_ERROR_OUT_OF_MEMORY;
-  }
-
+  nsDOMTextEvent* it = new nsDOMTextEvent(aOwner, aPresContext, aEvent);
   return CallQueryInterface(it, aInstancePtrResult);
 }
--- a/content/events/src/nsDOMTextEvent.h
+++ b/content/events/src/nsDOMTextEvent.h
@@ -9,17 +9,18 @@
 #include "nsDOMUIEvent.h"
 #include "nsIPrivateTextEvent.h"
 #include "nsPrivateTextRange.h"
 
 class nsDOMTextEvent : public nsDOMUIEvent,
                        public nsIPrivateTextEvent
 {
 public:
-  nsDOMTextEvent(nsPresContext* aPresContext, nsTextEvent* aEvent);
+  nsDOMTextEvent(mozilla::dom::EventTarget* aOwner,
+                 nsPresContext* aPresContext, nsTextEvent* aEvent);
 
   NS_DECL_ISUPPORTS_INHERITED
 
   // Forward to base class
   NS_FORWARD_TO_NSDOMUIEVENT
 
   // nsIPrivateTextEvent interface
   NS_IMETHOD GetText(nsString& aText);
--- a/content/events/src/nsDOMTouchEvent.cpp
+++ b/content/events/src/nsDOMTouchEvent.cpp
@@ -181,20 +181,21 @@ nsDOMTouchList::IdentifiedTouch(int32_t 
       break;
     }
   }
   return NS_OK;
 }
 
 // TouchEvent
 
-nsDOMTouchEvent::nsDOMTouchEvent(nsPresContext* aPresContext,
+nsDOMTouchEvent::nsDOMTouchEvent(mozilla::dom::EventTarget* aOwner,
+                                 nsPresContext* aPresContext,
                                  nsTouchEvent* aEvent)
-  : nsDOMUIEvent(aPresContext, aEvent ? aEvent :
-                                        new nsTouchEvent(false, 0, nullptr))
+  : nsDOMUIEvent(aOwner, aPresContext,
+                 aEvent ? aEvent : new nsTouchEvent(false, 0, nullptr))
 {
   if (aEvent) {
     mEventIsInternal = false;
 
     for (uint32_t i = 0; i < aEvent->touches.Length(); ++i) {
       nsIDOMTouch *touch = aEvent->touches[i];
       nsDOMTouch *domtouch = static_cast<nsDOMTouch*>(touch);
       domtouch->InitializePoints(mPresContext, aEvent);
@@ -405,15 +406,15 @@ nsDOMTouchEvent::PrefEnabled()
       nsContentUtils::InitializeTouchEventTable();
     }
   }
   return sPrefValue;
 }
 
 nsresult
 NS_NewDOMTouchEvent(nsIDOMEvent** aInstancePtrResult,
+                    mozilla::dom::EventTarget* aOwner,
                     nsPresContext* aPresContext,
                     nsTouchEvent *aEvent)
 {
-  nsDOMTouchEvent* it = new nsDOMTouchEvent(aPresContext, aEvent);
-
+  nsDOMTouchEvent* it = new nsDOMTouchEvent(aOwner, aPresContext, aEvent);
   return CallQueryInterface(it, aInstancePtrResult);
 }
--- a/content/events/src/nsDOMTouchEvent.h
+++ b/content/events/src/nsDOMTouchEvent.h
@@ -126,17 +126,18 @@ public:
 protected:
   nsTArray<nsCOMPtr<nsIDOMTouch> > mPoints;
 };
 
 class nsDOMTouchEvent : public nsDOMUIEvent,
                         public nsIDOMTouchEvent
 {
 public:
-  nsDOMTouchEvent(nsPresContext* aPresContext, nsTouchEvent* aEvent);
+  nsDOMTouchEvent(mozilla::dom::EventTarget* aOwner,
+                  nsPresContext* aPresContext, nsTouchEvent* aEvent);
   virtual ~nsDOMTouchEvent();
 
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsDOMTouchEvent, nsDOMUIEvent)
   NS_DECL_NSIDOMTOUCHEVENT
 
   NS_FORWARD_TO_NSDOMUIEVENT
 
--- a/content/events/src/nsDOMTransitionEvent.cpp
+++ b/content/events/src/nsDOMTransitionEvent.cpp
@@ -4,22 +4,23 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsDOMTransitionEvent.h"
 #include "nsGUIEvent.h"
 #include "nsDOMClassInfoID.h"
 #include "nsIClassInfo.h"
 #include "nsIXPCScriptable.h"
 
-nsDOMTransitionEvent::nsDOMTransitionEvent(nsPresContext *aPresContext,
+nsDOMTransitionEvent::nsDOMTransitionEvent(mozilla::dom::EventTarget* aOwner,
+                                           nsPresContext *aPresContext,
                                            nsTransitionEvent *aEvent)
-  : nsDOMEvent(aPresContext, aEvent ? aEvent
-                                    : new nsTransitionEvent(false, 0,
-                                                            EmptyString(),
-                                                            0.0))
+  : nsDOMEvent(aOwner, aPresContext,
+               aEvent ? aEvent : new nsTransitionEvent(false, 0,
+                                                       EmptyString(),
+                                                       0.0))
 {
   if (aEvent) {
     mEventIsInternal = false;
   }
   else {
     mEventIsInternal = true;
     mEvent->time = PR_Now();
   }
@@ -70,14 +71,16 @@ nsDOMTransitionEvent::InitTransitionEven
   TransitionEvent()->propertyName = propertyNameArg;
   TransitionEvent()->elapsedTime = elapsedTimeArg;
 
   return NS_OK;
 }
 
 nsresult
 NS_NewDOMTransitionEvent(nsIDOMEvent **aInstancePtrResult,
+                         mozilla::dom::EventTarget* aOwner,
                          nsPresContext *aPresContext,
                          nsTransitionEvent *aEvent)
 {
-  nsDOMTransitionEvent *it = new nsDOMTransitionEvent(aPresContext, aEvent);
+  nsDOMTransitionEvent *it =
+    new nsDOMTransitionEvent(aOwner, aPresContext, aEvent);
   return CallQueryInterface(it, aInstancePtrResult);
 }
--- a/content/events/src/nsDOMTransitionEvent.h
+++ b/content/events/src/nsDOMTransitionEvent.h
@@ -10,17 +10,18 @@
 #include "nsString.h"
 
 class nsTransitionEvent;
 
 class nsDOMTransitionEvent : public nsDOMEvent,
                              public nsIDOMTransitionEvent
 {
 public:
-  nsDOMTransitionEvent(nsPresContext *aPresContext,
+  nsDOMTransitionEvent(mozilla::dom::EventTarget* aOwner,
+                       nsPresContext *aPresContext,
                        nsTransitionEvent *aEvent);
   ~nsDOMTransitionEvent();
 
   NS_DECL_ISUPPORTS_INHERITED
   NS_FORWARD_TO_NSDOMEVENT
   NS_DECL_NSIDOMTRANSITIONEVENT
 
 private:
--- a/content/events/src/nsDOMUIEvent.cpp
+++ b/content/events/src/nsDOMUIEvent.cpp
@@ -18,18 +18,19 @@
 #include "nsIScrollableFrame.h"
 #include "DictionaryHelpers.h"
 #include "mozilla/Util.h"
 #include "mozilla/Assertions.h"
 #include "nsDOMClassInfoID.h"
 
 using namespace mozilla;
 
-nsDOMUIEvent::nsDOMUIEvent(nsPresContext* aPresContext, nsGUIEvent* aEvent)
-  : nsDOMEvent(aPresContext, aEvent ?
+nsDOMUIEvent::nsDOMUIEvent(mozilla::dom::EventTarget* aOwner,
+                           nsPresContext* aPresContext, nsGUIEvent* aEvent)
+  : nsDOMEvent(aOwner, aPresContext, aEvent ?
                static_cast<nsEvent *>(aEvent) :
                static_cast<nsEvent *>(new nsUIEvent(false, 0, 0)))
   , mClientPoint(0, 0), mLayerPoint(0, 0), mPagePoint(0, 0), mMovementPoint(0, 0)
   , mIsPointerLocked(nsEventStateManager::sIsPointerLocked)
   , mLastClientPoint(nsEventStateManager::sLastClientPoint)
 {
   if (aEvent) {
     mEventIsInternal = false;
@@ -500,14 +501,15 @@ nsDOMUIEvent::GetModifierStateInternal(c
   if (aKey.EqualsLiteral(NS_DOM_KEYNAME_SYMBOLLOCK)) {
     return inputEvent->IsSymbolLocked();
   }
   return false;
 }
 
 
 nsresult NS_NewDOMUIEvent(nsIDOMEvent** aInstancePtrResult,
+                          mozilla::dom::EventTarget* aOwner,
                           nsPresContext* aPresContext,
                           nsGUIEvent *aEvent) 
 {
-  nsDOMUIEvent* it = new nsDOMUIEvent(aPresContext, aEvent);
+  nsDOMUIEvent* it = new nsDOMUIEvent(aOwner, aPresContext, aEvent);
   return CallQueryInterface(it, aInstancePtrResult);
 }
--- a/content/events/src/nsDOMUIEvent.h
+++ b/content/events/src/nsDOMUIEvent.h
@@ -10,17 +10,18 @@
 #include "nsDOMEvent.h"
 #include "nsLayoutUtils.h"
 #include "nsEvent.h"
 
 class nsDOMUIEvent : public nsDOMEvent,
                      public nsIDOMUIEvent
 {
 public:
-  nsDOMUIEvent(nsPresContext* aPresContext, nsGUIEvent* aEvent);
+  nsDOMUIEvent(mozilla::dom::EventTarget* aOwner,
+               nsPresContext* aPresContext, nsGUIEvent* aEvent);
 
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsDOMUIEvent, nsDOMEvent)
 
   // nsIDOMUIEvent Interface
   NS_DECL_NSIDOMUIEVENT
   
   // Forward to nsDOMEvent
--- a/content/events/src/nsDOMXULCommandEvent.cpp
+++ b/content/events/src/nsDOMXULCommandEvent.cpp
@@ -2,19 +2,20 @@
 /* vim:set ts=2 sw=2 sts=2 et cindent: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsDOMClassInfoID.h"
 #include "nsDOMXULCommandEvent.h"
 
-nsDOMXULCommandEvent::nsDOMXULCommandEvent(nsPresContext* aPresContext,
+nsDOMXULCommandEvent::nsDOMXULCommandEvent(mozilla::dom::EventTarget* aOwner,
+                                           nsPresContext* aPresContext,
                                            nsInputEvent* aEvent)
-  : nsDOMUIEvent(aPresContext,
+  : nsDOMUIEvent(aOwner, aPresContext,
                  aEvent ? aEvent : new nsInputEvent(false, 0, nullptr))
 {
   if (aEvent) {
     mEventIsInternal = false;
   }
   else {
     mEventIsInternal = true;
     mEvent->time = PR_Now();
@@ -97,14 +98,16 @@ nsDOMXULCommandEvent::InitCommandEvent(c
   Event()->InitBasicModifiers(aCtrlKey, aAltKey, aShiftKey, aMetaKey);
   mSourceEvent = aSourceEvent;
 
   return NS_OK;
 }
 
 
 nsresult NS_NewDOMXULCommandEvent(nsIDOMEvent** aInstancePtrResult,
+                                  mozilla::dom::EventTarget* aOwner,
                                   nsPresContext* aPresContext,
                                   nsInputEvent *aEvent) 
 {
-  nsDOMXULCommandEvent* it = new nsDOMXULCommandEvent(aPresContext, aEvent);
+  nsDOMXULCommandEvent* it =
+    new nsDOMXULCommandEvent(aOwner, aPresContext, aEvent);
   return CallQueryInterface(it, aInstancePtrResult);
 }
--- a/content/events/src/nsDOMXULCommandEvent.h
+++ b/content/events/src/nsDOMXULCommandEvent.h
@@ -11,17 +11,18 @@
 
 #include "nsDOMUIEvent.h"
 #include "nsIDOMXULCommandEvent.h"
 
 class nsDOMXULCommandEvent : public nsDOMUIEvent,
                              public nsIDOMXULCommandEvent
 {
 public:
-  nsDOMXULCommandEvent(nsPresContext* aPresContext, nsInputEvent* aEvent);
+  nsDOMXULCommandEvent(mozilla::dom::EventTarget* aOwner,
+                       nsPresContext* aPresContext, nsInputEvent* aEvent);
 
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsDOMXULCommandEvent, nsDOMUIEvent)
   NS_DECL_NSIDOMXULCOMMANDEVENT
 
   // Forward our inherited virtual methods to the base class
   NS_FORWARD_TO_NSDOMUIEVENT
 
--- a/content/events/src/nsEventDispatcher.cpp
+++ b/content/events/src/nsEventDispatcher.cpp
@@ -693,176 +693,177 @@ nsEventDispatcher::DispatchDOMEvent(nsIS
   } else if (aEvent) {
     return nsEventDispatcher::Dispatch(aTarget, aPresContext, aEvent,
                                        aDOMEvent, aEventStatus);
   }
   return NS_ERROR_ILLEGAL_VALUE;
 }
 
 /* static */ nsresult
-nsEventDispatcher::CreateEvent(nsPresContext* aPresContext,
+nsEventDispatcher::CreateEvent(mozilla::dom::EventTarget* aOwner,
+                               nsPresContext* aPresContext,
                                nsEvent* aEvent,
                                const nsAString& aEventType,
                                nsIDOMEvent** aDOMEvent)
 {
   *aDOMEvent = nullptr;
 
   if (aEvent) {
     switch(aEvent->eventStructType) {
     case NS_MUTATION_EVENT:
-      return NS_NewDOMMutationEvent(aDOMEvent, aPresContext,
+      return NS_NewDOMMutationEvent(aDOMEvent, aOwner, aPresContext,
                                     static_cast<nsMutationEvent*>(aEvent));
     case NS_GUI_EVENT:
     case NS_SCROLLPORT_EVENT:
     case NS_UI_EVENT:
-      return NS_NewDOMUIEvent(aDOMEvent, aPresContext,
+      return NS_NewDOMUIEvent(aDOMEvent, aOwner, aPresContext,
                               static_cast<nsGUIEvent*>(aEvent));
     case NS_SCROLLAREA_EVENT:
-      return NS_NewDOMScrollAreaEvent(aDOMEvent, aPresContext,
+      return NS_NewDOMScrollAreaEvent(aDOMEvent, aOwner, aPresContext,
                                       static_cast<nsScrollAreaEvent *>(aEvent));
     case NS_KEY_EVENT:
-      return NS_NewDOMKeyboardEvent(aDOMEvent, aPresContext,
+      return NS_NewDOMKeyboardEvent(aDOMEvent, aOwner, aPresContext,
                                     static_cast<nsKeyEvent*>(aEvent));
     case NS_COMPOSITION_EVENT:
       return NS_NewDOMCompositionEvent(
-        aDOMEvent, aPresContext, static_cast<nsCompositionEvent*>(aEvent));
+        aDOMEvent, aOwner,
+        aPresContext, static_cast<nsCompositionEvent*>(aEvent));
     case NS_MOUSE_EVENT:
-      return NS_NewDOMMouseEvent(aDOMEvent, aPresContext,
+      return NS_NewDOMMouseEvent(aDOMEvent, aOwner, aPresContext,
                                  static_cast<nsInputEvent*>(aEvent));
     case NS_MOUSE_SCROLL_EVENT:
-      return NS_NewDOMMouseScrollEvent(aDOMEvent, aPresContext,
+      return NS_NewDOMMouseScrollEvent(aDOMEvent, aOwner, aPresContext,
                                  static_cast<nsInputEvent*>(aEvent));
     case NS_WHEEL_EVENT:
-      return NS_NewDOMWheelEvent(aDOMEvent, aPresContext,
+      return NS_NewDOMWheelEvent(aDOMEvent, aOwner, aPresContext,
                                  static_cast<widget::WheelEvent*>(aEvent));
     case NS_DRAG_EVENT:
-      return NS_NewDOMDragEvent(aDOMEvent, aPresContext,
+      return NS_NewDOMDragEvent(aDOMEvent, aOwner, aPresContext,
                                  static_cast<nsDragEvent*>(aEvent));
     case NS_TEXT_EVENT:
-      return NS_NewDOMTextEvent(aDOMEvent, aPresContext,
+      return NS_NewDOMTextEvent(aDOMEvent, aOwner, aPresContext,
                                 static_cast<nsTextEvent*>(aEvent));
     case NS_SVG_EVENT:
-      return NS_NewDOMSVGEvent(aDOMEvent, aPresContext,
+      return NS_NewDOMSVGEvent(aDOMEvent, aOwner, aPresContext,
                                aEvent);
     case NS_SVGZOOM_EVENT:
-      return NS_NewDOMSVGZoomEvent(aDOMEvent, aPresContext,
+      return NS_NewDOMSVGZoomEvent(aDOMEvent, aOwner, aPresContext,
                                    static_cast<nsGUIEvent*>(aEvent));
     case NS_SMIL_TIME_EVENT:
-      return NS_NewDOMTimeEvent(aDOMEvent, aPresContext, aEvent);
+      return NS_NewDOMTimeEvent(aDOMEvent, aOwner, aPresContext, aEvent);
 
     case NS_COMMAND_EVENT:
-      return NS_NewDOMCommandEvent(aDOMEvent, aPresContext,
+      return NS_NewDOMCommandEvent(aDOMEvent, aOwner, aPresContext,
                                    static_cast<nsCommandEvent*>(aEvent));
     case NS_SIMPLE_GESTURE_EVENT:
-      return NS_NewDOMSimpleGestureEvent(aDOMEvent, aPresContext,
+      return NS_NewDOMSimpleGestureEvent(aDOMEvent, aOwner, aPresContext,
                                          static_cast<nsSimpleGestureEvent*>(aEvent));
     case NS_TOUCH_EVENT:
-      return NS_NewDOMTouchEvent(aDOMEvent, aPresContext,
+      return NS_NewDOMTouchEvent(aDOMEvent, aOwner, aPresContext,
                                  static_cast<nsTouchEvent*>(aEvent));
     case NS_TRANSITION_EVENT:
-      return NS_NewDOMTransitionEvent(aDOMEvent, aPresContext,
+      return NS_NewDOMTransitionEvent(aDOMEvent, aOwner, aPresContext,
                                       static_cast<nsTransitionEvent*>(aEvent));
     case NS_ANIMATION_EVENT:
-      return NS_NewDOMAnimationEvent(aDOMEvent, aPresContext,
+      return NS_NewDOMAnimationEvent(aDOMEvent, aOwner, aPresContext,
                                      static_cast<nsAnimationEvent*>(aEvent));
     default:
       // For all other types of events, create a vanilla event object.
-      return NS_NewDOMEvent(aDOMEvent, aPresContext, aEvent);
+      return NS_NewDOMEvent(aDOMEvent, aOwner, aPresContext, aEvent);
     }
   }
 
   // And if we didn't get an event, check the type argument.
 
   if (aEventType.LowerCaseEqualsLiteral("mouseevent") ||
       aEventType.LowerCaseEqualsLiteral("mouseevents") ||
       aEventType.LowerCaseEqualsLiteral("popupevents"))
-    return NS_NewDOMMouseEvent(aDOMEvent, aPresContext, nullptr);
+    return NS_NewDOMMouseEvent(aDOMEvent, aOwner, aPresContext, nullptr);
   if (aEventType.LowerCaseEqualsLiteral("mousescrollevents"))
-    return NS_NewDOMMouseScrollEvent(aDOMEvent, aPresContext, nullptr);
+    return NS_NewDOMMouseScrollEvent(aDOMEvent, aOwner, aPresContext, nullptr);
   if (aEventType.LowerCaseEqualsLiteral("dragevent") ||
       aEventType.LowerCaseEqualsLiteral("dragevents"))
-    return NS_NewDOMDragEvent(aDOMEvent, aPresContext, nullptr);
+    return NS_NewDOMDragEvent(aDOMEvent, aOwner, aPresContext, nullptr);
   if (aEventType.LowerCaseEqualsLiteral("keyboardevent") ||
       aEventType.LowerCaseEqualsLiteral("keyevents"))
-    return NS_NewDOMKeyboardEvent(aDOMEvent, aPresContext, nullptr);
+    return NS_NewDOMKeyboardEvent(aDOMEvent, aOwner, aPresContext, nullptr);
   if (aEventType.LowerCaseEqualsLiteral("compositionevent"))
-    return NS_NewDOMCompositionEvent(aDOMEvent, aPresContext, nullptr);
+    return NS_NewDOMCompositionEvent(aDOMEvent, aOwner, aPresContext, nullptr);
   if (aEventType.LowerCaseEqualsLiteral("mutationevent") ||
         aEventType.LowerCaseEqualsLiteral("mutationevents"))
-    return NS_NewDOMMutationEvent(aDOMEvent, aPresContext, nullptr);
+    return NS_NewDOMMutationEvent(aDOMEvent, aOwner, aPresContext, nullptr);
   if (aEventType.LowerCaseEqualsLiteral("textevent") ||
       aEventType.LowerCaseEqualsLiteral("textevents"))
-    return NS_NewDOMTextEvent(aDOMEvent, aPresContext, nullptr);
+    return NS_NewDOMTextEvent(aDOMEvent, aOwner, aPresContext, nullptr);
   if (aEventType.LowerCaseEqualsLiteral("popupblockedevents"))
-    return NS_NewDOMPopupBlockedEvent(aDOMEvent, aPresContext, nullptr);
+    return NS_NewDOMPopupBlockedEvent(aDOMEvent, aOwner, aPresContext, nullptr);
   if (aEventType.LowerCaseEqualsLiteral("deviceorientationevent"))
-    return NS_NewDOMDeviceOrientationEvent(aDOMEvent, aPresContext, nullptr);
+    return NS_NewDOMDeviceOrientationEvent(aDOMEvent, aOwner, aPresContext, nullptr);
   if (aEventType.LowerCaseEqualsLiteral("devicemotionevent"))
-    return NS_NewDOMDeviceMotionEvent(aDOMEvent, aPresContext, nullptr);
+    return NS_NewDOMDeviceMotionEvent(aDOMEvent, aOwner, aPresContext, nullptr);
   if (aEventType.LowerCaseEqualsLiteral("uievent") ||
       aEventType.LowerCaseEqualsLiteral("uievents"))
-    return NS_NewDOMUIEvent(aDOMEvent, aPresContext, nullptr);
+    return NS_NewDOMUIEvent(aDOMEvent, aOwner, aPresContext, nullptr);
   if (aEventType.LowerCaseEqualsLiteral("event") ||
       aEventType.LowerCaseEqualsLiteral("events") ||
       aEventType.LowerCaseEqualsLiteral("htmlevents"))
-    return NS_NewDOMEvent(aDOMEvent, aPresContext, nullptr);
+    return NS_NewDOMEvent(aDOMEvent, aOwner, aPresContext, nullptr);
   if (aEventType.LowerCaseEqualsLiteral("svgevent") ||
       aEventType.LowerCaseEqualsLiteral("svgevents"))
-    return NS_NewDOMSVGEvent(aDOMEvent, aPresContext, nullptr);
+    return NS_NewDOMSVGEvent(aDOMEvent, aOwner, aPresContext, nullptr);
   if (aEventType.LowerCaseEqualsLiteral("svgzoomevent") ||
       aEventType.LowerCaseEqualsLiteral("svgzoomevents"))
-    return NS_NewDOMSVGZoomEvent(aDOMEvent, aPresContext, nullptr);
+    return NS_NewDOMSVGZoomEvent(aDOMEvent, aOwner, aPresContext, nullptr);
   if (aEventType.LowerCaseEqualsLiteral("timeevent") ||
       aEventType.LowerCaseEqualsLiteral("timeevents"))
-    return NS_NewDOMTimeEvent(aDOMEvent, aPresContext, nullptr);
+    return NS_NewDOMTimeEvent(aDOMEvent, aOwner, aPresContext, nullptr);
   if (aEventType.LowerCaseEqualsLiteral("xulcommandevent") ||
       aEventType.LowerCaseEqualsLiteral("xulcommandevents"))
-    return NS_NewDOMXULCommandEvent(aDOMEvent, aPresContext, nullptr);
+    return NS_NewDOMXULCommandEvent(aDOMEvent, aOwner, aPresContext, nullptr);
   if (aEventType.LowerCaseEqualsLiteral("commandevent") ||
       aEventType.LowerCaseEqualsLiteral("commandevents"))
-    return NS_NewDOMCommandEvent(aDOMEvent, aPresContext, nullptr);
+    return NS_NewDOMCommandEvent(aDOMEvent, aOwner, aPresContext, nullptr);
   if (aEventType.LowerCaseEqualsLiteral("elementreplace"))
-    return NS_NewDOMElementReplaceEvent(aDOMEvent, aPresContext, nullptr);
+    return NS_NewDOMElementReplaceEvent(aDOMEvent, aOwner, aPresContext, nullptr);
   if (aEventType.LowerCaseEqualsLiteral("datacontainerevent") ||
       aEventType.LowerCaseEqualsLiteral("datacontainerevents"))
-    return NS_NewDOMDataContainerEvent(aDOMEvent, aPresContext, nullptr);
+    return NS_NewDOMDataContainerEvent(aDOMEvent, aOwner, aPresContext, nullptr);
   if (aEventType.LowerCaseEqualsLiteral("messageevent"))
-    return NS_NewDOMMessageEvent(aDOMEvent, aPresContext, nullptr);
+    return NS_NewDOMMessageEvent(aDOMEvent, aOwner, aPresContext, nullptr);
   if (aEventType.LowerCaseEqualsLiteral("notifypaintevent"))
-    return NS_NewDOMNotifyPaintEvent(aDOMEvent, aPresContext, nullptr);
+    return NS_NewDOMNotifyPaintEvent(aDOMEvent, aOwner, aPresContext, nullptr);
   if (aEventType.LowerCaseEqualsLiteral("simplegestureevent"))
-    return NS_NewDOMSimpleGestureEvent(aDOMEvent, aPresContext, nullptr);
+    return NS_NewDOMSimpleGestureEvent(aDOMEvent, aOwner, aPresContext, nullptr);
   if (aEventType.LowerCaseEqualsLiteral("beforeunloadevent"))
-    return NS_NewDOMBeforeUnloadEvent(aDOMEvent, aPresContext, nullptr);
+    return NS_NewDOMBeforeUnloadEvent(aDOMEvent, aOwner, aPresContext, nullptr);
   if (aEventType.LowerCaseEqualsLiteral("pagetransition"))
-    return NS_NewDOMPageTransitionEvent(aDOMEvent, aPresContext, nullptr);
+    return NS_NewDOMPageTransitionEvent(aDOMEvent, aOwner, aPresContext, nullptr);
   if (aEventType.LowerCaseEqualsLiteral("domtransaction"))
-    return NS_NewDOMDOMTransactionEvent(aDOMEvent, aPresContext, nullptr);
+    return NS_NewDOMDOMTransactionEvent(aDOMEvent, aOwner, aPresContext, nullptr);
   if (aEventType.LowerCaseEqualsLiteral("scrollareaevent"))
-    return NS_NewDOMScrollAreaEvent(aDOMEvent, aPresContext, nullptr);
+    return NS_NewDOMScrollAreaEvent(aDOMEvent, aOwner, aPresContext, nullptr);
   // FIXME: Should get spec to say what the right string is here!  This
   // is probably wrong!
   if (aEventType.LowerCaseEqualsLiteral("transitionevent"))
-    return NS_NewDOMTransitionEvent(aDOMEvent, aPresContext, nullptr);
+    return NS_NewDOMTransitionEvent(aDOMEvent, aOwner, aPresContext, nullptr);
   if (aEventType.LowerCaseEqualsLiteral("animationevent"))
-    return NS_NewDOMAnimationEvent(aDOMEvent, aPresContext, nullptr);
+    return NS_NewDOMAnimationEvent(aDOMEvent, aOwner, aPresContext, nullptr);
   if (aEventType.LowerCaseEqualsLiteral("popstateevent"))
-    return NS_NewDOMPopStateEvent(aDOMEvent, aPresContext, nullptr);
+    return NS_NewDOMPopStateEvent(aDOMEvent, aOwner, aPresContext, nullptr);
   if (aEventType.LowerCaseEqualsLiteral("mozaudioavailableevent"))
-    return NS_NewDOMAudioAvailableEvent(aDOMEvent, aPresContext, nullptr);
+    return NS_NewDOMAudioAvailableEvent(aDOMEvent, aOwner, aPresContext, nullptr);
   if (aEventType.LowerCaseEqualsLiteral("closeevent"))
-    return NS_NewDOMCloseEvent(aDOMEvent, aPresContext, nullptr);
+    return NS_NewDOMCloseEvent(aDOMEvent, aOwner, aPresContext, nullptr);
   if (aEventType.LowerCaseEqualsLiteral("touchevent") &&
       nsDOMTouchEvent::PrefEnabled())
-    return NS_NewDOMTouchEvent(aDOMEvent, aPresContext, nullptr);
+    return NS_NewDOMTouchEvent(aDOMEvent, aOwner, aPresContext, nullptr);
   if (aEventType.LowerCaseEqualsLiteral("hashchangeevent"))
-    return NS_NewDOMHashChangeEvent(aDOMEvent, aPresContext, nullptr);
+    return NS_NewDOMHashChangeEvent(aDOMEvent, aOwner, aPresContext, nullptr);
   if (aEventType.LowerCaseEqualsLiteral("customevent"))
-    return NS_NewDOMCustomEvent(aDOMEvent, aPresContext, nullptr);
+    return NS_NewDOMCustomEvent(aDOMEvent, aOwner, aPresContext, nullptr);
   if (aEventType.LowerCaseEqualsLiteral("mozsmsevent"))
-    return NS_NewDOMMozSmsEvent(aDOMEvent, aPresContext, nullptr);
+    return NS_NewDOMMozSmsEvent(aDOMEvent, aOwner, aPresContext, nullptr);
   if (aEventType.LowerCaseEqualsLiteral("storageevent")) {
-    return NS_NewDOMStorageEvent(aDOMEvent, aPresContext, nullptr);
+    return NS_NewDOMStorageEvent(aDOMEvent, aOwner, aPresContext, nullptr);
   }
-    
 
   return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
 }
--- a/content/events/src/nsEventListenerManager.cpp
+++ b/content/events/src/nsEventListenerManager.cpp
@@ -954,18 +954,21 @@ nsEventListenerManager::HandleEventInter
     nsListenerStruct* ls = &iter.GetNext();
     // Check that the phase is same in event and event listener.
     // Handle only trusted events, except when listener permits untrusted events.
     if (ListenerCanHandle(ls, aEvent)) {
       hasListener = true;
       if (ls->IsListening(aEvent) &&
           (aEvent->mFlags.mIsTrusted || ls->mFlags.mAllowUntrustedEvents)) {
         if (!*aDOMEvent) {
-          nsEventDispatcher::CreateEvent(aPresContext, aEvent,
-                                         EmptyString(), aDOMEvent);
+          // This is tiny bit slow, but happens only once per event.
+          nsCOMPtr<mozilla::dom::EventTarget> et =
+            do_QueryInterface(aEvent->originalTarget);
+          nsEventDispatcher::CreateEvent(et, aPresContext,
+                                         aEvent, EmptyString(), aDOMEvent);
         }
         if (*aDOMEvent) {
           if (!aEvent->currentTarget) {
             aEvent->currentTarget = aCurrentTarget->GetTargetForDOMEvent();
             if (!aEvent->currentTarget) {
               break;
             }
           }
--- a/content/events/src/nsEventStateManager.cpp
+++ b/content/events/src/nsEventStateManager.cpp
@@ -2278,16 +2278,17 @@ nsEventStateManager::DoDefaultDragStart(
   nsCOMPtr<nsIDOMElement> dragTargetElement;
   aDataTransfer->GetDragTarget(getter_AddRefs(dragTargetElement));
   dragTarget = do_QueryInterface(dragTargetElement);
   if (!dragTarget) {
     dragTarget = do_QueryInterface(aDragTarget);
     if (!dragTarget)
       return false;
   }
+  nsCOMPtr<nsIContent> content = do_QueryInterface(dragTarget);
 
   // check which drag effect should initially be used. If the effect was not
   // set, just use all actions, otherwise Windows won't allow a drop.
   uint32_t action;
   aDataTransfer->GetEffectAllowedInt(&action);
   if (action == nsIDragService::DRAGDROP_ACTION_UNINITIALIZED)
     action = nsIDragService::DRAGDROP_ACTION_COPY |
              nsIDragService::DRAGDROP_ACTION_MOVE |
@@ -2301,17 +2302,18 @@ nsEventStateManager::DoDefaultDragStart(
   aDataTransfer->GetTransferables(getter_AddRefs(transArray), dragTarget);
   if (!transArray)
     return false;
 
   // XXXndeakin don't really want to create a new drag DOM event
   // here, but we need something to pass to the InvokeDragSession
   // methods.
   nsCOMPtr<nsIDOMEvent> domEvent;
-  NS_NewDOMDragEvent(getter_AddRefs(domEvent), aPresContext, aDragEvent);
+  NS_NewDOMDragEvent(getter_AddRefs(domEvent), content,
+                     aPresContext, aDragEvent);
 
   nsCOMPtr<nsIDOMDragEvent> domDragEvent = do_QueryInterface(domEvent);
   // if creating a drag event failed, starting a drag session will
   // just fail.
 
   // Use InvokeDragSessionWithSelection if a selection is being dragged,
   // such that the image can be generated from the selected text. However,
   // use InvokeDragSessionWithImage if a custom image was set or something
@@ -2325,17 +2327,16 @@ nsEventStateManager::DoDefaultDragStart(
     // if dragging within a XUL tree and no custom drag image was
     // set, the region argument to InvokeDragSessionWithImage needs
     // to be set to the area encompassing the selected rows of the
     // tree to ensure that the drag feedback gets clipped to those
     // rows. For other content, region should be null.
     nsCOMPtr<nsIScriptableRegion> region;
 #ifdef MOZ_XUL
     if (dragTarget && !dragImage) {
-      nsCOMPtr<nsIContent> content = do_QueryInterface(dragTarget);
       if (content->NodeInfo()->Equals(nsGkAtoms::treechildren,
                                       kNameSpaceID_XUL)) {
         nsTreeBodyFrame* treeBody = do_QueryFrame(content->GetPrimaryFrame());
         if (treeBody) {
           treeBody->GetSelectionRegion(getter_AddRefs(region));
         }
       }
     }
--- a/content/html/content/src/nsHTMLInputElement.cpp
+++ b/content/html/content/src/nsHTMLInputElement.cpp
@@ -4081,17 +4081,18 @@ nsHTMLInputElement::GetPhonetic(nsAStrin
 
 #ifdef ACCESSIBILITY
 /*static*/ nsresult
 FireEventForAccessibility(nsIDOMHTMLInputElement* aTarget,
                           nsPresContext* aPresContext,
                           const nsAString& aEventType)
 {
   nsCOMPtr<nsIDOMEvent> event;
-  if (NS_SUCCEEDED(nsEventDispatcher::CreateEvent(aPresContext, nullptr,
+  nsCOMPtr<mozilla::dom::Element> element = do_QueryInterface(aTarget);
+  if (NS_SUCCEEDED(nsEventDispatcher::CreateEvent(element, aPresContext, nullptr,
                                                   NS_LITERAL_STRING("Events"),
                                                   getter_AddRefs(event)))) {
     event->InitEvent(aEventType, true, true);
     event->SetTrusted(true);
 
     nsEventDispatcher::DispatchDOMEvent(aTarget, nullptr, event, aPresContext, nullptr);
   }
 
--- a/content/html/document/src/nsHTMLDocument.h
+++ b/content/html/document/src/nsHTMLDocument.h
@@ -20,16 +20,17 @@
 
 // Document.Write() related
 #include "nsIWyciwygChannel.h"
 #include "nsILoadGroup.h"
 #include "nsNetUtil.h"
 
 #include "nsICommandManager.h"
 #include "mozilla/dom/HTMLSharedElement.h"
+#include "nsDOMEvent.h"
 
 class nsIEditor;
 class nsIParser;
 class nsIURI;
 class nsIMarkupDocumentViewer;
 class nsIDocShell;
 class nsICachingChannel;
 
@@ -94,16 +95,21 @@ public:
   using nsDocument::GetMozFullScreenElement;
 
   // nsIDOMNode interface
   NS_FORWARD_NSIDOMNODE_TO_NSINODE
 
   // nsIDOMHTMLDocument interface
   NS_DECL_NSIDOMHTMLDOCUMENT
 
+  void RouteEvent(nsDOMEvent& aEvent)
+  {
+    RouteEvent(&aEvent);
+  }
+
   /**
    * Returns the result of document.all[aID] which can either be a node
    * or a nodelist depending on if there are multiple nodes with the same
    * id.
    */
   nsISupports *GetDocumentAllResult(const nsAString& aID,
                                     nsWrapperCache **aCache,
                                     nsresult *aResult);
--- a/content/smil/nsDOMTimeEvent.cpp
+++ b/content/smil/nsDOMTimeEvent.cpp
@@ -4,18 +4,19 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsDOMTimeEvent.h"
 #include "nsGUIEvent.h"
 #include "nsPresContext.h"
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsDOMClassInfoID.h"
 
-nsDOMTimeEvent::nsDOMTimeEvent(nsPresContext* aPresContext, nsEvent* aEvent)
-  : nsDOMEvent(aPresContext, aEvent ? aEvent : new nsUIEvent(false, 0, 0)),
+nsDOMTimeEvent::nsDOMTimeEvent(mozilla::dom::EventTarget* aOwner,
+                               nsPresContext* aPresContext, nsEvent* aEvent)
+  : nsDOMEvent(aOwner, aPresContext, aEvent ? aEvent : new nsUIEvent(false, 0, 0)),
     mDetail(0)
 {
   if (aEvent) {
     mEventIsInternal = false;
   } else {
     mEventIsInternal = true;
     mEvent->eventStructType = NS_SMIL_TIME_EVENT;
   }
@@ -83,14 +84,15 @@ nsDOMTimeEvent::InitTimeEvent(const nsAS
 
   mDetail = aDetailArg;
   mView = aViewArg;
 
   return NS_OK;
 }
 
 nsresult NS_NewDOMTimeEvent(nsIDOMEvent** aInstancePtrResult,
+                            mozilla::dom::EventTarget* aOwner,
                             nsPresContext* aPresContext,
                             nsEvent* aEvent)
 {
-  nsDOMTimeEvent* it = new nsDOMTimeEvent(aPresContext, aEvent);
+  nsDOMTimeEvent* it = new nsDOMTimeEvent(aOwner, aPresContext, aEvent);
   return CallQueryInterface(it, aInstancePtrResult);
 }
--- a/content/smil/nsDOMTimeEvent.h
+++ b/content/smil/nsDOMTimeEvent.h
@@ -8,17 +8,18 @@
 
 #include "nsIDOMTimeEvent.h"
 #include "nsDOMEvent.h"
 
 class nsDOMTimeEvent : public nsDOMEvent,
                        public nsIDOMTimeEvent
 {
 public:
-  nsDOMTimeEvent(nsPresContext* aPresContext, nsEvent* aEvent);
+  nsDOMTimeEvent(mozilla::dom::EventTarget* aOwner,
+                 nsPresContext* aPresContext, nsEvent* aEvent);
                      
   // nsISupports interface:
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsDOMTimeEvent, nsDOMEvent)
 
   // nsIDOMTimeEvent interface:
   NS_DECL_NSIDOMTIMEEVENT
 
--- a/content/svg/content/src/nsDOMSVGEvent.cpp
+++ b/content/svg/content/src/nsDOMSVGEvent.cpp
@@ -4,19 +4,20 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsDOMClassInfoID.h"
 #include "nsDOMSVGEvent.h"
 
 //----------------------------------------------------------------------
 // Implementation
 
-nsDOMSVGEvent::nsDOMSVGEvent(nsPresContext* aPresContext,
+nsDOMSVGEvent::nsDOMSVGEvent(mozilla::dom::EventTarget* aOwner,
+                             nsPresContext* aPresContext,
                              nsEvent* aEvent)
-  : nsDOMEvent(aPresContext,
+  : nsDOMEvent(aOwner, aPresContext,
                aEvent ? aEvent : new nsEvent(false, 0))
 {
   if (aEvent) {
     mEventIsInternal = false;
   }
   else {
     mEventIsInternal = true;
     mEvent->eventStructType = NS_SVG_EVENT;
@@ -42,17 +43,15 @@ NS_INTERFACE_MAP_BEGIN(nsDOMSVGEvent)
 NS_INTERFACE_MAP_END_INHERITING(nsDOMEvent)
 
 
 ////////////////////////////////////////////////////////////////////////
 // Exported creation functions:
 
 nsresult
 NS_NewDOMSVGEvent(nsIDOMEvent** aInstancePtrResult,
+                  mozilla::dom::EventTarget* aOwner,
                   nsPresContext* aPresContext,
                   nsEvent *aEvent)
 {
-  nsDOMSVGEvent* it = new nsDOMSVGEvent(aPresContext, aEvent);
-  if (!it)
-    return NS_ERROR_OUT_OF_MEMORY;
-
+  nsDOMSVGEvent* it = new nsDOMSVGEvent(aOwner, aPresContext, aEvent);
   return CallQueryInterface(it, aInstancePtrResult);
 }
--- a/content/svg/content/src/nsDOMSVGEvent.h
+++ b/content/svg/content/src/nsDOMSVGEvent.h
@@ -11,17 +11,18 @@
 
 class nsEvent;
 class nsPresContext;
 
 class nsDOMSVGEvent : public nsDOMEvent,
                       public nsIDOMSVGEvent
 {
 public:
-  nsDOMSVGEvent(nsPresContext* aPresContext, nsEvent* aEvent);
+  nsDOMSVGEvent(mozilla::dom::EventTarget* aOwner,
+                nsPresContext* aPresContext, nsEvent* aEvent);
 
   // nsISupports interface:
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIDOMSVGEvent interface:
   NS_DECL_NSIDOMSVGEVENT
 
   // Forward to base class
--- a/content/svg/content/src/nsDOMSVGZoomEvent.cpp
+++ b/content/svg/content/src/nsDOMSVGZoomEvent.cpp
@@ -12,19 +12,20 @@
 #include "mozilla/dom/Element.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 //----------------------------------------------------------------------
 // Implementation
 
-nsDOMSVGZoomEvent::nsDOMSVGZoomEvent(nsPresContext* aPresContext,
+nsDOMSVGZoomEvent::nsDOMSVGZoomEvent(mozilla::dom::EventTarget* aOwner,
+                                     nsPresContext* aPresContext,
                                      nsGUIEvent* aEvent)
-  : nsDOMUIEvent(aPresContext,
+  : nsDOMUIEvent(aOwner, aPresContext,
                  aEvent ? aEvent : new nsGUIEvent(false, NS_SVG_ZOOM, 0))
 {
   if (aEvent) {
     mEventIsInternal = false;
   }
   else {
     mEventIsInternal = true;
     mEvent->eventStructType = NS_SVGZOOM_EVENT;
@@ -121,17 +122,15 @@ nsDOMSVGZoomEvent::GetNewTranslate(nsISu
 }
 
 
 ////////////////////////////////////////////////////////////////////////
 // Exported creation functions:
 
 nsresult
 NS_NewDOMSVGZoomEvent(nsIDOMEvent** aInstancePtrResult,
+                      mozilla::dom::EventTarget* aOwner,
                       nsPresContext* aPresContext,
                       nsGUIEvent *aEvent)
 {
-  nsDOMSVGZoomEvent* it = new nsDOMSVGZoomEvent(aPresContext, aEvent);
-  if (!it)
-    return NS_ERROR_OUT_OF_MEMORY;
-
+  nsDOMSVGZoomEvent* it = new nsDOMSVGZoomEvent(aOwner, aPresContext, aEvent);
   return CallQueryInterface(it, aInstancePtrResult);
 }
--- a/content/svg/content/src/nsDOMSVGZoomEvent.h
+++ b/content/svg/content/src/nsDOMSVGZoomEvent.h
@@ -18,17 +18,18 @@ class DOMSVGPoint;
 }
 
 class nsDOMSVGZoomEvent : public nsDOMUIEvent,
                           public nsIDOMSVGZoomEvent
 {
 public:
   typedef mozilla::DOMSVGPoint DOMSVGPoint;
 
-  nsDOMSVGZoomEvent(nsPresContext* aPresContext, nsGUIEvent* aEvent);
+  nsDOMSVGZoomEvent(mozilla::dom::EventTarget* aOwner,
+                    nsPresContext* aPresContext, nsGUIEvent* aEvent);
                      
   // nsISupports interface:
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIDOMSVGZoomEvent interface:
   NS_DECL_NSIDOMSVGZOOMEVENT
 
   // Forward to base class
--- a/dom/base/DOMRequest.cpp
+++ b/dom/base/DOMRequest.cpp
@@ -152,17 +152,18 @@ DOMRequest::FireError(nsresult aError)
 
 void
 DOMRequest::FireEvent(const nsAString& aType, bool aBubble, bool aCancelable)
 {
   if (NS_FAILED(CheckInnerWindowCorrectness())) {
     return;
   }
 
-  nsRefPtr<nsDOMEvent> event = new nsDOMEvent(nullptr, nullptr);
+  nsCOMPtr<nsIDOMEvent> event;
+  NS_NewDOMEvent(getter_AddRefs(event), this, nullptr, nullptr);
   nsresult rv = event->InitEvent(aType, aBubble, aCancelable);
   if (NS_FAILED(rv)) {
     return;
   }
 
   event->SetTrusted(true);
 
   bool dummy;
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -643,47 +643,47 @@ static nsDOMClassInfoData sClassInfoData
   NS_DEFINE_CLASSINFO_DATA(Attr, nsAttributeSH,
                            NODE_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(NamedNodeMap, nsNamedNodeMapSH,
                            ARRAY_SCRIPTABLE_FLAGS)
 
   // Misc Core related classes
 
   // Event
-  NS_DEFINE_CLASSINFO_DATA(Event, nsDOMGenericSH,
-                           DOM_DEFAULT_SCRIPTABLE_FLAGS)
-  NS_DEFINE_CLASSINFO_DATA(MutationEvent, nsDOMGenericSH,
-                           DOM_DEFAULT_SCRIPTABLE_FLAGS)
-  NS_DEFINE_CLASSINFO_DATA(UIEvent, nsDOMGenericSH,
-                           DOM_DEFAULT_SCRIPTABLE_FLAGS)
-  NS_DEFINE_CLASSINFO_DATA(MouseEvent, nsDOMGenericSH,
-                           DOM_DEFAULT_SCRIPTABLE_FLAGS)
-  NS_DEFINE_CLASSINFO_DATA(MouseScrollEvent, nsDOMGenericSH,
-                           DOM_DEFAULT_SCRIPTABLE_FLAGS)
-  NS_DEFINE_CLASSINFO_DATA(WheelEvent, nsDOMGenericSH,
-                           DOM_DEFAULT_SCRIPTABLE_FLAGS)
-  NS_DEFINE_CLASSINFO_DATA(DragEvent, nsDOMGenericSH,
-                           DOM_DEFAULT_SCRIPTABLE_FLAGS)
-  NS_DEFINE_CLASSINFO_DATA(KeyboardEvent, nsDOMGenericSH,
-                           DOM_DEFAULT_SCRIPTABLE_FLAGS)
-  NS_DEFINE_CLASSINFO_DATA(CompositionEvent, nsDOMGenericSH,
+  NS_DEFINE_CLASSINFO_DATA(Event, nsEventSH,
+                           DOM_DEFAULT_SCRIPTABLE_FLAGS)
+  NS_DEFINE_CLASSINFO_DATA(MutationEvent, nsEventSH,
+                           DOM_DEFAULT_SCRIPTABLE_FLAGS)
+  NS_DEFINE_CLASSINFO_DATA(UIEvent, nsEventSH,
+                           DOM_DEFAULT_SCRIPTABLE_FLAGS)
+  NS_DEFINE_CLASSINFO_DATA(MouseEvent, nsEventSH,
+                           DOM_DEFAULT_SCRIPTABLE_FLAGS)
+  NS_DEFINE_CLASSINFO_DATA(MouseScrollEvent, nsEventSH,
+                           DOM_DEFAULT_SCRIPTABLE_FLAGS)
+  NS_DEFINE_CLASSINFO_DATA(WheelEvent, nsEventSH,
+                           DOM_DEFAULT_SCRIPTABLE_FLAGS)
+  NS_DEFINE_CLASSINFO_DATA(DragEvent, nsEventSH,
+                           DOM_DEFAULT_SCRIPTABLE_FLAGS)
+  NS_DEFINE_CLASSINFO_DATA(KeyboardEvent, nsEventSH,
+                           DOM_DEFAULT_SCRIPTABLE_FLAGS)
+  NS_DEFINE_CLASSINFO_DATA(CompositionEvent, nsEventSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
 
 #define MOZ_GENERATED_EVENT_LIST
-#define MOZ_GENERATED_EVENT(_event_interface)                \
-  NS_DEFINE_CLASSINFO_DATA(_event_interface, nsDOMGenericSH, \
+#define MOZ_GENERATED_EVENT(_event_interface)             \
+  NS_DEFINE_CLASSINFO_DATA(_event_interface, nsEventSH,   \
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
 #include "GeneratedEvents.h"
 #undef MOZ_GENERATED_EVENT_LIST
 
-  NS_DEFINE_CLASSINFO_DATA(DeviceMotionEvent, nsDOMGenericSH,
-                           DOM_DEFAULT_SCRIPTABLE_FLAGS)
-  NS_DEFINE_CLASSINFO_DATA(DeviceAcceleration, nsDOMGenericSH,
-                           DOM_DEFAULT_SCRIPTABLE_FLAGS)
-  NS_DEFINE_CLASSINFO_DATA(DeviceRotationRate, nsDOMGenericSH,
+  NS_DEFINE_CLASSINFO_DATA(DeviceMotionEvent, nsEventSH,
+                           DOM_DEFAULT_SCRIPTABLE_FLAGS)
+  NS_DEFINE_CLASSINFO_DATA(DeviceAcceleration, nsEventSH,
+                           DOM_DEFAULT_SCRIPTABLE_FLAGS)
+  NS_DEFINE_CLASSINFO_DATA(DeviceRotationRate, nsEventSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
 
   // Misc HTML classes
   NS_DEFINE_CLASSINFO_DATA(HTMLDocument, nsHTMLDocumentSH,
                            DOCUMENT_SCRIPTABLE_FLAGS |
                            nsIXPCScriptable::WANT_GETPROPERTY)
   // HTML element classes
   NS_DEFINE_CLASSINFO_DATA(HTMLAppletElement, nsHTMLPluginObjElementSH,
@@ -801,25 +801,25 @@ static nsDOMClassInfoData sClassInfoData
 #endif
 
   NS_DEFINE_CLASSINFO_DATA(CSSMozDocumentRule, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
 
   NS_DEFINE_CLASSINFO_DATA(CSSSupportsRule, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
 
-  NS_DEFINE_CLASSINFO_DATA(BeforeUnloadEvent, nsDOMGenericSH,
+  NS_DEFINE_CLASSINFO_DATA(BeforeUnloadEvent, nsEventSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
 
   // SVG document
   NS_DEFINE_CLASSINFO_DATA(SVGDocument, nsDocumentSH,
                            DOCUMENT_SCRIPTABLE_FLAGS)
 
   // SVG element classes
-  NS_DEFINE_CLASSINFO_DATA(TimeEvent, nsDOMGenericSH,
+  NS_DEFINE_CLASSINFO_DATA(TimeEvent, nsEventSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(SVGFEColorMatrixElement, nsElementSH,
                            ELEMENT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(SVGFEComponentTransferElement, nsElementSH,
                            ELEMENT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(SVGFECompositeElement, nsElementSH,
                            ELEMENT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(SVGFEConvolveMatrixElement, nsElementSH,
@@ -855,27 +855,27 @@ static nsDOMClassInfoData sClassInfoData
   NS_DEFINE_CLASSINFO_DATA(SVGAnimatedInteger, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(SVGAnimatedNumber, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(SVGAnimatedRect, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(SVGAnimatedString, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
-  NS_DEFINE_CLASSINFO_DATA(SVGEvent, nsDOMGenericSH,
+  NS_DEFINE_CLASSINFO_DATA(SVGEvent, nsEventSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(SVGLength, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(SVGNumber, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(SVGRect, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(SVGStringList, nsSVGStringListSH,
                            ARRAY_SCRIPTABLE_FLAGS)
-  NS_DEFINE_CLASSINFO_DATA(SVGZoomEvent, nsDOMGenericSH,
+  NS_DEFINE_CLASSINFO_DATA(SVGZoomEvent, nsEventSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
 
   NS_DEFINE_CLASSINFO_DATA(HTMLCanvasElement, nsElementSH,
                            ELEMENT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(CanvasGradient, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(CanvasPattern, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
@@ -915,20 +915,20 @@ static nsDOMClassInfoData sClassInfoData
                            nsIXPCScriptable::DONT_ENUM_STATIC_PROPS |
                            nsIXPCScriptable::WANT_NEWENUMERATE)
   NS_DEFINE_CLASSINFO_DATA(StorageItem, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
 
   NS_DEFINE_CLASSINFO_DATA(ClientRect, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
 
-  NS_DEFINE_CLASSINFO_DATA(XULCommandEvent, nsDOMGenericSH,
-                           DOM_DEFAULT_SCRIPTABLE_FLAGS)
-
-  NS_DEFINE_CLASSINFO_DATA(CommandEvent, nsDOMGenericSH,
+  NS_DEFINE_CLASSINFO_DATA(XULCommandEvent, nsEventSH,
+                           DOM_DEFAULT_SCRIPTABLE_FLAGS)
+
+  NS_DEFINE_CLASSINFO_DATA(CommandEvent, nsEventSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(OfflineResourceList, nsOfflineResourceListSH,
                            ARRAY_SCRIPTABLE_FLAGS)
 
   NS_DEFINE_CLASSINFO_DATA(Blob, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(File, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
@@ -938,20 +938,20 @@ static nsDOMClassInfoData sClassInfoData
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(ArchiveRequest, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
 
   NS_DEFINE_CLASSINFO_DATA(ModalContentWindow, nsWindowSH,
                            DEFAULT_SCRIPTABLE_FLAGS |
                            WINDOW_SCRIPTABLE_FLAGS)
 
-  NS_DEFINE_CLASSINFO_DATA(DataContainerEvent, nsDOMGenericSH,
-                           DOM_DEFAULT_SCRIPTABLE_FLAGS)
-
-  NS_DEFINE_CLASSINFO_DATA(MessageEvent, nsDOMGenericSH,
+  NS_DEFINE_CLASSINFO_DATA(DataContainerEvent, nsEventSH,
+                           DOM_DEFAULT_SCRIPTABLE_FLAGS)
+
+  NS_DEFINE_CLASSINFO_DATA(MessageEvent, nsEventSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
 
   NS_DEFINE_CLASSINFO_DATA(DeviceStorage, nsEventTargetSH,
                            EVENTTARGET_SCRIPTABLE_FLAGS)
 
   NS_DEFINE_CLASSINFO_DATA(DeviceStorageCursor, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
 
@@ -1017,32 +1017,32 @@ static nsDOMClassInfoData sClassInfoData
   // DOM Traversal NodeIterator class
   NS_DEFINE_CLASSINFO_DATA(NodeIterator, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
 
   // data transfer for drag and drop
   NS_DEFINE_CLASSINFO_DATA(DataTransfer, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
 
-  NS_DEFINE_CLASSINFO_DATA(NotifyPaintEvent, nsDOMGenericSH,
-                           DOM_DEFAULT_SCRIPTABLE_FLAGS)
-
-  NS_DEFINE_CLASSINFO_DATA(NotifyAudioAvailableEvent, nsDOMGenericSH,
-                           DOM_DEFAULT_SCRIPTABLE_FLAGS)
-
-  NS_DEFINE_CLASSINFO_DATA(SimpleGestureEvent, nsDOMGenericSH,
-                           DOM_DEFAULT_SCRIPTABLE_FLAGS)
-
-  NS_DEFINE_CLASSINFO_DATA(ScrollAreaEvent, nsDOMGenericSH,
+  NS_DEFINE_CLASSINFO_DATA(NotifyPaintEvent, nsEventSH,
+                           DOM_DEFAULT_SCRIPTABLE_FLAGS)
+
+  NS_DEFINE_CLASSINFO_DATA(NotifyAudioAvailableEvent, nsEventSH,
+                           DOM_DEFAULT_SCRIPTABLE_FLAGS)
+
+  NS_DEFINE_CLASSINFO_DATA(SimpleGestureEvent, nsEventSH,
+                           DOM_DEFAULT_SCRIPTABLE_FLAGS)
+
+  NS_DEFINE_CLASSINFO_DATA(ScrollAreaEvent, nsEventSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(EventListenerInfo, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
-  NS_DEFINE_CLASSINFO_DATA(TransitionEvent, nsDOMGenericSH,
-                           DOM_DEFAULT_SCRIPTABLE_FLAGS)
-  NS_DEFINE_CLASSINFO_DATA(AnimationEvent, nsDOMGenericSH,
+  NS_DEFINE_CLASSINFO_DATA(TransitionEvent, nsEventSH,
+                           DOM_DEFAULT_SCRIPTABLE_FLAGS)
+  NS_DEFINE_CLASSINFO_DATA(AnimationEvent, nsEventSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CHROME_ONLY_CLASSINFO_DATA(ContentFrameMessageManager, nsEventTargetSH,
                                        DOM_DEFAULT_SCRIPTABLE_FLAGS |
                                        nsIXPCScriptable::IS_GLOBAL_OBJECT)
   NS_DEFINE_CHROME_ONLY_CLASSINFO_DATA(ChromeMessageBroadcaster, nsDOMGenericSH,
                                        DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CHROME_ONLY_CLASSINFO_DATA(ChromeMessageSender, nsDOMGenericSH,
                                        DOM_DEFAULT_SCRIPTABLE_FLAGS)
@@ -1067,26 +1067,26 @@ static nsDOMClassInfoData sClassInfoData
   NS_DEFINE_CLASSINFO_DATA(IDBCursor, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(IDBCursorWithValue, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(IDBKeyRange, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(IDBIndex, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
-  NS_DEFINE_CLASSINFO_DATA(IDBVersionChangeEvent, nsDOMGenericSH,
+  NS_DEFINE_CLASSINFO_DATA(IDBVersionChangeEvent, nsEventSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(IDBOpenDBRequest, IDBEventTargetSH,
                            IDBEVENTTARGET_SCRIPTABLE_FLAGS)
 
   NS_DEFINE_CLASSINFO_DATA(Touch, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(TouchList, nsDOMTouchListSH,
                            ARRAY_SCRIPTABLE_FLAGS)
-  NS_DEFINE_CLASSINFO_DATA(TouchEvent, nsDOMGenericSH,
+  NS_DEFINE_CLASSINFO_DATA(TouchEvent, nsEventSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
 
   NS_DEFINE_CLASSINFO_DATA(MozCSSKeyframeRule, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(MozCSSKeyframesRule, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
 
   NS_DEFINE_CLASSINFO_DATA(CSSPageRule, nsDOMGenericSH,
@@ -1099,17 +1099,17 @@ static nsDOMClassInfoData sClassInfoData
   NS_DEFINE_CLASSINFO_DATA(Telephony, nsEventTargetSH,
                            EVENTTARGET_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(TelephonyCall, nsEventTargetSH,
                            EVENTTARGET_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(MozVoicemail, nsEventTargetSH,
                            EVENTTARGET_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(MozIccManager, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
-  NS_DEFINE_CLASSINFO_DATA(MozStkCommandEvent, nsDOMGenericSH,
+  NS_DEFINE_CLASSINFO_DATA(MozStkCommandEvent, nsEventSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
 #endif
 
 #ifdef MOZ_B2G_FM
   NS_DEFINE_CLASSINFO_DATA(FMRadio, nsEventTargetSH,
                            EVENTTARGET_SCRIPTABLE_FLAGS)
 #endif
 
@@ -1180,27 +1180,26 @@ NS_DEFINE_CONTRACT_CTOR(ArchiveReader, N
 NS_DEFINE_CONTRACT_CTOR(XSLTProcessor,
                         "@mozilla.org/document-transformer;1?type=xslt")
 #ifdef MOZ_SYS_MSG
 NS_DEFINE_CONTRACT_CTOR(MozActivity, NS_DOMACTIVITY_CONTRACTID)
 #endif
 
 #undef NS_DEFINE_CONTRACT_CTOR
 
-#define NS_DEFINE_EVENT_CTOR(_class)                        \
-  static nsresult                                           \
-  NS_DOM##_class##Ctor(nsISupports** aInstancePtrResult)    \
-  {                                                         \
-    nsIDOMEvent* e = nullptr;                               \
-    nsresult rv = NS_NewDOM##_class(&e, nullptr, nullptr);  \
-    *aInstancePtrResult = e;                                \
-    return rv;                                              \
-  }
-
-NS_DEFINE_EVENT_CTOR(Event)
+#define NS_DEFINE_EVENT_CTOR(_class)                                 \
+  static nsresult                                                    \
+  NS_DOM##_class##Ctor(nsISupports** aInstancePtrResult)             \
+  {                                                                  \
+    nsIDOMEvent* e = nullptr;                                        \
+    nsresult rv = NS_NewDOM##_class(&e, nullptr, nullptr, nullptr);  \
+    *aInstancePtrResult = e;                                         \
+    return rv;                                                       \
+  }
+
 NS_DEFINE_EVENT_CTOR(UIEvent)
 NS_DEFINE_EVENT_CTOR(MouseEvent)
 NS_DEFINE_EVENT_CTOR(WheelEvent)
 
 #define MOZ_GENERATED_EVENT_LIST
 #define MOZ_GENERATED_EVENT(_event_interface) \
   NS_DEFINE_EVENT_CTOR(_event_interface)
 #include "GeneratedEvents.h"
@@ -1217,17 +1216,16 @@ struct nsConstructorFuncMapData
 
 #define NS_DEFINE_EVENT_CONSTRUCTOR_FUNC_DATA(_class)   \
   { eDOMClassInfo_##_class##_id, NS_DOM##_class##Ctor },
 
 static const nsConstructorFuncMapData kConstructorFuncMap[] =
 {
   NS_DEFINE_CONSTRUCTOR_FUNC_DATA(Blob, nsDOMMultipartFile::NewBlob)
   NS_DEFINE_CONSTRUCTOR_FUNC_DATA(File, nsDOMMultipartFile::NewFile)
-  NS_DEFINE_EVENT_CONSTRUCTOR_FUNC_DATA(Event)
   NS_DEFINE_EVENT_CONSTRUCTOR_FUNC_DATA(UIEvent)
   NS_DEFINE_EVENT_CONSTRUCTOR_FUNC_DATA(MouseEvent)
   NS_DEFINE_EVENT_CONSTRUCTOR_FUNC_DATA(WheelEvent)
 #ifdef MOZ_B2G_RIL
   NS_DEFINE_EVENT_CONSTRUCTOR_FUNC_DATA(MozWifiStatusChangeEvent)
   NS_DEFINE_EVENT_CONSTRUCTOR_FUNC_DATA(MozWifiConnectionInfoEvent)
 #endif
 #define MOZ_GENERATED_EVENT_LIST
@@ -6176,16 +6174,49 @@ nsEventTargetSH::AddProperty(nsIXPConnec
 void
 nsEventTargetSH::PreserveWrapper(nsISupports *aNative)
 {
   nsDOMEventTargetHelper *target =
     nsDOMEventTargetHelper::FromSupports(aNative);
   nsContentUtils::PreserveWrapper(aNative, target);
 }
 
+// Event helper
+
+NS_IMETHODIMP
+nsEventSH::PreCreate(nsISupports* aNativeObj, JSContext* aCx,
+                     JSObject* aGlobalObj, JSObject** aParentObj)
+{
+  nsDOMEvent* event =
+    nsDOMEvent::FromSupports(aNativeObj);
+
+  nsCOMPtr<nsIScriptGlobalObject> native_parent;
+  event->GetParentObject(getter_AddRefs(native_parent));
+
+  *aParentObj = native_parent ? native_parent->GetGlobalJSObject() : aGlobalObj;
+
+  return *aParentObj ? NS_OK : NS_ERROR_FAILURE;
+}
+
+NS_IMETHODIMP
+nsEventSH::AddProperty(nsIXPConnectWrappedNative* aWrapper, JSContext* aCx,
+                       JSObject* aObj, jsid Id, jsval* aVp, bool* aRetval)
+{
+  nsEventSH::PreserveWrapper(GetNative(aWrapper, aObj));
+  return NS_OK;
+}
+
+void
+nsEventSH::PreserveWrapper(nsISupports* aNative)
+{
+  nsDOMEvent* event =
+    nsDOMEvent::FromSupports(aNative);
+  nsContentUtils::PreserveWrapper(aNative, event);
+}
+
 // IDBFactory helper
 
 /* static */
 template<nsresult (*func)(JSContext *, unsigned, jsval *, bool), bool aDelete>
 JSBool
 IDBFNativeShim(JSContext *cx, unsigned argc, jsval *vp)
 {
   nsresult rv = (*func)(cx, argc, vp, aDelete);
--- a/dom/base/nsDOMClassInfo.h
+++ b/dom/base/nsDOMClassInfo.h
@@ -297,16 +297,41 @@ public:
   virtual void PreserveWrapper(nsISupports *aNative);
 
   static nsIClassInfo *doCreate(nsDOMClassInfoData* aData)
   {
     return new nsEventTargetSH(aData);
   }
 };
 
+// Makes sure that the wrapper is preserved if new properties are added.
+class nsEventSH : public nsDOMGenericSH
+{
+protected:
+  nsEventSH(nsDOMClassInfoData* aData) : nsDOMGenericSH(aData)
+  {
+  }
+
+  virtual ~nsEventSH()
+  {
+  }
+public:
+  NS_IMETHOD PreCreate(nsISupports* aNativeObj, JSContext* aCx,
+                       JSObject* aGlobalObj, JSObject** aParentObj);
+  NS_IMETHOD AddProperty(nsIXPConnectWrappedNative* aWrapper, JSContext* aCx,
+                         JSObject* aObj, jsid Id, jsval* aVp, bool* aRetval);
+
+  virtual void PreserveWrapper(nsISupports *aNative);
+
+  static nsIClassInfo *doCreate(nsDOMClassInfoData* aData)
+  {
+    return new nsEventSH(aData);
+  }
+};
+
 // Window scriptable helper
 
 class nsWindowSH : public nsDOMGenericSH
 {
 protected:
   nsWindowSH(nsDOMClassInfoData *aData) : nsDOMGenericSH(aData)
   {
   }
--- a/dom/base/nsDOMClassInfoID.h
+++ b/dom/base/nsDOMClassInfoID.h
@@ -49,16 +49,17 @@ enum nsDOMClassInfoID {
 #undef DOMCI_CASTABLE_INTERFACE
 #define DOMCI_CASTABLE_INTERFACES(_extra)                                     \
 DOMCI_CASTABLE_INTERFACE(nsINode, nsINode, 0, _extra)                         \
 DOMCI_CASTABLE_NODECL_INTERFACE(mozilla::dom::Element,  mozilla::dom::Element,\
                                 1, _extra)                                    \
 /* If this is ever removed, the IID for EventTarget can go away */            \
 DOMCI_CASTABLE_NODECL_INTERFACE(mozilla::dom::EventTarget,                    \
                                 mozilla::dom::EventTarget, 2, _extra)         \
+DOMCI_CASTABLE_INTERFACE(nsDOMEvent, nsIDOMEvent, 3, _extra)                  \
 DOMCI_CASTABLE_INTERFACE(nsIDocument, nsIDocument, 4, _extra)                 \
 DOMCI_CASTABLE_INTERFACE(nsDocument, nsIDocument, 5, _extra)                  \
 DOMCI_CASTABLE_INTERFACE(nsGenericHTMLElement, nsGenericHTMLElement, 6,       \
                          _extra)                                              \
 DOMCI_CASTABLE_INTERFACE(nsHTMLDocument, nsIDocument, 7, _extra)              \
 DOMCI_CASTABLE_INTERFACE(nsStyledElement, nsStyledElement, 8, _extra)         \
 DOMCI_CASTABLE_INTERFACE(nsSVGElement, nsIContent, 9, _extra)
 
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -8321,17 +8321,17 @@ nsGlobalWindow::FireHashchange(const nsA
   nsRefPtr<nsPresContext> presContext;
   if (shell) {
     presContext = shell->GetPresContext();
   }
 
   // Create a new hashchange event.
   nsCOMPtr<nsIDOMEvent> domEvent;
   nsresult rv =
-    nsEventDispatcher::CreateEvent(presContext, nullptr,
+    nsEventDispatcher::CreateEvent(this, presContext, nullptr,
                                    NS_LITERAL_STRING("hashchangeevent"),
                                    getter_AddRefs(domEvent));
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsCOMPtr<nsIDOMHashChangeEvent> hashchangeEvent = do_QueryInterface(domEvent);
   NS_ENSURE_TRUE(hashchangeEvent, NS_ERROR_UNEXPECTED);
 
   // The hashchange event bubbles and isn't cancellable.
@@ -8377,17 +8377,17 @@ nsGlobalWindow::DispatchSyncPopState()
   nsIPresShell *shell = mDoc->GetShell();
   nsRefPtr<nsPresContext> presContext;
   if (shell) {
     presContext = shell->GetPresContext();
   }
 
   // Create a new popstate event
   nsCOMPtr<nsIDOMEvent> domEvent;
-  rv = nsEventDispatcher::CreateEvent(presContext, nullptr,
+  rv = nsEventDispatcher::CreateEvent(this, presContext, nullptr,
                                       NS_LITERAL_STRING("popstateevent"),
                                       getter_AddRefs(domEvent));
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Initialize the popstate event, which does bubble but isn't cancellable.
   nsCOMPtr<nsIDOMPopStateEvent> popstateEvent = do_QueryInterface(domEvent);
   rv = popstateEvent->InitPopStateEvent(NS_LITERAL_STRING("popstate"),
                                         true, false,
@@ -9364,17 +9364,18 @@ nsGlobalWindow::Observe(nsISupports* aSu
       observer->Observe(aSubject, aTopic, aData);
 
     return NS_OK;
   }
 
 #ifdef MOZ_B2G
   if (!nsCRT::strcmp(aTopic, NS_NETWORK_ACTIVITY_BLIP_UPLOAD_TOPIC) ||
       !nsCRT::strcmp(aTopic, NS_NETWORK_ACTIVITY_BLIP_DOWNLOAD_TOPIC)) {
-    nsRefPtr<nsDOMEvent> event = new nsDOMEvent(nullptr, nullptr);
+    nsCOMPtr<nsIDOMEvent> event;
+    NS_NewDOMEvent(getter_AddRefs(event), this, nullptr, nullptr);
     nsresult rv = event->InitEvent(
       !nsCRT::strcmp(aTopic, NS_NETWORK_ACTIVITY_BLIP_UPLOAD_TOPIC)
         ? NETWORK_UPLOAD_EVENT_NAME
         : NETWORK_DOWNLOAD_EVENT_NAME,
       false, false);
     NS_ENSURE_SUCCESS(rv, rv);
 
     event->SetTrusted(true);
@@ -9409,17 +9410,17 @@ nsGlobalWindow::CloneStorageEvent(const 
   domEvent->GetCancelable(&cancelable);
 
   aEvent->GetKey(key);
   aEvent->GetOldValue(oldValue);
   aEvent->GetNewValue(newValue);
   aEvent->GetUrl(url);
   aEvent->GetStorageArea(getter_AddRefs(storageArea));
 
-  NS_NewDOMStorageEvent(getter_AddRefs(domEvent), nullptr, nullptr);
+  NS_NewDOMStorageEvent(getter_AddRefs(domEvent), this, nullptr, nullptr);
   aEvent = do_QueryInterface(domEvent);
   return aEvent->InitStorageEvent(aType, canBubble, cancelable,
                                   key, oldValue, newValue,
                                   url, storageArea);
 }
 
 nsresult
 nsGlobalWindow::FireDelayedDOMEvents()
--- a/dom/bindings/BindingUtils.h
+++ b/dom/bindings/BindingUtils.h
@@ -980,16 +980,23 @@ WrapObject(JSContext* cx, JSObject* scop
 template<>
 inline bool
 WrapObject<JSObject>(JSContext* cx, JSObject* scope, JSObject* p, JS::Value* vp)
 {
   vp->setObjectOrNull(p);
   return true;
 }
 
+inline bool
+WrapObject(JSContext* cx, JSObject* scope, JSObject& p, JS::Value* vp)
+{
+  vp->setObject(p);
+  return true;
+}
+
 bool
 WrapCallbackInterface(JSContext *cx, JSObject *scope, nsISupports* callback,
                       JS::Value* vp);
 
 static inline bool
 WrapCallbackInterface(JSContext *cx, JSObject *scope, nsISupports& callback,
                       JS::Value* vp)
 {
--- a/dom/bindings/Bindings.conf
+++ b/dom/bindings/Bindings.conf
@@ -251,17 +251,23 @@ DOMInterfaces = {
         'classList', 'attributes', 'children', 'firstElementChild',
         'lastElementChild', 'previousElementSibling', 'nextElementSibling',
         'getAttributeNode', 'getAttributeNodeNS', 'querySelector'
     ]
 },
 
 'Event': [
 {
+    'nativeType': 'nsDOMEvent',
+    'hasXPConnectImpls': True
+},
+{
+    'nativeType': 'JSObject',
     'workers': True,
+    'skipGen': True
 }],
 
 'EventListener': [
 {
     'nativeType': 'nsIDOMEventListener'
 },
 {
     'workers': True,
--- a/dom/bluetooth/BluetoothAdapter.cpp
+++ b/dom/bluetooth/BluetoothAdapter.cpp
@@ -276,41 +276,41 @@ BluetoothAdapter::Notify(const Bluetooth
   InfallibleTArray<BluetoothNamedValue> arr;
 
   BT_LOG("[A] %s: %s", __FUNCTION__, NS_ConvertUTF16toUTF8(aData.name()).get());
 
   BluetoothValue v = aData.value();
   if (aData.name().EqualsLiteral("DeviceFound")) {
     nsRefPtr<BluetoothDevice> device = BluetoothDevice::Create(GetOwner(), mPath, aData.value());
     nsCOMPtr<nsIDOMEvent> event;
-    NS_NewDOMBluetoothDeviceEvent(getter_AddRefs(event), nullptr, nullptr);
+    NS_NewDOMBluetoothDeviceEvent(getter_AddRefs(event), this, nullptr, nullptr);
 
     nsCOMPtr<nsIDOMBluetoothDeviceEvent> e = do_QueryInterface(event);
     e->InitBluetoothDeviceEvent(NS_LITERAL_STRING("devicefound"),
                                 false, false, device);
     DispatchTrustedEvent(event);
   } else if (aData.name().EqualsLiteral("DeviceDisappeared")) {
     const nsAString& deviceAddress = aData.value().get_nsString();
 
     nsCOMPtr<nsIDOMEvent> event;
-    NS_NewDOMBluetoothDeviceAddressEvent(getter_AddRefs(event), nullptr, nullptr);
+    NS_NewDOMBluetoothDeviceAddressEvent(getter_AddRefs(event), this, nullptr, nullptr);
 
     nsCOMPtr<nsIDOMBluetoothDeviceAddressEvent> e = do_QueryInterface(event);
     e->InitBluetoothDeviceAddressEvent(NS_LITERAL_STRING("devicedisappeared"),
                                        false, false, deviceAddress);
     DispatchTrustedEvent(e);
   } else if (aData.name().EqualsLiteral("DeviceCreated")) {
     NS_ASSERTION(aData.value().type() == BluetoothValue::TArrayOfBluetoothNamedValue,
                  "DeviceCreated: Invalid value type");
 
     nsRefPtr<BluetoothDevice> device = BluetoothDevice::Create(GetOwner(),
                                                                GetPath(),
                                                                aData.value());
     nsCOMPtr<nsIDOMEvent> event;
-    NS_NewDOMBluetoothDeviceEvent(getter_AddRefs(event), nullptr, nullptr);
+    NS_NewDOMBluetoothDeviceEvent(getter_AddRefs(event), this, nullptr, nullptr);
 
     nsCOMPtr<nsIDOMBluetoothDeviceEvent> e = do_QueryInterface(event);
     e->InitBluetoothDeviceEvent(NS_LITERAL_STRING("devicecreated"),
                                 false, false, device);
     DispatchTrustedEvent(e);
   } else if (aData.name().EqualsLiteral("PropertyChanged")) {
     NS_ASSERTION(v.type() == BluetoothValue::TArrayOfBluetoothNamedValue,
                  "PropertyChanged: Invalid value type");
--- a/dom/browser-element/BrowserElementParent.cpp
+++ b/dom/browser-element/BrowserElementParent.cpp
@@ -77,17 +77,17 @@ DispatchCustomDOMEvent(Element* aFrameEl
   NS_ENSURE_TRUE(aFrameElement, false);
   nsIPresShell *shell = aFrameElement->OwnerDoc()->GetShell();
   nsRefPtr<nsPresContext> presContext;
   if (shell) {
     presContext = shell->GetPresContext();
   }
 
   nsCOMPtr<nsIDOMEvent> domEvent;
-  nsEventDispatcher::CreateEvent(presContext, nullptr,
+  nsEventDispatcher::CreateEvent(aFrameElement, presContext, nullptr,
                                  NS_LITERAL_STRING("customevent"),
                                  getter_AddRefs(domEvent));
   NS_ENSURE_TRUE(domEvent, false);
 
   nsCOMPtr<nsIWritableVariant> detailVariant = new nsVariant();
   nsresult rv = detailVariant->SetAsISupports(aDetailValue);
   NS_ENSURE_SUCCESS(rv, false);
   nsCOMPtr<nsIDOMCustomEvent> customEvent = do_QueryInterface(domEvent);
--- a/dom/cellbroadcast/src/CellBroadcast.cpp
+++ b/dom/cellbroadcast/src/CellBroadcast.cpp
@@ -79,17 +79,17 @@ CellBroadcast::~CellBroadcast()
 NS_IMPL_EVENT_HANDLER(CellBroadcast, received)
 
 // Forwarded nsICellBroadcastListener methods
 
 NS_IMETHODIMP
 CellBroadcast::NotifyMessageReceived(nsIDOMMozCellBroadcastMessage* aMessage)
 {
   nsCOMPtr<nsIDOMEvent> event;
-  NS_NewDOMMozCellBroadcastEvent(getter_AddRefs(event), nullptr, nullptr);
+  NS_NewDOMMozCellBroadcastEvent(getter_AddRefs(event), this, nullptr, nullptr);
 
   nsCOMPtr<nsIDOMMozCellBroadcastEvent> ce = do_QueryInterface(event);
   nsresult rv = ce->InitMozCellBroadcastEvent(NS_LITERAL_STRING("received"),
                                               true, false, aMessage);
   NS_ENSURE_SUCCESS(rv, rv);
 
   return DispatchTrustedEvent(ce);
 }
--- a/dom/devicestorage/nsDeviceStorage.cpp
+++ b/dom/devicestorage/nsDeviceStorage.cpp
@@ -2258,17 +2258,17 @@ nsDOMDeviceStorage::EnumerateInternal(co
   return NS_OK;
 }
 
 #ifdef MOZ_WIDGET_GONK
 void
 nsDOMDeviceStorage::DispatchMountChangeEvent(nsAString& aType)
 {
   nsCOMPtr<nsIDOMEvent> event;
-  NS_NewDOMDeviceStorageChangeEvent(getter_AddRefs(event), nullptr, nullptr);
+  NS_NewDOMDeviceStorageChangeEvent(getter_AddRefs(event), this, nullptr, nullptr);
 
   nsCOMPtr<nsIDOMDeviceStorageChangeEvent> ce = do_QueryInterface(event);
   nsresult rv = ce->InitDeviceStorageChangeEvent(NS_LITERAL_STRING("change"),
                                                  true, false,
                                                  NS_LITERAL_STRING(""),
                                                  aType);
   if (NS_FAILED(rv)) {
     return;
@@ -2354,17 +2354,18 @@ nsDOMDeviceStorage::Notify(const char* a
   }
 
   NS_ASSERTION(fullpath.Length() >= rootpath.Length(), "Root path longer than full path!");
 
   nsAString::size_type len = rootpath.Length() + 1; // +1 for the trailing /
   nsDependentSubstring newPath (fullpath, len, fullpath.Length() - len);
 
   nsCOMPtr<nsIDOMEvent> event;
-  NS_NewDOMDeviceStorageChangeEvent(getter_AddRefs(event), nullptr, nullptr);
+  NS_NewDOMDeviceStorageChangeEvent(getter_AddRefs(event), this,
+                                    nullptr, nullptr);
 
   nsCOMPtr<nsIDOMDeviceStorageChangeEvent> ce = do_QueryInterface(event);
 
   nsString reason;
   reason.AssignWithConversion(aReason);
   rv = ce->InitDeviceStorageChangeEvent(NS_LITERAL_STRING("change"), true, false, newPath, reason);
   NS_ENSURE_SUCCESS(rv, rv);
 
--- a/dom/file/FileRequest.cpp
+++ b/dom/file/FileRequest.cpp
@@ -126,17 +126,18 @@ NS_IMPL_EVENT_HANDLER(FileRequest, progr
 void
 FileRequest::FireProgressEvent(uint64_t aLoaded, uint64_t aTotal)
 {
   if (NS_FAILED(CheckInnerWindowCorrectness())) {
     return;
   }
 
   nsCOMPtr<nsIDOMEvent> event;
-  nsresult rv = NS_NewDOMProgressEvent(getter_AddRefs(event), nullptr, nullptr);
+  nsresult rv = NS_NewDOMProgressEvent(getter_AddRefs(event), this,
+                                       nullptr, nullptr);
   if (NS_FAILED(rv)) {
     return;
   }
 
   nsCOMPtr<nsIDOMProgressEvent> progress = do_QueryInterface(event);
   MOZ_ASSERT(progress);
   rv = progress->InitProgressEvent(NS_LITERAL_STRING("progress"), false, false,
                                    false, aLoaded, aTotal);
--- a/dom/file/LockedFile.cpp
+++ b/dom/file/LockedFile.cpp
@@ -192,20 +192,22 @@ public:
 private:
   bool mWholeFile;
   uint64_t mStart;
   uint64_t mLength;
 
   nsCOMPtr<nsIInputStream> mStream;
 };
 
-already_AddRefed<nsDOMEvent>
-CreateGenericEvent(const nsAString& aType, bool aBubbles, bool aCancelable)
+already_AddRefed<nsIDOMEvent>
+CreateGenericEvent(mozilla::dom::EventTarget* aEventOwner,
+                   const nsAString& aType, bool aBubbles, bool aCancelable)
 {
-  nsRefPtr<nsDOMEvent> event(new nsDOMEvent(nullptr, nullptr));
+  nsCOMPtr<nsIDOMEvent> event;
+  NS_NewDOMEvent(getter_AddRefs(event), aEventOwner, nullptr, nullptr);
   nsresult rv = event->InitEvent(aType, aBubbles, aCancelable);
   NS_ENSURE_SUCCESS(rv, nullptr);
 
   event->SetTrusted(true);
 
   return event.forget();
 }
 
@@ -924,20 +926,22 @@ FinishHelper::Run()
 
     FileService* service = FileService::Get();
     if (service) {
       service->NotifyLockedFileCompleted(mLockedFile);
     }
 
     nsCOMPtr<nsIDOMEvent> event;
     if (mAborted) {
-      event = CreateGenericEvent(NS_LITERAL_STRING("abort"), true, false);
+      event = CreateGenericEvent(mLockedFile, NS_LITERAL_STRING("abort"),
+                                 true, false);
     }
     else {
-      event = CreateGenericEvent(NS_LITERAL_STRING("complete"), false, false);
+      event = CreateGenericEvent(mLockedFile, NS_LITERAL_STRING("complete"),
+                                 false, false);
     }
     NS_ENSURE_TRUE(event, NS_ERROR_DOM_FILEHANDLE_UNKNOWN_ERR);
 
     bool dummy;
     if (NS_FAILED(mLockedFile->DispatchEvent(event, &dummy))) {
       NS_WARNING("Dispatch failed!");
     }
 
--- a/dom/icc/src/IccManager.cpp
+++ b/dom/icc/src/IccManager.cpp
@@ -161,17 +161,17 @@ IccManager::IccCloseChannel(int32_t aCha
 NS_IMPL_EVENT_HANDLER(IccManager, stkcommand)
 NS_IMPL_EVENT_HANDLER(IccManager, stksessionend)
 
 // nsIIccListener
 
 NS_IMETHODIMP
 IccManager::NotifyStkCommand(const nsAString& aMessage)
 {
-  nsRefPtr<StkCommandEvent> event = StkCommandEvent::Create(aMessage);
+  nsRefPtr<StkCommandEvent> event = StkCommandEvent::Create(this, aMessage);
   NS_ASSERTION(event, "This should never fail!");
 
   return event->Dispatch(ToIDOMEventTarget(), NS_LITERAL_STRING("stkcommand"));
 }
 
 NS_IMETHODIMP
 IccManager::NotifyStkSessionEnd()
 {
--- a/dom/icc/src/StkCommandEvent.cpp
+++ b/dom/icc/src/StkCommandEvent.cpp
@@ -14,19 +14,20 @@
 
 DOMCI_DATA(MozStkCommandEvent, mozilla::dom::icc::StkCommandEvent)
 
 namespace mozilla {
 namespace dom {
 namespace icc {
 
 already_AddRefed<StkCommandEvent>
-StkCommandEvent::Create(const nsAString& aMessage)
+StkCommandEvent::Create(mozilla::dom::EventTarget* aOwner,
+                        const nsAString& aMessage)
 {
-  nsRefPtr<StkCommandEvent> event = new StkCommandEvent();
+  nsRefPtr<StkCommandEvent> event = new StkCommandEvent(aOwner);
   event->mCommand = aMessage;
   return event.forget();
 }
 
 NS_IMPL_ADDREF_INHERITED(StkCommandEvent, nsDOMEvent)
 NS_IMPL_RELEASE_INHERITED(StkCommandEvent, nsDOMEvent)
 
 NS_INTERFACE_MAP_BEGIN(StkCommandEvent)
--- a/dom/icc/src/StkCommandEvent.h
+++ b/dom/icc/src/StkCommandEvent.h
@@ -19,17 +19,17 @@ class StkCommandEvent : public nsDOMEven
 
 public:
   NS_DECL_ISUPPORTS_INHERITED
   NS_FORWARD_TO_NSDOMEVENT
   NS_DECL_NSIDOMMOZSTKCOMMANDEVENT
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(StkCommandEvent, nsDOMEvent)
 
   static already_AddRefed<StkCommandEvent>
-  Create(const nsAString& aMessage);
+  Create(mozilla::dom::EventTarget* aOwner, const nsAString& aMessage);
 
   nsresult
   Dispatch(nsIDOMEventTarget* aTarget, const nsAString& aEventType)
   {
     NS_ASSERTION(aTarget, "Null pointer!");
     NS_ASSERTION(!aEventType.IsEmpty(), "Empty event type!");
 
     nsresult rv = InitEvent(aEventType, false, false);
@@ -42,18 +42,18 @@ public:
     bool dummy;
     rv = aTarget->DispatchEvent(thisEvent, &dummy);
     NS_ENSURE_SUCCESS(rv, rv);
 
     return NS_OK;
   }
 
 private:
-  StkCommandEvent()
-  : nsDOMEvent(nullptr, nullptr)
+  StkCommandEvent(mozilla::dom::EventTarget* aOwner)
+  : nsDOMEvent(aOwner, nullptr, nullptr)
   { }
 
   ~StkCommandEvent()
   { }
 };
 
 }
 }
--- a/dom/imptests/failures/webapps/DOMCore/tests/approved/test_interfaces.html.json
+++ b/dom/imptests/failures/webapps/DOMCore/tests/approved/test_interfaces.html.json
@@ -28,35 +28,18 @@
   "DOMException exception: constant TIMEOUT_ERR on exception interface prototype object": true,
   "DOMException exception: constant INVALID_NODE_TYPE_ERR on exception interface prototype object": true,
   "DOMException exception: constant DATA_CLONE_ERR on exception interface prototype object": true,
   "DOMException exception: field code on exception interface prototype object": true,
   "DOMError interface: existence and properties of interface object": true,
   "DOMError interface: existence and properties of interface prototype object": true,
   "DOMError interface: existence and properties of interface prototype object's \"constructor\" property": true,
   "DOMError interface: attribute name": true,
-  "Event interface: existence and properties of interface object": true,
-  "Event interface constructor": true,
-  "Event interface: existence and properties of interface prototype object": true,
-  "Event interface: existence and properties of interface prototype object's \"constructor\" property": true,
-  "Event interface: attribute type": true,
-  "Event interface: attribute target": true,
-  "Event interface: attribute currentTarget": true,
-  "Event interface: attribute eventPhase": true,
-  "Event interface: attribute bubbles": true,
-  "Event interface: attribute cancelable": true,
-  "Event interface: attribute defaultPrevented": true,
-  "Event interface: attribute isTrusted": true,
-  "Event interface: attribute timeStamp": true,
-  "Stringification of document.createEvent(\"Event\")": "debug",
   "Event interface: document.createEvent(\"Event\") must inherit property \"timeStamp\" with the proper type (14)": true,
-  "Event interface: calling initEvent(DOMString,boolean,boolean) on document.createEvent(\"Event\") with too few arguments must throw TypeError": true,
-  "Stringification of new Event(\"foo\")": "debug",
   "Event interface: new Event(\"foo\") must inherit property \"timeStamp\" with the proper type (14)": true,
-  "Event interface: calling initEvent(DOMString,boolean,boolean) on new Event(\"foo\") with too few arguments must throw TypeError": true,
   "CustomEvent interface: existence and properties of interface object": true,
   "CustomEvent interface constructor": true,
   "CustomEvent interface: existence and properties of interface prototype object": true,
   "CustomEvent interface: existence and properties of interface prototype object's \"constructor\" property": true,
   "CustomEvent interface: attribute detail": true,
   "Stringification of new CustomEvent(\"foo\")": "debug",
   "Event interface: new CustomEvent(\"foo\") must inherit property \"timeStamp\" with the proper type (14)": true,
   "Event interface: calling initEvent(DOMString,boolean,boolean) on new CustomEvent(\"foo\") with too few arguments must throw TypeError": true,
--- a/dom/imptests/failures/webapps/DOMCore/tests/submissions/Ms2ger/Makefile.in
+++ b/dom/imptests/failures/webapps/DOMCore/tests/submissions/Ms2ger/Makefile.in
@@ -12,17 +12,16 @@ include $(DEPTH)/config/autoconf.mk
 MOCHITEST_FILES := \
   test_CharacterData-remove.html.json \
   test_DOMImplementation-createDocument.html.json \
   test_DOMImplementation-createHTMLDocument.html.json \
   test_Document-createElementNS.html.json \
   test_Document-getElementsByTagName.html.json \
   test_DocumentType-remove.html.json \
   test_Element-remove.html.json \
-  test_Event-constructors.html.json \
   test_Event-defaultPrevented.html.json \
   test_EventTarget-dispatchEvent.html.json \
   test_Node-isEqualNode.xhtml.json \
   test_NodeFilter-constants.html.json \
   test_Range-attributes.html.json \
   test_Range-commonAncestorContainer.html.json \
   test_Range-comparePoint.html.json \
   test_Range-detach.html.json \
deleted file mode 100644
--- a/dom/imptests/failures/webapps/DOMCore/tests/submissions/Ms2ger/test_Event-constructors.html.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
-  "Event constructors": true
-}
--- a/dom/indexedDB/AsyncConnectionHelper.cpp
+++ b/dom/indexedDB/AsyncConnectionHelper.cpp
@@ -415,30 +415,30 @@ AsyncConnectionHelper::GetCurrentTransac
 nsresult
 AsyncConnectionHelper::Init()
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
   return NS_OK;
 }
 
-already_AddRefed<nsDOMEvent>
-AsyncConnectionHelper::CreateSuccessEvent()
+already_AddRefed<nsIDOMEvent>
+AsyncConnectionHelper::CreateSuccessEvent(mozilla::dom::EventTarget* aOwner)
 {
-  return CreateGenericEvent(NS_LITERAL_STRING(SUCCESS_EVT_STR),
+  return CreateGenericEvent(mRequest, NS_LITERAL_STRING(SUCCESS_EVT_STR),
                             eDoesNotBubble, eNotCancelable);
 }
 
 nsresult
 AsyncConnectionHelper::OnSuccess()
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
   NS_ASSERTION(mRequest, "Null request!");
 
-  nsRefPtr<nsDOMEvent> event = CreateSuccessEvent();
+  nsRefPtr<nsIDOMEvent> event = CreateSuccessEvent(mRequest);
   if (!event) {
     NS_ERROR("Failed to create event!");
     return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
   }
 
   bool dummy;
   nsresult rv = mRequest->DispatchEvent(event, &dummy);
   NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
@@ -463,18 +463,18 @@ AsyncConnectionHelper::OnSuccess()
 
 void
 AsyncConnectionHelper::OnError()
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
   NS_ASSERTION(mRequest, "Null request!");
 
   // Make an error event and fire it at the target.
-  nsRefPtr<nsDOMEvent> event =
-    CreateGenericEvent(NS_LITERAL_STRING(ERROR_EVT_STR), eDoesBubble,
+  nsRefPtr<nsIDOMEvent> event =
+    CreateGenericEvent(mRequest, NS_LITERAL_STRING(ERROR_EVT_STR), eDoesBubble,
                        eCancelable);
   if (!event) {
     NS_ERROR("Failed to create event!");
     return;
   }
 
   bool doDefault;
   nsresult rv = mRequest->DispatchEvent(event, &doDefault);
--- a/dom/indexedDB/AsyncConnectionHelper.h
+++ b/dom/indexedDB/AsyncConnectionHelper.h
@@ -173,17 +173,18 @@ protected:
    */
   virtual nsresult DoDatabaseWork(mozIStorageConnection* aConnection) = 0;
 
   /**
    * This function returns the event to be dispatched at the request when
    * OnSuccess is called.  A subclass can override this to fire an event other
    * than "success" at the request.
    */
-  virtual already_AddRefed<nsDOMEvent> CreateSuccessEvent();
+  virtual already_AddRefed<nsIDOMEvent> CreateSuccessEvent(
+    mozilla::dom::EventTarget* aOwner);
 
   /**
    * This callback is run on the main thread if DoDatabaseWork returned NS_OK.
    * The default implementation fires a "success" DOM event with its target set
    * to the request. Returning anything other than NS_OK from the OnSuccess
    * callback will trigger the OnError callback.
    */
   virtual nsresult OnSuccess();
--- a/dom/indexedDB/IDBEvents.cpp
+++ b/dom/indexedDB/IDBEvents.cpp
@@ -33,60 +33,63 @@ public:
 
 private:
   nsCOMPtr<nsIDOMEventTarget> mTarget;
   nsCOMPtr<nsIDOMEvent> mEvent;
 };
 
 } // anonymous namespace
 
-already_AddRefed<nsDOMEvent>
-mozilla::dom::indexedDB::CreateGenericEvent(const nsAString& aType,
+already_AddRefed<nsIDOMEvent>
+mozilla::dom::indexedDB::CreateGenericEvent(mozilla::dom::EventTarget* aOwner,
+                                            const nsAString& aType,
                                             Bubbles aBubbles,
                                             Cancelable aCancelable)
 {
-  nsRefPtr<nsDOMEvent> event(new nsDOMEvent(nullptr, nullptr));
+  nsCOMPtr<nsIDOMEvent> event;
+  NS_NewDOMEvent(getter_AddRefs(event), aOwner, nullptr, nullptr);
   nsresult rv = event->InitEvent(aType,
                                  aBubbles == eDoesBubble ? true : false,
                                  aCancelable == eCancelable ? true : false);
   NS_ENSURE_SUCCESS(rv, nullptr);
 
   event->SetTrusted(true);
 
   return event.forget();
 }
 
 // static
 already_AddRefed<nsDOMEvent>
-IDBVersionChangeEvent::CreateInternal(const nsAString& aType,
+IDBVersionChangeEvent::CreateInternal(mozilla::dom::EventTarget* aOwner,
+                                      const nsAString& aType,
                                       uint64_t aOldVersion,
                                       uint64_t aNewVersion)
 {
-  nsRefPtr<IDBVersionChangeEvent> event(new IDBVersionChangeEvent());
+  nsRefPtr<IDBVersionChangeEvent> event(new IDBVersionChangeEvent(aOwner));
 
   nsresult rv = event->InitEvent(aType, false, false);
   NS_ENSURE_SUCCESS(rv, nullptr);
 
   event->SetTrusted(true);
 
   event->mOldVersion = aOldVersion;
   event->mNewVersion = aNewVersion;
 
   return event.forget();
 }
 
 // static
 already_AddRefed<nsIRunnable>
-IDBVersionChangeEvent::CreateRunnableInternal(const nsAString& aType,
+IDBVersionChangeEvent::CreateRunnableInternal(mozilla::dom::EventTarget* aTarget,
+                                              const nsAString& aType,
                                               uint64_t aOldVersion,
-                                              uint64_t aNewVersion,
-                                              nsIDOMEventTarget* aTarget)
+                                              uint64_t aNewVersion)
 {
   nsRefPtr<nsDOMEvent> event =
-    CreateInternal(aType, aOldVersion, aNewVersion);
+    CreateInternal(aTarget, aType, aOldVersion, aNewVersion);
   NS_ENSURE_TRUE(event, nullptr);
 
   nsCOMPtr<nsIRunnable> runnable(new EventFiringRunnable(aTarget, event));
   return runnable.forget();
 }
 
 NS_IMPL_ADDREF_INHERITED(IDBVersionChangeEvent, nsDOMEvent)
 NS_IMPL_RELEASE_INHERITED(IDBVersionChangeEvent, nsDOMEvent)
--- a/dom/indexedDB/IDBEvents.h
+++ b/dom/indexedDB/IDBEvents.h
@@ -31,85 +31,95 @@ enum Bubbles {
   eDoesBubble
 };
 
 enum Cancelable {
   eNotCancelable,
   eCancelable
 };
 
-already_AddRefed<nsDOMEvent>
-CreateGenericEvent(const nsAString& aType,
+already_AddRefed<nsIDOMEvent>
+CreateGenericEvent(mozilla::dom::EventTarget* aOwner,
+                   const nsAString& aType,
                    Bubbles aBubbles,
                    Cancelable aCancelable);
 
 class IDBVersionChangeEvent : public nsDOMEvent,
                               public nsIIDBVersionChangeEvent
 {
 public:
   NS_DECL_ISUPPORTS_INHERITED
   NS_FORWARD_TO_NSDOMEVENT
   NS_DECL_NSIIDBVERSIONCHANGEEVENT
 
   inline static already_AddRefed<nsDOMEvent>
-  Create(int64_t aOldVersion,
+  Create(mozilla::dom::EventTarget* aOwner,
+         int64_t aOldVersion,
          int64_t aNewVersion)
   {
-    return CreateInternal(NS_LITERAL_STRING(VERSIONCHANGE_EVT_STR),
+    return CreateInternal(aOwner,
+                          NS_LITERAL_STRING(VERSIONCHANGE_EVT_STR),
                           aOldVersion, aNewVersion);
   }
 
   inline static already_AddRefed<nsDOMEvent>
-  CreateBlocked(uint64_t aOldVersion,
+  CreateBlocked(mozilla::dom::EventTarget* aOwner,
+                uint64_t aOldVersion,
                 uint64_t aNewVersion)
   {
-    return CreateInternal(NS_LITERAL_STRING(BLOCKED_EVT_STR),
+    return CreateInternal(aOwner, NS_LITERAL_STRING(BLOCKED_EVT_STR),
                           aOldVersion, aNewVersion);
   }
 
   inline static already_AddRefed<nsDOMEvent>
-  CreateUpgradeNeeded(uint64_t aOldVersion,
+  CreateUpgradeNeeded(mozilla::dom::EventTarget* aOwner,
+                      uint64_t aOldVersion,
                       uint64_t aNewVersion)
   {
-    return CreateInternal(NS_LITERAL_STRING(UPGRADENEEDED_EVT_STR),
+    return CreateInternal(aOwner,
+                          NS_LITERAL_STRING(UPGRADENEEDED_EVT_STR),
                           aOldVersion, aNewVersion);
   }
 
   inline static already_AddRefed<nsIRunnable>
-  CreateRunnable(uint64_t aOldVersion,
-                 uint64_t aNewVersion,
-                 nsIDOMEventTarget* aTarget)
+  CreateRunnable(mozilla::dom::EventTarget* aTarget,
+                 uint64_t aOldVersion,
+                 uint64_t aNewVersion)
   {
-    return CreateRunnableInternal(NS_LITERAL_STRING(VERSIONCHANGE_EVT_STR),
-                                  aOldVersion, aNewVersion, aTarget);
+    return CreateRunnableInternal(aTarget,
+                                  NS_LITERAL_STRING(VERSIONCHANGE_EVT_STR),
+                                  aOldVersion, aNewVersion);
   }
 
   static already_AddRefed<nsIRunnable>
-  CreateBlockedRunnable(uint64_t aOldVersion,
-                        uint64_t aNewVersion,
-                        nsIDOMEventTarget* aTarget)
+  CreateBlockedRunnable(mozilla::dom::EventTarget* aTarget,
+                        uint64_t aOldVersion,
+                        uint64_t aNewVersion)
   {
-    return CreateRunnableInternal(NS_LITERAL_STRING(BLOCKED_EVT_STR),
-                                  aOldVersion, aNewVersion, aTarget);
+    return CreateRunnableInternal(aTarget,
+                                  NS_LITERAL_STRING(BLOCKED_EVT_STR),
+                                  aOldVersion, aNewVersion);
   }
 
 protected:
-  IDBVersionChangeEvent() : nsDOMEvent(nullptr, nullptr) { }
+  IDBVersionChangeEvent(mozilla::dom::EventTarget* aOwner)
+  : nsDOMEvent(aOwner, nullptr, nullptr) { }
   virtual ~IDBVersionChangeEvent() { }
 
   static already_AddRefed<nsDOMEvent>
-  CreateInternal(const nsAString& aType,
+  CreateInternal(mozilla::dom::EventTarget* aOwner,
+                 const nsAString& aType,
                  uint64_t aOldVersion,
                  uint64_t aNewVersion);
 
   static already_AddRefed<nsIRunnable>
-  CreateRunnableInternal(const nsAString& aType,
+  CreateRunnableInternal(mozilla::dom::EventTarget* aOwner,
+                         const nsAString& aType,
                          uint64_t aOldVersion,
-                         uint64_t aNewVersion,
-                         nsIDOMEventTarget* aTarget);
+                         uint64_t aNewVersion);
 
   uint64_t mOldVersion;
   uint64_t mNewVersion;
 };
 
 END_INDEXEDDB_NAMESPACE
 
 #endif // mozilla_dom_indexeddb_idbevents_h__
--- a/dom/indexedDB/IDBTransaction.cpp
+++ b/dom/indexedDB/IDBTransaction.cpp
@@ -832,29 +832,31 @@ CommitHelper::Run()
     if (NS_FAILED(mAbortCode)) {
       if (mTransaction->GetMode() == IDBTransaction::VERSION_CHANGE) {
         // This will make the database take a snapshot of it's DatabaseInfo
         mTransaction->Database()->Close();
         // Then remove the info from the hash as it contains invalid data.
         DatabaseInfo::Remove(mTransaction->Database()->Id());
       }
 
-      event = CreateGenericEvent(NS_LITERAL_STRING(ABORT_EVT_STR),
+      event = CreateGenericEvent(mTransaction,
+                                 NS_LITERAL_STRING(ABORT_EVT_STR),
                                  eDoesBubble, eNotCancelable);
 
       // The transaction may already have an error object (e.g. if one of the
       // requests failed).  If it doesn't, and it wasn't aborted
       // programmatically, create one now.
       if (!mTransaction->mError &&
           mAbortCode != NS_ERROR_DOM_INDEXEDDB_ABORT_ERR) {
         mTransaction->mError = DOMError::CreateForNSResult(mAbortCode);
       }
     }
     else {
-      event = CreateGenericEvent(NS_LITERAL_STRING(COMPLETE_EVT_STR),
+      event = CreateGenericEvent(mTransaction,
+                                 NS_LITERAL_STRING(COMPLETE_EVT_STR),
                                  eDoesNotBubble, eNotCancelable);
     }
     NS_ENSURE_TRUE(event, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
 
     if (mListener) {
       mListener->NotifyTransactionPreComplete(mTransaction);
     }
 
--- a/dom/indexedDB/OpenDatabaseHelper.cpp
+++ b/dom/indexedDB/OpenDatabaseHelper.cpp
@@ -1353,17 +1353,18 @@ protected:
                                   MOZ_OVERRIDE;
 
   // SetVersionHelper never fires an error event at the request.  It hands that
   // responsibility back to the OpenDatabaseHelper
   virtual void OnError() MOZ_OVERRIDE
   { }
 
   // Need an upgradeneeded event here.
-  virtual already_AddRefed<nsDOMEvent> CreateSuccessEvent() MOZ_OVERRIDE;
+  virtual already_AddRefed<nsIDOMEvent> CreateSuccessEvent(
+    mozilla::dom::EventTarget* aOwner) MOZ_OVERRIDE;
 
   virtual nsresult NotifyTransactionPreComplete(IDBTransaction* aTransaction)
                                                 MOZ_OVERRIDE;
   virtual nsresult NotifyTransactionPostComplete(IDBTransaction* aTransaction)
                                                  MOZ_OVERRIDE;
 
   virtual ChildProcessSendResult
   SendResponseToChildProcess(nsresult aResultCode) MOZ_OVERRIDE
@@ -1525,29 +1526,30 @@ public:
         NS_ASSERTION(database->IsClosed(),
                    "AbortCloseDatabasesForWindow should have closed database");
         ownerDoc->DisallowBFCaching();
         continue;
       }
 
       // Otherwise fire a versionchange event.
       nsRefPtr<nsDOMEvent> event = 
-        IDBVersionChangeEvent::Create(mOldVersion, mNewVersion);
+        IDBVersionChangeEvent::Create(database, mOldVersion, mNewVersion);
       NS_ENSURE_TRUE(event, NS_ERROR_FAILURE);
 
       bool dummy;
       database->DispatchEvent(event, &dummy);
     }
 
     // Now check to see if any didn't close. If there are some running still
     // then fire the blocked event.
     for (uint32_t index = 0; index < count; index++) {
       if (!mWaitingDatabases[index]->IsClosed()) {
         nsRefPtr<nsDOMEvent> event =
-          IDBVersionChangeEvent::CreateBlocked(mOldVersion, mNewVersion);
+          IDBVersionChangeEvent::CreateBlocked(mRequest,
+                                               mOldVersion, mNewVersion);
         NS_ENSURE_TRUE(event, NS_ERROR_FAILURE);
 
         bool dummy;
         mRequest->DispatchEvent(event, &dummy);
 
         break;
       }
     }
@@ -2195,33 +2197,33 @@ OpenDatabaseHelper::BlockDatabase()
   NS_ASSERTION(mDatabase, "This is going bad fast.");
 
   mDatabase->EnterSetVersionTransaction();
 }
 
 void
 OpenDatabaseHelper::DispatchSuccessEvent()
 {
-  nsRefPtr<nsDOMEvent> event =
-    CreateGenericEvent(NS_LITERAL_STRING(SUCCESS_EVT_STR),
+  nsRefPtr<nsIDOMEvent> event =
+    CreateGenericEvent(mOpenDBRequest, NS_LITERAL_STRING(SUCCESS_EVT_STR),
                        eDoesNotBubble, eNotCancelable);
   if (!event) {
     NS_ERROR("Failed to create event!");
     return;
   }
 
   bool dummy;
   mOpenDBRequest->DispatchEvent(event, &dummy);
 }
 
 void
 OpenDatabaseHelper::DispatchErrorEvent()
 {
-  nsRefPtr<nsDOMEvent> event =
-    CreateGenericEvent(NS_LITERAL_STRING(ERROR_EVT_STR),
+  nsRefPtr<nsIDOMEvent> event =
+    CreateGenericEvent(mOpenDBRequest, NS_LITERAL_STRING(ERROR_EVT_STR),
                        eDoesBubble, eCancelable);
   if (!event) {
     NS_ERROR("Failed to create event!");
     return;
   }
 
   nsCOMPtr<nsIDOMDOMError> error;
   DebugOnly<nsresult> rv =
@@ -2313,22 +2315,23 @@ VersionChangeEventsRunnable::QueueVersio
                                     closure->mOpenRequest,
                                     aDatabases,
                                     closure->mCurrentVersion,
                                     closure->RequestedVersion());
 
   NS_DispatchToCurrentThread(eventsRunnable);
 }
 
-already_AddRefed<nsDOMEvent>
-SetVersionHelper::CreateSuccessEvent()
+already_AddRefed<nsIDOMEvent>
+SetVersionHelper::CreateSuccessEvent(mozilla::dom::EventTarget* aOwner)
 {
   NS_ASSERTION(mCurrentVersion < mRequestedVersion, "Huh?");
 
-  return IDBVersionChangeEvent::CreateUpgradeNeeded(mCurrentVersion,
+  return IDBVersionChangeEvent::CreateUpgradeNeeded(aOwner,
+                                                    mCurrentVersion,
                                                     mRequestedVersion);
 }
 
 nsresult
 SetVersionHelper::NotifyTransactionPreComplete(IDBTransaction* aTransaction)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
   NS_ASSERTION(aTransaction, "This is unexpected.");
--- a/dom/indexedDB/ipc/IndexedDBChild.cpp
+++ b/dom/indexedDB/ipc/IndexedDBChild.cpp
@@ -86,18 +86,18 @@ public:
                                             MOZ_OVERRIDE;
 
   virtual ChildProcessSendResult
   SendResponseToChildProcess(nsresult aResultCode) MOZ_OVERRIDE;
 
   virtual nsresult
   DoDatabaseWork(mozIStorageConnection* aConnection) MOZ_OVERRIDE;
 
-  virtual already_AddRefed<nsDOMEvent>
-  CreateSuccessEvent() MOZ_OVERRIDE;
+  virtual already_AddRefed<nsIDOMEvent>
+  CreateSuccessEvent(mozilla::dom::EventTarget* aOwner) MOZ_OVERRIDE;
 
   virtual nsresult
   GetSuccessResult(JSContext* aCx, jsval* aVal) MOZ_OVERRIDE;
 };
 
 class IPCDeleteDatabaseHelper : public AsyncConnectionHelper
 {
 public:
@@ -135,17 +135,17 @@ public:
 
   NS_IMETHOD Run() MOZ_OVERRIDE
   {
     if (mDatabase->IsClosed()) {
       return NS_OK;
     }
 
     nsRefPtr<nsDOMEvent> event =
-      IDBVersionChangeEvent::Create(mOldVersion, mNewVersion);
+      IDBVersionChangeEvent::Create(mDatabase, mOldVersion, mNewVersion);
     MOZ_ASSERT(event);
 
     bool dummy;
     nsresult rv = mDatabase->DispatchEvent(event, &dummy);
     NS_ENSURE_SUCCESS(rv, rv);
 
     return NS_OK;
   }
@@ -429,18 +429,17 @@ IndexedDBDatabaseChild::RecvError(const 
 
 bool
 IndexedDBDatabaseChild::RecvBlocked(const uint64_t& aOldVersion)
 {
   MOZ_ASSERT(mRequest);
   MOZ_ASSERT(!mDatabase);
 
   nsCOMPtr<nsIRunnable> runnable =
-    IDBVersionChangeEvent::CreateBlockedRunnable(aOldVersion, mVersion,
-                                                 mRequest);
+    IDBVersionChangeEvent::CreateBlockedRunnable(mRequest, aOldVersion, mVersion);
 
   MainThreadEventTarget target;
   if (NS_FAILED(target.Dispatch(runnable, NS_DISPATCH_NORMAL))) {
     NS_WARNING("Dispatch of blocked event failed!");
   }
 
   return true;
 }
@@ -1252,18 +1251,18 @@ IndexedDBDeleteDatabaseRequestChild::Rec
 
 bool
 IndexedDBDeleteDatabaseRequestChild::RecvBlocked(
                                                 const uint64_t& aCurrentVersion)
 {
   MOZ_ASSERT(mOpenRequest);
 
   nsCOMPtr<nsIRunnable> runnable =
-    IDBVersionChangeEvent::CreateBlockedRunnable(aCurrentVersion, 0,
-                                                 mOpenRequest);
+    IDBVersionChangeEvent::CreateBlockedRunnable(mOpenRequest,
+                                                 aCurrentVersion, 0);
 
   MainThreadEventTarget target;
   if (NS_FAILED(target.Dispatch(runnable, NS_DISPATCH_NORMAL))) {
     NS_WARNING("Dispatch of blocked event failed!");
   }
 
   return true;
 }
@@ -1318,20 +1317,21 @@ IPCSetVersionHelper::SendResponseToChild
 
 nsresult
 IPCSetVersionHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
 {
   MOZ_NOT_REACHED("Don't call me!");
   return NS_ERROR_FAILURE;
 }
 
-already_AddRefed<nsDOMEvent>
-IPCSetVersionHelper::CreateSuccessEvent()
+already_AddRefed<nsIDOMEvent>
+IPCSetVersionHelper::CreateSuccessEvent(mozilla::dom::EventTarget* aOwner)
 {
-  return IDBVersionChangeEvent::CreateUpgradeNeeded(mOldVersion,
+  return IDBVersionChangeEvent::CreateUpgradeNeeded(aOwner,
+                                                    mOldVersion,
                                                     mRequestedVersion);
 }
 
 nsresult
 IPCSetVersionHelper::GetSuccessResult(JSContext* aCx, jsval* aVal)
 {
   mOpenRequest->SetTransaction(mTransaction);
 
--- a/dom/interfaces/events/nsIDOMEvent.idl
+++ b/dom/interfaces/events/nsIDOMEvent.idl
@@ -3,47 +3,53 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "domstubs.idl"
 
 interface nsIDOMEventTarget;
 
 [ptr] native nsEventPtr(nsEvent);
+[ptr] native nsDOMEventPtr(nsDOMEvent);
 [ptr] native IPCMessagePtr(IPC::Message);
 [ptr] native ConstIPCMessagePtr(const IPC::Message);
+[ptr] native EventTargetPtr(mozilla::dom::EventTarget);
 %{C++
 #ifdef ERROR
 #undef ERROR
 #endif
 
 class nsEvent;
+class nsDOMEvent;
 class nsCommandEvent;
 class nsPresContext;
 class nsInvalidateRequestList;
 namespace IPC {
 class Message;
 }
 namespace mozilla {
 namespace widget {
 class WheelEvent;
 } // namespace widget
+namespace dom {
+class EventTarget;
+} // namespace dom
 } // namespace mozilla
 %}
 
 /**
  * The nsIDOMEvent interface is the primary datatype for all events in
  * the Document Object Model.
  *
  * For more information on this interface please see 
  * http://dev.w3.org/2006/webapi/DOM-Level-3-Events/html/DOM3-Events.html and
  * http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html
  */
 
-[scriptable, builtinclass, uuid(c939eab8-1345-4344-875b-e0f2d8d89171)]
+[scriptable, builtinclass, uuid(547ec16c-e41d-4df7-9fb6-ad6041f0687a)]
 interface nsIDOMEvent : nsISupports
 {
   // PhaseType
   /**
    * The event isn't being dispatched.
    */
   const unsigned short      NONE                           = 0;
   /**
@@ -246,86 +252,173 @@ interface nsIDOMEvent : nsISupports
   [noscript] void duplicatePrivateData();
   [noscript] void setTarget(in nsIDOMEventTarget aTarget);
   [notxpcom] boolean IsDispatchStopped();
   [notxpcom] nsEventPtr GetInternalNSEvent();
   [noscript,notxpcom] void SetTrusted(in boolean aTrusted);
   [notxpcom] void Serialize(in IPCMessagePtr aMsg,
                             in boolean aSerializeInterfaceType);
   [notxpcom] boolean Deserialize(in ConstIPCMessagePtr aMsg, out voidPtr aIter);
-  
+  [noscript,notxpcom] void SetOwner(in EventTargetPtr aOwner);
+  [notxpcom] nsDOMEventPtr InternalDOMEvent();
 };
 
 dictionary EventInit
 {
   boolean bubbles;
   boolean cancelable;
 };
 
 %{C++
+
 nsresult
-NS_NewDOMEvent(nsIDOMEvent** aInstancePtrResult, nsPresContext* aPresContext, nsEvent *aEvent);
+NS_NewDOMEvent(nsIDOMEvent** aInstancePtrResult,
+               mozilla::dom::EventTarget* aOwner,
+               nsPresContext* aPresContext,
+               nsEvent *aEvent);
 nsresult
-NS_NewDOMDataContainerEvent(nsIDOMEvent** aInstancePtrResult, nsPresContext* aPresContext, nsEvent *aEvent);
+NS_NewDOMDataContainerEvent(nsIDOMEvent** aInstancePtrResult,
+                            mozilla::dom::EventTarget* aOwner,
+                            nsPresContext* aPresContext,
+                            nsEvent* aEvent);
 nsresult
-NS_NewDOMUIEvent(nsIDOMEvent** aInstancePtrResult, nsPresContext* aPresContext, class nsGUIEvent *aEvent);
+NS_NewDOMUIEvent(nsIDOMEvent** aInstancePtrResult,
+                 mozilla::dom::EventTarget* aOwner,
+                 nsPresContext* aPresContext,
+                 class nsGUIEvent* aEvent);
 nsresult
-NS_NewDOMMouseEvent(nsIDOMEvent** aInstancePtrResult, nsPresContext* aPresContext, class nsInputEvent *aEvent);
+NS_NewDOMMouseEvent(nsIDOMEvent** aInstancePtrResult,
+                    mozilla::dom::EventTarget* aOwner,
+                    nsPresContext* aPresContext,
+                    class nsInputEvent* aEvent);
 nsresult
-NS_NewDOMMouseScrollEvent(nsIDOMEvent** aInstancePtrResult, nsPresContext* aPresContext, class nsInputEvent *aEvent);
+NS_NewDOMMouseScrollEvent(nsIDOMEvent** aInstancePtrResult,
+                          mozilla::dom::EventTarget* aOwner,
+                          nsPresContext* aPresContext,
+                          class nsInputEvent* aEvent);
 nsresult
-NS_NewDOMWheelEvent(nsIDOMEvent** aInstancePtrResult, nsPresContext* aPresContext, mozilla::widget::WheelEvent *aEvent);
+NS_NewDOMWheelEvent(nsIDOMEvent** aInstancePtrResult,
+                    mozilla::dom::EventTarget* aOwner,
+                    nsPresContext* aPresContext,
+                    mozilla::widget::WheelEvent* aEvent);
 nsresult
-NS_NewDOMDragEvent(nsIDOMEvent** aInstancePtrResult, nsPresContext* aPresContext, class nsDragEvent *aEvent);
+NS_NewDOMDragEvent(nsIDOMEvent** aInstancePtrResult,
+                   mozilla::dom::EventTarget* aOwner,
+                   nsPresContext* aPresContext,
+                   class nsDragEvent* aEvent);
 nsresult
-NS_NewDOMKeyboardEvent(nsIDOMEvent** aInstancePtrResult, nsPresContext* aPresContext, class nsKeyEvent *aEvent);
+NS_NewDOMKeyboardEvent(nsIDOMEvent** aInstancePtrResult,
+                       mozilla::dom::EventTarget* aOwner,
+                       nsPresContext* aPresContext,
+                       class nsKeyEvent* aEvent);
 nsresult
-NS_NewDOMCompositionEvent(nsIDOMEvent** aInstancePtrResult, nsPresContext* aPresContext, class nsCompositionEvent *aEvent);
+NS_NewDOMCompositionEvent(nsIDOMEvent** aInstancePtrResult,
+                          mozilla::dom::EventTarget* aOwner,
+                          nsPresContext* aPresContext,
+                          class nsCompositionEvent* aEvent);
 nsresult
-NS_NewDOMMutationEvent(nsIDOMEvent** aResult, nsPresContext* aPresContext, class nsMutationEvent* aEvent);
+NS_NewDOMMutationEvent(nsIDOMEvent** aResult,
+                       mozilla::dom::EventTarget* aOwner,
+                       nsPresContext* aPresContext,
+                       class nsMutationEvent* aEvent);
 nsresult
-NS_NewDOMDeviceMotionEvent(nsIDOMEvent** aResult, nsPresContext* aPresContext, nsEvent* aEvent);
+NS_NewDOMDeviceMotionEvent(nsIDOMEvent** aResult,
+                           mozilla::dom::EventTarget* aOwner,
+                           nsPresContext* aPresContext,
+                           nsEvent* aEvent);
 nsresult
-NS_NewDOMTextEvent(nsIDOMEvent** aResult, nsPresContext* aPresContext, class nsTextEvent* aEvent);
+NS_NewDOMTextEvent(nsIDOMEvent** aResult,
+                   mozilla::dom::EventTarget* aOwner,
+                   nsPresContext* aPresContext,
+                   class nsTextEvent* aEvent);
 nsresult
-NS_NewDOMBeforeUnloadEvent(nsIDOMEvent** aResult, nsPresContext* aPresContext, nsEvent* aEvent);
+NS_NewDOMBeforeUnloadEvent(nsIDOMEvent** aResult,
+                           mozilla::dom::EventTarget* aOwner,
+                           nsPresContext* aPresContext,
+                           nsEvent* aEvent);
 nsresult
-NS_NewDOMSVGEvent(nsIDOMEvent** aResult, nsPresContext* aPresContext, class nsEvent* aEvent);
+NS_NewDOMSVGEvent(nsIDOMEvent** aResult,
+                  mozilla::dom::EventTarget* aOwner,
+                  nsPresContext* aPresContext,
+                  class nsEvent* aEvent);
 nsresult
-NS_NewDOMSVGZoomEvent(nsIDOMEvent** aResult, nsPresContext* aPresContext, class nsGUIEvent* aEvent);
+NS_NewDOMSVGZoomEvent(nsIDOMEvent** aResult,
+                      mozilla::dom::EventTarget* aOwner,
+                      nsPresContext* aPresContext,
+                      class nsGUIEvent* aEvent);
 nsresult
-NS_NewDOMTimeEvent(nsIDOMEvent** aResult, nsPresContext* aPresContext, class nsEvent* aEvent);
+NS_NewDOMTimeEvent(nsIDOMEvent** aResult,
+                   mozilla::dom::EventTarget* aOwner,
+                   nsPresContext* aPresContext,
+                   class nsEvent* aEvent);
 nsresult
-NS_NewDOMXULCommandEvent(nsIDOMEvent** aResult, nsPresContext* aPresContext, class nsInputEvent* aEvent);
+NS_NewDOMXULCommandEvent(nsIDOMEvent** aResult,
+                         mozilla::dom::EventTarget* aOwner,
+                         nsPresContext* aPresContext,
+                         class nsInputEvent* aEvent);
 nsresult
-NS_NewDOMCommandEvent(nsIDOMEvent** aInstancePtrResult, nsPresContext* aPresContext, nsCommandEvent* aEvent);
+NS_NewDOMCommandEvent(nsIDOMEvent** aInstancePtrResult,
+                      mozilla::dom::EventTarget* aOwner,
+                      nsPresContext* aPresContext,
+                      nsCommandEvent* aEvent);
 nsresult
-NS_NewDOMMessageEvent(nsIDOMEvent** aInstancePtrResult, nsPresContext* aPresContext, class nsEvent* aEvent);
+NS_NewDOMMessageEvent(nsIDOMEvent** aInstancePtrResult,
+                      mozilla::dom::EventTarget* aOwner,
+                      nsPresContext* aPresContext,
+                      class nsEvent* aEvent);
 nsresult
-NS_NewDOMProgressEvent(nsIDOMEvent** aInstancePtrResult, nsPresContext* aPresContext, class nsEvent* aEvent);
+NS_NewDOMProgressEvent(nsIDOMEvent** aInstancePtrResult,
+                       mozilla::dom::EventTarget* aOwner,
+                       nsPresContext* aPresContext,
+                       class nsEvent* aEvent);
 // This empties aInvalidateRequests.
 nsresult
-NS_NewDOMNotifyPaintEvent(nsIDOMEvent** aResult, nsPresContext* aPresContext,
+NS_NewDOMNotifyPaintEvent(nsIDOMEvent** aResult,
+                          mozilla::dom::EventTarget* aOwner,
+                          nsPresContext* aPresContext,
                           nsEvent* aEvent,
                           uint32_t aEventType = 0,
                           nsInvalidateRequestList* aInvalidateRequests = nullptr);
 nsresult
-NS_NewDOMAudioAvailableEvent(nsIDOMEvent** aResult, nsPresContext* aPresContext,
+NS_NewDOMAudioAvailableEvent(nsIDOMEvent** aResult,
+                             mozilla::dom::EventTarget* aOwner,
+                             nsPresContext* aPresContext,
                              nsEvent* aEvent,
                              uint32_t aEventType = 0,
                              float* aFrameBuffer = nullptr,
                              uint32_t aFrameBufferLength = 0,
                              float aTime = 0);
 nsresult
-NS_NewDOMSimpleGestureEvent(nsIDOMEvent** aInstancePtrResult, nsPresContext* aPresContext, class nsSimpleGestureEvent* aEvent);
+NS_NewDOMSimpleGestureEvent(nsIDOMEvent** aInstancePtrResult,
+                            mozilla::dom::EventTarget* aOwner,
+                            nsPresContext* aPresContext,
+                            class nsSimpleGestureEvent* aEvent);
 nsresult
-NS_NewDOMScrollAreaEvent(nsIDOMEvent** aInstancePtrResult, nsPresContext* aPresContext, class nsScrollAreaEvent* aEvent);
+NS_NewDOMScrollAreaEvent(nsIDOMEvent** aInstancePtrResult,
+                         mozilla::dom::EventTarget* aOwner,
+                         nsPresContext* aPresContext,
+                         class nsScrollAreaEvent* aEvent);
 nsresult
-NS_NewDOMTransitionEvent(nsIDOMEvent** aInstancePtrResult, nsPresContext* aPresContext, class nsTransitionEvent* aEvent);
+NS_NewDOMTransitionEvent(nsIDOMEvent** aInstancePtrResult,
+                         mozilla::dom::EventTarget* aOwner,
+                         nsPresContext* aPresContext,
+                         class nsTransitionEvent* aEvent);
 nsresult
-NS_NewDOMAnimationEvent(nsIDOMEvent** aInstancePtrResult, nsPresContext* aPresContext, class nsAnimationEvent* aEvent);
+NS_NewDOMAnimationEvent(nsIDOMEvent** aInstancePtrResult,
+                        mozilla::dom::EventTarget* aOwner,
+                        nsPresContext* aPresContext,
+                        class nsAnimationEvent* aEvent);
 nsresult
-NS_NewDOMTouchEvent(nsIDOMEvent** aInstancePtrResult, nsPresContext* aPresContext, class nsTouchEvent *aEvent);
+NS_NewDOMTouchEvent(nsIDOMEvent** aInstancePtrResult,
+                    mozilla::dom::EventTarget* aOwner,
+                    nsPresContext* aPresContext,
+                    class nsTouchEvent* aEvent);
 nsresult
-NS_NewDOMMozSettingsEvent(nsIDOMEvent** aInstancePtrResult, nsPresContext* aPresContext, nsEvent* aEvent);
+NS_NewDOMMozSettingsEvent(nsIDOMEvent** aInstancePtrResult,
+                          mozilla::dom::EventTarget* aOwner,
+                          nsPresContext* aPresContext,
+                          nsEvent* aEvent);
 nsresult
-NS_NewDOMMozApplicationEvent(nsIDOMEvent** aInstancePtrResult, nsPresContext* aPresContext, nsEvent* aEvent);
+NS_NewDOMMozApplicationEvent(nsIDOMEvent** aInstancePtrResult,
+                             mozilla::dom::EventTarget* aOwner,
+                             nsPresContext* aPresContext,
+                             nsEvent* aEvent);
 %}
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -1968,17 +1968,17 @@ class UnloadScriptEvent : public nsRunna
 public:
   UnloadScriptEvent(TabChild* aTabChild, TabChildGlobal* aTabChildGlobal)
     : mTabChild(aTabChild), mTabChildGlobal(aTabChildGlobal)
   { }
 
   NS_IMETHOD Run()
   {
     nsCOMPtr<nsIDOMEvent> event;
-    NS_NewDOMEvent(getter_AddRefs(event), nullptr, nullptr);
+    NS_NewDOMEvent(getter_AddRefs(event), mTabChildGlobal, nullptr, nullptr);
     if (event) {
       event->InitEvent(NS_LITERAL_STRING("unload"), false, false);
       event->SetTrusted(true);
 
       bool dummy;
       mTabChildGlobal->DispatchEvent(event, &dummy);
     }
 
--- a/dom/ipc/TabMessageUtils.cpp
+++ b/dom/ipc/TabMessageUtils.cpp
@@ -20,17 +20,17 @@ bool
 ReadRemoteEvent(const IPC::Message* aMsg, void** aIter,
                 RemoteDOMEvent* aResult)
 {
   aResult->mEvent = nullptr;
   nsString type;
   NS_ENSURE_TRUE(ReadParam(aMsg, aIter, &type), false);
 
   nsCOMPtr<nsIDOMEvent> event;
-  nsEventDispatcher::CreateEvent(nullptr, nullptr, type, getter_AddRefs(event));
+  nsEventDispatcher::CreateEvent(nullptr, nullptr, nullptr, type, getter_AddRefs(event));
   aResult->mEvent = do_QueryInterface(event);
   NS_ENSURE_TRUE(aResult->mEvent, false);
 
   return aResult->mEvent->Deserialize(aMsg, aIter);
 }
 
 }
 }
--- a/dom/ipc/TabMessageUtils.h
+++ b/dom/ipc/TabMessageUtils.h
@@ -14,16 +14,17 @@
 #ifdef MOZ_CRASHREPORTER
 #include "nsExceptionHandler.h"
 #endif
 
 namespace mozilla {
 namespace dom {
 struct RemoteDOMEvent
 {
+  // Make sure to set the owner after deserializing.
   nsCOMPtr<nsIDOMEvent> mEvent;
 };
 
 bool ReadRemoteEvent(const IPC::Message* aMsg, void** aIter,
                      mozilla::dom::RemoteDOMEvent* aResult);
 
 #ifdef MOZ_CRASHREPORTER
 typedef CrashReporter::ThreadId NativeThreadId;
--- a/dom/ipc/TabParent.cpp
+++ b/dom/ipc/TabParent.cpp
@@ -294,19 +294,21 @@ TabParent::RecvMoveFocus(const bool& aFo
 }
 
 bool
 TabParent::RecvEvent(const RemoteDOMEvent& aEvent)
 {
   nsCOMPtr<nsIDOMEvent> event = do_QueryInterface(aEvent.mEvent);
   NS_ENSURE_TRUE(event, true);
 
-  nsCOMPtr<nsIDOMEventTarget> target = do_QueryInterface(mFrameElement);
+  nsCOMPtr<mozilla::dom::EventTarget> target = do_QueryInterface(mFrameElement);
   NS_ENSURE_TRUE(target, true);
 
+  event->SetOwner(target);
+
   bool dummy;
   target->DispatchEvent(event, &dummy);
   return true;
 }
 
 bool
 TabParent::AnswerCreateWindow(PBrowserParent** retval)
 {
--- a/dom/mobilemessage/src/SmsManager.cpp
+++ b/dom/mobilemessage/src/SmsManager.cpp
@@ -314,17 +314,17 @@ SmsManager::GetThreadList(nsIDOMMozSmsRe
   req.forget(aRequest);
   return NS_OK;
 }
 
 nsresult
 SmsManager::DispatchTrustedSmsEventToSelf(const nsAString& aEventName, nsIDOMMozSmsMessage* aMessage)
 {
   nsCOMPtr<nsIDOMEvent> event;
-  NS_NewDOMMozSmsEvent(getter_AddRefs(event), nullptr, nullptr);
+  NS_NewDOMMozSmsEvent(getter_AddRefs(event), this, nullptr, nullptr);
   NS_ASSERTION(event, "This should never fail!");
 
   nsCOMPtr<nsIDOMMozSmsEvent> se = do_QueryInterface(event);
   MOZ_ASSERT(se);
   nsresult rv = se->InitMozSmsEvent(aEventName, false, false, aMessage);
   NS_ENSURE_SUCCESS(rv, rv);
 
   return DispatchTrustedEvent(event);
--- a/dom/mobilemessage/src/SmsRequest.cpp
+++ b/dom/mobilemessage/src/SmsRequest.cpp
@@ -279,17 +279,18 @@ SmsRequest::GetResult(jsval* aResult)
 
   *aResult = mResult;
   return NS_OK;
 }
 
 nsresult
 SmsRequest::DispatchTrustedEvent(const nsAString& aEventName)
 {
-  nsRefPtr<nsDOMEvent> event = new nsDOMEvent(nullptr, nullptr);
+  nsCOMPtr<nsIDOMEvent> event;
+  NS_NewDOMEvent(getter_AddRefs(event), this, nullptr, nullptr);
   nsresult rv = event->InitEvent(aEventName, false, false);
   NS_ENSURE_SUCCESS(rv, rv);
 
   event->SetTrusted(true);
 
   bool dummy;
   return DispatchEvent(event, &dummy);
 }
--- a/dom/network/src/MobileConnection.cpp
+++ b/dom/network/src/MobileConnection.cpp
@@ -324,47 +324,47 @@ MobileConnection::NotifyIccInfoChanged()
   return DispatchTrustedEvent(NS_LITERAL_STRING("iccinfochange"));
 }
 
 NS_IMETHODIMP
 MobileConnection::NotifyUssdReceived(const nsAString& aMessage,
                                      bool aSessionEnded)
 {
   nsCOMPtr<nsIDOMEvent> event;
-  NS_NewDOMUSSDReceivedEvent(getter_AddRefs(event), nullptr, nullptr);
+  NS_NewDOMUSSDReceivedEvent(getter_AddRefs(event), this, nullptr, nullptr);
 
   nsCOMPtr<nsIDOMUSSDReceivedEvent> ce = do_QueryInterface(event);
   nsresult rv = ce->InitUSSDReceivedEvent(NS_LITERAL_STRING("ussdreceived"),
                                           false, false,
                                           aMessage, aSessionEnded);
   NS_ENSURE_SUCCESS(rv, rv);
 
   return DispatchTrustedEvent(ce);
 }
 
 NS_IMETHODIMP
 MobileConnection::NotifyDataError(const nsAString& aMessage)
 {
   nsCOMPtr<nsIDOMEvent> event;
-  NS_NewDOMDataErrorEvent(getter_AddRefs(event), nullptr, nullptr);
+  NS_NewDOMDataErrorEvent(getter_AddRefs(event), this, nullptr, nullptr);
 
   nsCOMPtr<nsIDOMDataErrorEvent> ce = do_QueryInterface(event);
   nsresult rv = ce->InitDataErrorEvent(NS_LITERAL_STRING("dataerror"),
                                        false, false, aMessage);
   NS_ENSURE_SUCCESS(rv, rv);
 
   return DispatchTrustedEvent(ce);
 }
 
 NS_IMETHODIMP
 MobileConnection::NotifyIccCardLockError(const nsAString& aLockType,
                                          uint32_t aRetryCount)
 {
   nsCOMPtr<nsIDOMEvent> event;
-  NS_NewDOMICCCardLockErrorEvent(getter_AddRefs(event), nullptr, nullptr);
+  NS_NewDOMICCCardLockErrorEvent(getter_AddRefs(event), this, nullptr, nullptr);
 
   nsCOMPtr<nsIDOMICCCardLockErrorEvent> ce = do_QueryInterface(event);
   nsresult rv =
     ce->InitICCCardLockErrorEvent(NS_LITERAL_STRING("icccardlockerror"),
                                   false, false, aLockType, aRetryCount);
   NS_ENSURE_SUCCESS(rv, rv);
 
   return DispatchTrustedEvent(ce);
@@ -374,17 +374,17 @@ NS_IMETHODIMP
 MobileConnection::NotifyCFStateChange(bool aSuccess,
                                       unsigned short aAction,
                                       unsigned short aReason,
                                       const nsAString& aNumber,
                                       unsigned short aSeconds,
                                       unsigned short aServiceClass)
 {
   nsCOMPtr<nsIDOMEvent> event;
-  NS_NewDOMCFStateChangeEvent(getter_AddRefs(event), nullptr, nullptr);
+  NS_NewDOMCFStateChangeEvent(getter_AddRefs(event), this, nullptr, nullptr);
 
   nsCOMPtr<nsIDOMCFStateChangeEvent> ce = do_QueryInterface(event);
   nsresult rv = ce->InitCFStateChangeEvent(NS_LITERAL_STRING("cfstatechange"),
                                            false, false,
                                            aSuccess, aAction, aReason, aNumber,
                                            aSeconds, aServiceClass);
   NS_ENSURE_SUCCESS(rv, rv);
 
--- a/dom/src/events/nsJSEventListener.cpp
+++ b/dom/src/events/nsJSEventListener.cpp
@@ -20,16 +20,17 @@
 #include "nsGkAtoms.h"
 #include "nsIDOMEventTarget.h"
 #include "nsIJSContextStack.h"
 #include "xpcpublic.h"
 #include "nsJSEnvironment.h"
 #include "nsDOMJSUtils.h"
 #include "mozilla/Likely.h"
 #include "mozilla/dom/UnionTypes.h"
+#include "nsDOMEvent.h"
 
 #ifdef DEBUG
 
 #include "nspr.h" // PR_fprintf
 
 class EventListenerCounter
 {
 public:
@@ -187,17 +188,17 @@ nsJSEventListener::HandleEvent(nsIDOMEve
       msgOrEvent.SetAsString() = static_cast<nsAString*>(&errorMsg);
 
       file = scriptEvent->fileName;
       fileName = &file;
 
       lineNumber.Construct();
       lineNumber.Value() = scriptEvent->lineNr;
     } else {
-      msgOrEvent.SetAsEvent() = aEvent;
+      msgOrEvent.SetAsEvent() = aEvent->InternalDOMEvent();
     }
 
     nsRefPtr<OnErrorEventHandlerNonNull> handler =
       mHandler.OnErrorEventHandler();
     ErrorResult rv;
     bool handled = handler->Call(mTarget, msgOrEvent, fileName, lineNumber,
                                  columnNumber, rv);
     if (rv.Failed()) {
@@ -212,17 +213,17 @@ nsJSEventListener::HandleEvent(nsIDOMEve
 
   if (mHandler.Type() == nsEventHandler::eOnBeforeUnload) {
     MOZ_ASSERT(mEventName == nsGkAtoms::onbeforeunload);
 
     nsRefPtr<BeforeUnloadEventHandlerNonNull> handler =
       mHandler.BeforeUnloadEventHandler();
     ErrorResult rv;
     nsString retval;
-    handler->Call(mTarget, aEvent, retval, rv);
+    handler->Call(mTarget, *(aEvent->InternalDOMEvent()), retval, rv);
     if (rv.Failed()) {
       return rv.ErrorCode();
     }
 
     nsCOMPtr<nsIDOMBeforeUnloadEvent> beforeUnload = do_QueryInterface(aEvent);
     NS_ENSURE_STATE(beforeUnload);
 
     if (!DOMStringIsNull(retval)) {
@@ -240,17 +241,18 @@ nsJSEventListener::HandleEvent(nsIDOMEve
     }
 
     return NS_OK;
   }
 
   MOZ_ASSERT(mHandler.Type() == nsEventHandler::eNormal);
   ErrorResult rv;
   nsRefPtr<EventHandlerNonNull> handler = mHandler.EventHandler();
-  JS::Value retval = handler->Call(mTarget, aEvent, rv);
+  JS::Value retval =
+    handler->Call(mTarget, *(aEvent->InternalDOMEvent()), rv);
   if (rv.Failed()) {
     return rv.ErrorCode();
   }
 
   // If the handler returned false and its sense is not reversed,
   // or the handler returned true and its sense is reversed from
   // the usual (false means cancel), then prevent default.
   if (retval.isBoolean() &&
--- a/dom/src/notification/nsDesktopNotification.cpp
+++ b/dom/src/notification/nsDesktopNotification.cpp
@@ -146,17 +146,17 @@ nsDOMDesktopNotification::~nsDOMDesktopN
 void
 nsDOMDesktopNotification::DispatchNotificationEvent(const nsString& aName)
 {
   if (NS_FAILED(CheckInnerWindowCorrectness())) {
     return;
   }
 
   nsCOMPtr<nsIDOMEvent> event;
-  nsresult rv = NS_NewDOMEvent(getter_AddRefs(event), nullptr, nullptr);
+  nsresult rv = NS_NewDOMEvent(getter_AddRefs(event), this, nullptr, nullptr);
   if (NS_SUCCEEDED(rv)) {
     // it doesn't bubble, and it isn't cancelable
     rv = event->InitEvent(aName, false, false);
     if (NS_SUCCEEDED(rv)) {
       event->SetTrusted(true);
       DispatchDOMEvent(nullptr, event, nullptr, nullptr);
     }
   }
--- a/dom/src/offline/nsDOMOfflineResourceList.cpp
+++ b/dom/src/offline/nsDOMOfflineResourceList.cpp
@@ -522,17 +522,17 @@ nsDOMOfflineResourceList::SendEvent(cons
     return NS_OK;
   }
 
   if (!GetOwner()->GetDocShell()) {
     return NS_OK;
   }
 
   nsCOMPtr<nsIDOMEvent> event;
-  nsresult rv = nsEventDispatcher::CreateEvent(nullptr, nullptr,
+  nsresult rv = nsEventDispatcher::CreateEvent(this, nullptr, nullptr,
                                                NS_LITERAL_STRING("Events"),
                                                getter_AddRefs(event));
   NS_ENSURE_SUCCESS(rv, rv);
   event->InitEvent(aEventName, false, true);
 
   // We assume anyone that managed to call SendEvent is trusted
   event->SetTrusted(true);
 
--- a/dom/src/storage/nsDOMStorage.cpp
+++ b/dom/src/storage/nsDOMStorage.cpp
@@ -1623,17 +1623,19 @@ StorageNotifierRunnable::Run()
 
 void
 nsDOMStorage2::BroadcastChangeNotification(const nsSubstring &aKey,
                                            const nsSubstring &aOldValue,
                                            const nsSubstring &aNewValue)
 {
   nsresult rv;
   nsCOMPtr<nsIDOMEvent> domEvent;
-  NS_NewDOMStorageEvent(getter_AddRefs(domEvent), nullptr, nullptr);
+  // Note, this DOM event should never reach JS. It is cloned later in
+  // nsGlobalWindow.
+  NS_NewDOMStorageEvent(getter_AddRefs(domEvent), nullptr, nullptr, nullptr);
   nsCOMPtr<nsIDOMStorageEvent> event = do_QueryInterface(domEvent);
   rv = event->InitStorageEvent(NS_LITERAL_STRING("storage"),
                                false,
                                false,
                                aKey,
                                aOldValue,
                                aNewValue,
                                mDocumentURI,
--- a/dom/system/nsDeviceSensors.cpp
+++ b/dom/system/nsDeviceSensors.cpp
@@ -211,59 +211,59 @@ nsDeviceSensors::Notify(const mozilla::h
     if (WindowCannotReceiveSensorEvent(pwindow)) {
         continue;
     }
 
     nsCOMPtr<nsIDOMDocument> domdoc;
     windowListeners[i]->GetDocument(getter_AddRefs(domdoc));
 
     if (domdoc) {
-      nsCOMPtr<nsIDOMEventTarget> target = do_QueryInterface(windowListeners[i]);
+      nsCOMPtr<mozilla::dom::EventTarget> target = do_QueryInterface(windowListeners[i]);
       if (type == nsIDeviceSensorData::TYPE_ACCELERATION || 
         type == nsIDeviceSensorData::TYPE_LINEAR_ACCELERATION || 
         type == nsIDeviceSensorData::TYPE_GYROSCOPE)
         FireDOMMotionEvent(domdoc, target, type, x, y, z);
       else if (type == nsIDeviceSensorData::TYPE_ORIENTATION)
         FireDOMOrientationEvent(domdoc, target, x, y, z);
       else if (type == nsIDeviceSensorData::TYPE_PROXIMITY)
         FireDOMProximityEvent(target, x, y, z);
       else if (type == nsIDeviceSensorData::TYPE_LIGHT)
         FireDOMLightEvent(target, x);
 
     }
   }
 }
 
 void
-nsDeviceSensors::FireDOMLightEvent(nsIDOMEventTarget *aTarget,
-                                  double aValue)
+nsDeviceSensors::FireDOMLightEvent(mozilla::dom::EventTarget* aTarget,
+                                   double aValue)
 {
   nsCOMPtr<nsIDOMEvent> event;
-  NS_NewDOMDeviceLightEvent(getter_AddRefs(event), nullptr, nullptr);
+  NS_NewDOMDeviceLightEvent(getter_AddRefs(event), aTarget, nullptr, nullptr);
 
   nsCOMPtr<nsIDOMDeviceLightEvent> oe = do_QueryInterface(event);
   oe->InitDeviceLightEvent(NS_LITERAL_STRING("devicelight"),
                           true,
                           false,
                           aValue);
 
   event->SetTrusted(true);
 
   bool defaultActionEnabled;
   aTarget->DispatchEvent(event, &defaultActionEnabled);
 }
 
 void
-nsDeviceSensors::FireDOMProximityEvent(nsIDOMEventTarget *aTarget,
+nsDeviceSensors::FireDOMProximityEvent(mozilla::dom::EventTarget* aTarget,
                                        double aValue,
                                        double aMin,
                                        double aMax)
 {
   nsCOMPtr<nsIDOMEvent> event;
-  NS_NewDOMDeviceProximityEvent(getter_AddRefs(event), nullptr, nullptr);
+  NS_NewDOMDeviceProximityEvent(getter_AddRefs(event), aTarget, nullptr, nullptr);
   nsCOMPtr<nsIDOMDeviceProximityEvent> oe = do_QueryInterface(event);
 
   oe->InitDeviceProximityEvent(NS_LITERAL_STRING("deviceproximity"),
                                true,
                                false,
                                aValue,
                                aMin,
                                aMax);
@@ -281,20 +281,21 @@ nsDeviceSensors::FireDOMProximityEvent(n
   bool near = (aValue < aMax);
   if (mIsUserProximityNear != near) {
     mIsUserProximityNear = near;
     FireDOMUserProximityEvent(aTarget, mIsUserProximityNear);
   }
 }
 
 void
-nsDeviceSensors::FireDOMUserProximityEvent(nsIDOMEventTarget *aTarget, bool aNear)
+nsDeviceSensors::FireDOMUserProximityEvent(mozilla::dom::EventTarget* aTarget,
+                                           bool aNear)
 {
   nsCOMPtr<nsIDOMEvent> event;
-  NS_NewDOMUserProximityEvent(getter_AddRefs(event), nullptr, nullptr);
+  NS_NewDOMUserProximityEvent(getter_AddRefs(event), aTarget, nullptr, nullptr);
   nsCOMPtr<nsIDOMUserProximityEvent> pe = do_QueryInterface(event);
 
   pe->InitUserProximityEvent(NS_LITERAL_STRING("userproximity"),
                              true,
                              false,
                              aNear);
 
   event->SetTrusted(true);
--- a/dom/system/nsDeviceSensors.h
+++ b/dom/system/nsDeviceSensors.h
@@ -40,25 +40,25 @@ public:
   virtual ~nsDeviceSensors();
 
   void Notify(const mozilla::hal::SensorData& aSensorData);
 
 private:
   // sensor -> window listener
   nsTArray<nsTArray<nsIDOMWindow*>* > mWindowListeners;
 
-  void FireDOMLightEvent(nsIDOMEventTarget *target,
+  void FireDOMLightEvent(mozilla::dom::EventTarget* aTarget,
                          double value);
 
-  void FireDOMProximityEvent(nsIDOMEventTarget *aTarget,
+  void FireDOMProximityEvent(mozilla::dom::EventTarget* aTarget,
                              double aValue,
                              double aMin,
                              double aMax);
 
-  void FireDOMUserProximityEvent(nsIDOMEventTarget *aTarget,
+  void FireDOMUserProximityEvent(mozilla::dom::EventTarget* aTarget,
                                  bool aNear);
 
   void FireDOMOrientationEvent(class nsIDOMDocument *domDoc, 
                                class nsIDOMEventTarget *target,
                                double alpha,
                                double beta,
                                double gamma);
 
--- a/dom/telephony/Telephony.cpp
+++ b/dom/telephony/Telephony.cpp
@@ -501,17 +501,17 @@ Telephony::NotifyError(int32_t aCallInde
 
 nsresult
 Telephony::DispatchCallEvent(const nsAString& aType,
                              nsIDOMTelephonyCall* aCall)
 {
   MOZ_ASSERT(aCall);
 
   nsCOMPtr<nsIDOMEvent> event;
-  NS_NewDOMCallEvent(getter_AddRefs(event), nullptr, nullptr);
+  NS_NewDOMCallEvent(getter_AddRefs(event), this, nullptr, nullptr);
   NS_ASSERTION(event, "This should never fail!");
 
   nsCOMPtr<nsIDOMCallEvent> callEvent = do_QueryInterface(event);
   MOZ_ASSERT(callEvent);
   nsresult rv = callEvent->InitCallEvent(aType, false, false, aCall);
   NS_ENSURE_SUCCESS(rv, rv);
 
   return DispatchTrustedEvent(callEvent);
--- a/dom/telephony/TelephonyCall.cpp
+++ b/dom/telephony/TelephonyCall.cpp
@@ -126,17 +126,17 @@ TelephonyCall::ChangeStateInternal(uint1
 
 nsresult
 TelephonyCall::DispatchCallEvent(const nsAString& aType,
                                  nsIDOMTelephonyCall* aCall)
 {
   MOZ_ASSERT(aCall);
 
   nsCOMPtr<nsIDOMEvent> event;
-  NS_NewDOMCallEvent(getter_AddRefs(event), nullptr, nullptr);
+  NS_NewDOMCallEvent(getter_AddRefs(event), this, nullptr, nullptr);
   NS_ASSERTION(event, "This should never fail!");
 
   nsCOMPtr<nsIDOMCallEvent> callEvent = do_QueryInterface(event);
   MOZ_ASSERT(callEvent);
   nsresult rv = callEvent->InitCallEvent(aType, false, false, aCall);
   NS_ENSURE_SUCCESS(rv, rv);
 
   return DispatchTrustedEvent(callEvent);
--- a/dom/tests/mochitest/bugs/test_bug484775.html
+++ b/dom/tests/mochitest/bugs/test_bug484775.html
@@ -21,32 +21,34 @@ https://bugzilla.mozilla.org/show_bug.cg
 /** Test for Bug 484775 **/
 
 var expectedTarget = null;
 var expectedType = null;
 var eventCount = 0;
 
 function listener(evt) {
   ++eventCount;
-  ok(evt.type, expectedType, "Wrong event type!");
-  ok(evt.target, expectedTarget, "Wrong event type!");
+  is(evt.type, expectedType, "Wrong event type!");
+  is(evt.target, expectedTarget, "Wrong event target!");
 }
 
 expectedType = "TestEvent";
 var event = document.createEvent("Event");
 event.initEvent(expectedType, true, true);
-ok(event.type, expectedType, "Wrong event type!");
+is(event.type, expectedType, "Wrong event type after initEvent!");
 
 var attr = document.createAttribute("attribute");
+expectedTarget = attr;
 attr.addEventListener(expectedType, listener, false);
 attr.dispatchEvent(event);
 is(eventCount, 1, "Should have fired an event!");
 attr.removeEventListener(expectedType, listener, false);
 
 var df = document.createDocumentFragment();
+expectedTarget = df;
 df.addEventListener(expectedType, listener, false);
 df.dispatchEvent(event);
 is(eventCount, 2, "Should have fired an event!");
 df.removeEventListener(expectedType, listener, false);
 
 </script>
 </pre>
 </body>
--- a/dom/voicemail/Voicemail.cpp
+++ b/dom/voicemail/Voicemail.cpp
@@ -103,17 +103,17 @@ Voicemail::GetDisplayName(nsAString& aDi
 NS_IMPL_EVENT_HANDLER(Voicemail, statuschanged)
 
 // nsIVoicemailListener
 
 NS_IMETHODIMP
 Voicemail::NotifyStatusChanged(nsIDOMMozVoicemailStatus* aStatus)
 {
   nsCOMPtr<nsIDOMEvent> event;
-  NS_NewDOMMozVoicemailEvent(getter_AddRefs(event), nullptr, nullptr);
+  NS_NewDOMMozVoicemailEvent(getter_AddRefs(event), this, nullptr, nullptr);
 
   nsCOMPtr<nsIDOMMozVoicemailEvent> ce = do_QueryInterface(event);
   nsresult rv = ce->InitMozVoicemailEvent(NS_LITERAL_STRING("statuschanged"),
                                           false, false, aStatus);
   NS_ENSURE_SUCCESS(rv, rv);
 
   return DispatchTrustedEvent(ce);
 }
--- a/dom/webidl/Event.webidl
+++ b/dom/webidl/Event.webidl
@@ -11,33 +11,81 @@
  */
 
 [Constructor(DOMString type, optional EventInit eventInitDict)]
 interface Event {
   readonly attribute DOMString type;
   readonly attribute EventTarget? target;
   readonly attribute EventTarget? currentTarget;
 
+  const unsigned short NONE = 0;
   const unsigned short CAPTURING_PHASE = 1;
   const unsigned short AT_TARGET = 2;
   const unsigned short BUBBLING_PHASE = 3;
   readonly attribute unsigned short eventPhase;
 
   void stopPropagation();
   void stopImmediatePropagation();
 
   readonly attribute boolean bubbles;
   readonly attribute boolean cancelable;
   void preventDefault();
   readonly attribute boolean defaultPrevented;
 
   readonly attribute boolean isTrusted;
   readonly attribute DOMTimeStamp timeStamp;
 
+  [Throws]
   void initEvent(DOMString type, boolean bubbles, boolean cancelable);
 };
 
-/*
+// Mozilla specific legacy stuff.
+partial interface Event {
+  const long MOUSEDOWN    = 0x00000001;
+  const long MOUSEUP      = 0x00000002;
+  const long MOUSEOVER    = 0x00000004;
+  const long MOUSEOUT     = 0x00000008;
+  const long MOUSEMOVE    = 0x00000010;
+  const long MOUSEDRAG    = 0x00000020;
+  const long CLICK        = 0x00000040;
+  const long DBLCLICK     = 0x00000080;
+  const long KEYDOWN      = 0x00000100;
+  const long KEYUP        = 0x00000200;
+  const long KEYPRESS     = 0x00000400;
+  const long DRAGDROP     = 0x00000800;
+  const long FOCUS        = 0x00001000;
+  const long BLUR         = 0x00002000;
+  const long SELECT       = 0x00004000;
+  const long CHANGE       = 0x00008000;
+  const long RESET        = 0x00010000;
+  const long SUBMIT       = 0x00020000;
+  const long SCROLL       = 0x00040000;
+  const long LOAD         = 0x00080000;
+  const long UNLOAD       = 0x00100000;
+  const long XFER_DONE    = 0x00200000;
+  const long ABORT        = 0x00400000;
+  const long ERROR        = 0x00800000;
+  const long LOCATE       = 0x01000000;
+  const long MOVE         = 0x02000000;
+  const long RESIZE       = 0x04000000;
+  const long FORWARD      = 0x08000000;
+  const long HELP         = 0x10000000;
+  const long BACK         = 0x20000000;
+  const long TEXT         = 0x40000000;
+
+  const long ALT_MASK     = 0x00000001;
+  const long CONTROL_MASK = 0x00000002;
+  const long SHIFT_MASK   = 0x00000004;
+  const long META_MASK    = 0x00000008;
+
+  readonly attribute EventTarget? originalTarget;
+  readonly attribute EventTarget? explicitOriginalTarget;
+
+  void preventBubble();
+  void preventCapture();
+  boolean getPreventDefault();
+};
+
 dictionary EventInit {
-  boolean bubbles;
-  boolean cancelable;
+  boolean bubbles = false;
+  boolean cancelable = false;
 };
-*/
+
--- a/dom/webidl/EventListener.webidl
+++ b/dom/webidl/EventListener.webidl
@@ -5,13 +5,11 @@
  *
  * The origin of this IDL file is
  * http://www.w3.org/TR/2012/WD-dom-20120105/
  *
  * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
  * liability, trademark and document use rules apply.
  */
 
-interface Event;
-
 callback interface EventListener {
   void handleEvent(Event event);
 };
--- a/dom/webidl/EventTarget.webidl
+++ b/dom/webidl/EventTarget.webidl
@@ -5,18 +5,16 @@
  *
  * The origin of this IDL file is
  * http://www.w3.org/TR/2012/WD-dom-20120105/
  *
  * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
  * liability, trademark and document use rules apply.
  */
 
-interface Event;
-
 interface EventTarget {
   /* Passing null for wantsUntrusted means "default behavior", which
      differs in content and chrome.  In content that default boolean
      value is true, while in chrome the default boolean value is
      false. */
   [Throws]
   void addEventListener(DOMString type,
                         EventListener? listener,
--- a/dom/webidl/WebIDL.mk
+++ b/dom/webidl/WebIDL.mk
@@ -40,16 +40,17 @@ webidl_files = \
   DOMParser.webidl \
   DOMSettableTokenList.webidl \
   DOMStringMap.webidl \
   DOMTokenList.webidl \
   DOMTransaction.webidl \
   DummyBinding.webidl \
   DynamicsCompressorNode.webidl \
   Element.webidl \
+  Event.webidl \
   EventHandler.webidl \
   EventListener.webidl \
   EventSource.webidl \
   EventTarget.webidl \
   File.webidl \
   FileHandle.webidl \
   FileList.webidl \
   FileReaderSync.webidl \
--- a/dom/workers/EventTarget.h
+++ b/dom/workers/EventTarget.h
@@ -41,19 +41,19 @@ public:
                    bool aCapture, Nullable<bool> aWantsUntrusted,
                    ErrorResult& aRv);
 
   void
   RemoveEventListener(const nsAString& aType, JSObject* aListener,
                       bool aCapture, ErrorResult& aRv);
 
   bool
-  DispatchEvent(JSObject* aEvent, ErrorResult& aRv) const
+  DispatchEvent(JSObject& aEvent, ErrorResult& aRv) const
   {
-    return mListenerManager.DispatchEvent(GetJSContext(), *this, aEvent, aRv);
+    return mListenerManager.DispatchEvent(GetJSContext(), *this, &aEvent, aRv);
   }
 
   JSObject*
   GetEventListener(const nsAString& aType, ErrorResult& aRv) const;
 
   void
   SetEventListener(const nsAString& aType, JSObject* aListener,
                    ErrorResult& aRv);
--- a/js/xpconnect/src/event_impl_gen.py
+++ b/js/xpconnect/src/event_impl_gen.py
@@ -64,20 +64,27 @@ def print_header_file(fd, conf):
         fd.write("#include \"nsIDOM%s.h\"\n" % e)
     fd.write("#else\n")
     fd.write("#ifndef _gen_mozilla_idl_generated_events_h_\n"
              "#define _gen_mozilla_idl_generated_events_h_\n\n")
     fd.write("/* THIS FILE IS AUTOGENERATED - DO NOT EDIT */\n")
     fd.write("#include \"nscore.h\"\n")
     fd.write("class nsEvent;\n")
     fd.write("class nsIDOMEvent;\n")
-    fd.write("class nsPresContext;\n\n")
+    fd.write("class nsPresContext;\n")
+    fd.write("namespace mozilla {\n");
+    fd.write("namespace dom {\n");
+    fd.write("class EventTarget;\n")
+    fd.write("}\n");
+    fd.write("}\n\n");
     for e in conf.simple_events:
         fd.write("nsresult\n")
-        fd.write("NS_NewDOM%s(nsIDOMEvent** aInstance, nsPresContext* aPresContext, nsEvent* aEvent);\n" % e)
+        fd.write("NS_NewDOM%s(nsIDOMEvent** aInstance, " % e)
+        fd.write("mozilla::dom::EventTarget* aOwner, ")
+        fd.write("nsPresContext* aPresContext, nsEvent* aEvent);\n")
  
     fd.write("\n#endif\n")
     fd.write("#endif\n")
 
 def collect_names_and_non_primitive_attribute_types(idl, attrnames, forwards):
     for p in idl.productions:
         if p.kind == 'interface' or p.kind == 'dictionary':
             interfaces = []
@@ -111,16 +118,17 @@ def print_cpp(idl, fd, conf, eventname):
 
 def print_cpp_file(fd, conf):
     fd.write("/* THIS FILE IS AUTOGENERATED - DO NOT EDIT */\n\n")
     fd.write('#include "GeneratedEvents.h"\n')
     fd.write('#include "nsDOMClassInfoID.h"\n')
     fd.write('#include "nsPresContext.h"\n')
     fd.write('#include "nsGUIEvent.h"\n')
     fd.write('#include "nsDOMEvent.h"\n');
+    fd.write('#include "mozilla/dom/EventTarget.h"\n');
 
     includes = []
     for s in conf.special_includes:
         if not s in includes:
             includes.append(strip_end(s, ".h"))
     
     for e in conf.simple_events:
         if not e in includes:
@@ -226,18 +234,19 @@ def write_cpp(eventname, iface, fd):
         for member in baseiface.members:
             if isinstance(member, xpidl.Attribute):
                 baseattributes.append(member)
 
 
     fd.write("\nclass %s : public %s, public %s\n" % (classname, basename, iface.name))
     fd.write("{\n")
     fd.write("public:\n")
-    fd.write("  %s(nsPresContext* aPresContext, nsEvent* aEvent)\n" % classname)
-    fd.write("  : %s(aPresContext, aEvent)" % basename)
+    fd.write("  %s(mozilla::dom::EventTarget* aOwner, " % classname)
+    fd.write("nsPresContext* aPresContext = nullptr, nsEvent* aEvent = nullptr)\n");
+    fd.write("  : %s(aOwner, aPresContext, aEvent)" % basename)
     for a in attributes:
         fd.write(",\n    m%s(%s)" % (firstCap(a.name), init_value(a)))
     fd.write("\n  {}\n")
     fd.write("  virtual ~%s() {}\n\n" % classname)
     fd.write("  NS_DECL_ISUPPORTS_INHERITED\n")
     fd.write("  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(%s, %s)\n" % (classname, basename))
     fd.write("  NS_FORWARD_TO_NSDOMEVENT\n")
 
@@ -302,19 +311,20 @@ def write_cpp(eventname, iface, fd):
         fd.write("  m%s = a%s;\n" % (firstCap(a.name), firstCap(a.name)))
     fd.write("  return NS_OK;\n")
     fd.write("}\n\n")
 
     for a in attributes:
         writeAttributeGetter(fd, classname, a)
 
     fd.write("nsresult\n")
-    fd.write("NS_NewDOM%s(nsIDOMEvent** aInstance, nsPresContext* aPresContext, nsEvent* aEvent)\n" % eventname)
+    fd.write("NS_NewDOM%s(nsIDOMEvent** aInstance, "  % eventname)
+    fd.write("mozilla::dom::EventTarget* aOwner, nsPresContext* aPresContext = nullptr, nsEvent* aEvent = nullptr)\n")
     fd.write("{\n")
-    fd.write("  %s* it = new %s(aPresContext, aEvent);\n" % (classname, classname))
+    fd.write("  %s* it = new %s(aOwner, aPresContext, aEvent);\n" % (classname, classname))
     fd.write("  return CallQueryInterface(it, aInstance);\n")
     fd.write("}\n\n")
 
 if __name__ == '__main__':
     from optparse import OptionParser
     o = OptionParser(usage="usage: %prog [options] configfile")
     o.add_option('-I', action='append', dest='incdirs', default=['.'],
                  help="Directory to search for imported files")
--- a/js/xpconnect/src/nsDOMQS.h
+++ b/js/xpconnect/src/nsDOMQS.h
@@ -11,16 +11,17 @@
 #include "nsHTMLFormElement.h"
 #include "mozilla/dom/HTMLImageElement.h"
 #include "mozilla/dom/HTMLOptionElement.h"
 #include "HTMLOptGroupElement.h"
 #include "nsHTMLVideoElement.h"
 #include "nsHTMLDocument.h"
 #include "nsICSSDeclaration.h"
 #include "nsSVGElement.h"
+#include "nsDOMEvent.h"
 #include "mozilla/dom/EventTargetBinding.h"
 #include "mozilla/dom/NodeBinding.h"
 #include "mozilla/dom/ElementBinding.h"
 #include "mozilla/dom/HTMLElementBinding.h"
 #include "mozilla/dom/DocumentBinding.h"
 #include "mozilla/dom/SVGElementBinding.h"
 
 template<class T>
@@ -45,16 +46,17 @@ struct ProtoIDAndDepth<_native>         
 
 NEW_BINDING(mozilla::dom::EventTarget, EventTarget);
 NEW_BINDING(nsINode, Node);
 NEW_BINDING(mozilla::dom::Element, Element);
 NEW_BINDING(nsGenericHTMLElement, HTMLElement);
 NEW_BINDING(nsIDocument, Document);
 NEW_BINDING(nsDocument, Document);
 NEW_BINDING(nsSVGElement, SVGElement);
+NEW_BINDING(nsDOMEvent, Event);
 
 #define DEFINE_UNWRAP_CAST(_interface, _base, _bit)                           \
 template <>                                                                   \
 MOZ_ALWAYS_INLINE JSBool                                                      \
 xpc_qsUnwrapThis<_interface>(JSContext *cx,                                   \
                              JSObject *obj,                                   \
                              _interface **ppThis,                             \
                              nsISupports **pThisRef,                          \
--- a/layout/base/nsPresContext.cpp
+++ b/layout/base/nsPresContext.cpp
@@ -2073,35 +2073,35 @@ nsPresContext::EnsureSafeToHandOutCSSRul
 
 void
 nsPresContext::FireDOMPaintEvent(nsInvalidateRequestList* aList)
 {
   nsPIDOMWindow* ourWindow = mDocument->GetWindow();
   if (!ourWindow)
     return;
 
-  nsCOMPtr<nsIDOMEventTarget> dispatchTarget = do_QueryInterface(ourWindow);
-  nsCOMPtr<nsIDOMEventTarget> eventTarget = dispatchTarget;
+  nsCOMPtr<EventTarget> dispatchTarget = do_QueryInterface(ourWindow);
+  nsCOMPtr<EventTarget> eventTarget = dispatchTarget;
   if (!IsChrome() && !mSendAfterPaintToContent) {
     // Don't tell the window about this event, it should not know that
     // something happened in a subdocument. Tell only the chrome event handler.
     // (Events sent to the window get propagated to the chrome event handler
     // automatically.)
     dispatchTarget = do_QueryInterface(ourWindow->GetParentTarget());
     if (!dispatchTarget) {
       return;
     }
   }
   // Events sent to the window get propagated to the chrome event handler
   // automatically.
   nsCOMPtr<nsIDOMEvent> event;
   // This will empty our list in case dispatching the event causes more damage
   // (hopefully it won't, or we're likely to get an infinite loop! At least
   // it won't be blocking app execution though).
-  NS_NewDOMNotifyPaintEvent(getter_AddRefs(event), this, nullptr,
+  NS_NewDOMNotifyPaintEvent(getter_AddRefs(event), eventTarget, this, nullptr,
                             NS_AFTERPAINT, aList);
   if (!event) {
     return;
   }
 
   // Even if we're not telling the window about the event (so eventTarget is
   // the chrome event handler, not the window), the window is still
   // logically the event target.
--- a/layout/xul/base/src/nsMenuFrame.cpp
+++ b/layout/xul/base/src/nsMenuFrame.cpp
@@ -88,17 +88,17 @@ public:
     }
     else {
       // Unhighlight the menu.
       mMenu->UnsetAttr(kNameSpaceID_None, nsGkAtoms::menuactive, true);
       domEventToFire.AssignLiteral("DOMMenuItemInactive");
     }
 
     nsCOMPtr<nsIDOMEvent> event;
-    if (NS_SUCCEEDED(nsEventDispatcher::CreateEvent(mPresContext, nullptr,
+    if (NS_SUCCEEDED(nsEventDispatcher::CreateEvent(mMenu, mPresContext, nullptr,
                                                     NS_LITERAL_STRING("Events"),
                                                     getter_AddRefs(event)))) {
       event->InitEvent(domEventToFire, true, true);
 
       event->SetTrusted(true);
 
       nsEventDispatcher::DispatchDOMEvent(mMenu, nullptr, event,
                                           mPresContext, nullptr);
--- a/security/manager/ssl/src/nsNSSComponent.cpp
+++ b/security/manager/ssl/src/nsNSSComponent.cpp
@@ -33,16 +33,17 @@
 #include "nsThreadUtils.h"
 
 #ifndef MOZ_DISABLE_CRYPTOLEGACY
 #include "nsIDOMNode.h"
 #include "nsIDOMEvent.h"
 #include "nsIDOMDocument.h"
 #include "nsIDOMWindow.h"
 #include "nsIDOMWindowCollection.h"
+#include "nsIDocument.h"
 #include "nsIDOMSmartCardEvent.h"
 #include "nsSmartCardMonitor.h"
 #include "nsIDOMCryptoLegacy.h"
 #include "nsIPrincipal.h"
 #else
 #include "nsIDOMCrypto.h"
 #endif
 
@@ -521,19 +522,21 @@ nsNSSComponent::DispatchEventToWindow(ns
 
   // find the document
   nsCOMPtr<nsIDOMDocument> doc;
   rv = domWin->GetDocument(getter_AddRefs(doc));
   if (!doc) {
     return NS_FAILED(rv) ? rv : NS_ERROR_FAILURE;
   }
 
+  nsCOMPtr<nsIDocument> d = do_QueryInterface(doc);
+
   // create the event
   nsCOMPtr<nsIDOMEvent> event;
-  NS_NewDOMSmartCardEvent(getter_AddRefs(event), nullptr, nullptr);
+  NS_NewDOMSmartCardEvent(getter_AddRefs(event), d, nullptr, nullptr);
   nsCOMPtr<nsIDOMSmartCardEvent> smartCardEvent = do_QueryInterface(event);
   rv = smartCardEvent->InitSmartCardEvent(eventType, false, true, tokenName);
   NS_ENSURE_SUCCESS(rv, rv);
   smartCardEvent->SetTrusted(true);
 
   // Send it 
   nsCOMPtr<nsIDOMEventTarget> target = do_QueryInterface(doc, &rv);
   if (NS_FAILED(rv)) {