Bug 658714 Part 9: Don't use EventGroups for system-group. r=smaug
authorJonas Sicking <jonas@sicking.cc>
Thu, 23 Jun 2011 19:18:02 -0700
changeset 71657 47c73a8334bb6b4bc059fcd6e8bbf6ac8d2a4cb1
parent 71656 7236111084214e4141934859855a79a96a19de13
child 71658 c980dcde975498d0529112b4a2854e31d5212f16
push id219
push usermak77@bonardo.net
push dateFri, 24 Jun 2011 09:42:20 +0000
treeherdermozilla-inbound@537f0d13d96c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs658714
milestone7.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 658714 Part 9: Don't use EventGroups for system-group. r=smaug
content/base/src/nsGenericElement.cpp
content/events/public/nsIEventListenerService.idl
content/events/src/nsDOMEventTargetHelper.cpp
content/events/src/nsEventListenerManager.cpp
content/events/src/nsEventListenerManager.h
content/events/src/nsEventListenerService.cpp
content/html/content/src/nsTextEditorState.cpp
content/smil/nsSMILTimeValueSpec.cpp
content/smil/nsSMILTimeValueSpec.h
content/xbl/src/nsXBLBinding.cpp
content/xbl/src/nsXBLService.cpp
content/xul/content/src/nsXULElement.cpp
dom/base/nsGlobalWindow.cpp
dom/base/nsWindowRoot.cpp
dom/interfaces/events/nsIDOMEventTarget.idl
dom/src/threads/nsDOMWorkerMessageHandler.cpp
dom/src/threads/nsDOMWorkerMessageHandler.h
editor/libeditor/base/nsEditorEventListener.cpp
editor/libeditor/html/tests/test_contenteditable_text_input_handling.html
editor/libeditor/html/tests/test_htmleditor_keyevent_handling.html
editor/libeditor/text/tests/test_bug569988.html
editor/libeditor/text/tests/test_texteditor_keyevent_handling.html
embedding/browser/webBrowser/nsDocShellTreeOwner.cpp
layout/forms/nsFileControlFrame.cpp
testing/mochitest/specialpowers/content/specialpowers.js
--- a/content/base/src/nsGenericElement.cpp
+++ b/content/base/src/nsGenericElement.cpp
@@ -1057,24 +1057,16 @@ nsINode::RemoveEventListenerByIID(nsIDOM
 }
 
 nsEventListenerManager*
 nsINode::GetListenerManager(PRBool aCreateIfNotFound)
 {
   return nsContentUtils::GetListenerManager(this, aCreateIfNotFound);
 }
 
-nsresult
-nsINode::GetSystemEventGroup(nsIDOMEventGroup** aGroup)
-{
-  nsEventListenerManager* elm = GetListenerManager(PR_TRUE);
-  NS_ENSURE_STATE(elm);
-  return elm->GetSystemEventGroupLM(aGroup);
-}
-
 nsIScriptContext*
 nsINode::GetContextForEventHandlers(nsresult* aRv)
 {
   return nsContentUtils::GetContextForEventHandlers(this, aRv);
 }
 
 //----------------------------------------------------------------------
 
--- a/content/events/public/nsIEventListenerService.idl
+++ b/content/events/public/nsIEventListenerService.idl
@@ -62,17 +62,17 @@ interface nsIEventListenerInfo : nsISupp
 
   /**
    * If jsdIDebuggerService is active and the listener is implemented in JS,
    * this returns the listener as a jsdIValue. Otherwise null.
    */
   nsISupports getDebugObject();
 };
 
-[scriptable, uuid(7b0ca544-a38f-4072-96c6-5fff4996277a)]
+[scriptable, uuid(0cf94aa6-ea9a-44cb-a063-be834afa679d)]
 interface nsIEventListenerService : nsISupports
 {
   /**
    * Returns an array of nsIEventListenerInfo objects.
    * If aEventTarget doesn't have any listeners, this returns null.
    */
   void getListenerInfoFor(in nsIDOMEventTarget aEventTarget,
                           [optional] out unsigned long aCount,
@@ -94,13 +94,24 @@ interface nsIEventListenerService : nsIS
 
   /**
    * Returns true if a event target has any listener for the given type.
    */
   boolean hasListenersFor(in nsIDOMEventTarget aEventTarget,
                           in DOMString aType);
 
   /**
-   * Returns system event group.
+   * Add a system-group eventlistener to a event target.
    */
-  readonly attribute nsIDOMEventGroup systemEventGroup;
+  void addSystemEventListener(in nsIDOMEventTarget target,
+                              in DOMString type,
+                              in nsIDOMEventListener listener,
+                              in boolean useCapture);
+
+  /**
+   * Remove a system-group eventlistener from a event target.
+   */
+  void removeSystemEventListener(in nsIDOMEventTarget target,
+                                 in DOMString type,
+                                 in nsIDOMEventListener listener,
+                                 in boolean useCapture);
 };
 
--- a/content/events/src/nsDOMEventTargetHelper.cpp
+++ b/content/events/src/nsDOMEventTargetHelper.cpp
@@ -221,24 +221,16 @@ nsDOMEventTargetHelper::RemoveEventListe
 {
   nsEventListenerManager* elm = GetListenerManager(PR_FALSE);
   if (elm) {
     elm->RemoveEventListenerByIID(aListener, aIID, NS_EVENT_FLAG_BUBBLE);
   }
   return NS_OK;
 }
 
-nsresult
-nsDOMEventTargetHelper::GetSystemEventGroup(nsIDOMEventGroup** aGroup)
-{
-  nsEventListenerManager* elm = GetListenerManager(PR_TRUE);
-  NS_ENSURE_STATE(elm);
-  return elm->GetSystemEventGroupLM(aGroup);
-}
-
 nsIScriptContext*
 nsDOMEventTargetHelper::GetContextForEventHandlers(nsresult* aRv)
 {
   *aRv = CheckInnerWindowCorrectness();
   if (NS_FAILED(*aRv)) {
     return nsnull;
   }
   return mScriptContext;
--- a/content/events/src/nsEventListenerManager.cpp
+++ b/content/events/src/nsEventListenerManager.cpp
@@ -267,17 +267,16 @@ static const EventTypeData sEventTypes[]
   IMPL_EVENTTYPEDATA(Focus),
   IMPL_EVENTTYPEDATA(Form),
   IMPL_EVENTTYPEDATA(Text),
   IMPL_EVENTTYPEDATA(Composition),
   IMPL_EVENTTYPEDATA(UI)
 };
 
 // Strong references to event groups
-nsIDOMEventGroup* gSystemEventGroup = nsnull;
 nsIDOMEventGroup* gDOM2EventGroup = nsnull;
 
 PRUint32 nsEventListenerManager::mInstanceCount = 0;
 PRUint32 nsEventListenerManager::sCreatedCount = 0;
 
 nsEventListenerManager::nsEventListenerManager(nsISupports* aTarget) :
   mTarget(aTarget)
 {
@@ -311,30 +310,20 @@ void
 nsEventListenerManager::RemoveAllListeners()
 {
   mListeners.Clear();
 }
 
 void
 nsEventListenerManager::Shutdown()
 {
-  NS_IF_RELEASE(gSystemEventGroup);
   sAddListenerID = JSID_VOID;
   nsDOMEvent::Shutdown();
 }
 
-nsIDOMEventGroup*
-nsEventListenerManager::GetSystemEventGroup()
-{
-  if (!gSystemEventGroup) {
-    CallCreateInstance(kDOMEventGroupCID, &gSystemEventGroup);
-  }
-  return gSystemEventGroup;
-}
-
 NS_IMPL_CYCLE_COLLECTION_CLASS(nsEventListenerManager)
 
 NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(nsEventListenerManager, AddRef)
 NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(nsEventListenerManager, Release)
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_BEGIN(nsEventListenerManager)
   PRUint32 count = tmp->mListeners.Length();
   for (PRUint32 i = 0; i < count; i++) {
@@ -404,28 +393,16 @@ nsEventListenerManager::AddEventListener
                                          PRInt32 aFlags,
                                          nsIDOMEventGroup* aEvtGrp)
 {
   NS_ENSURE_TRUE(aListener, NS_ERROR_FAILURE);
   NS_ENSURE_TRUE(aType || aTypeData, NS_ERROR_FAILURE);
 
   nsRefPtr<nsIDOMEventListener> kungFuDeathGrip = aListener;
 
-  PRBool isSame = PR_FALSE;
-  PRUint16 group = 0;
-  nsCOMPtr<nsIDOMEventGroup> sysGroup;
-  GetSystemEventGroupLM(getter_AddRefs(sysGroup));
-  if (sysGroup) {
-    sysGroup->IsSameEventGroup(aEvtGrp, &isSame);
-    if (isSame) {
-      group = NS_EVENT_FLAG_SYSTEM_EVENT;
-      mMayHaveSystemGroupListeners = PR_TRUE;
-    }
-  }
-
   if (!aTypeData) {
     // If we don't have type data, we can try to QI listener to the right
     // interface and set mTypeData only if QI succeeds. This way we can save
     // calls to DispatchToInterface (in HandleEvent) in those cases when QI
     // would fail.
     // @see also DispatchToInterface()
     const EventTypeData* td = GetTypeDataForEventName(aTypeAtom);
     if (td && td->iid) {
@@ -438,34 +415,36 @@ nsEventListenerManager::AddEventListener
     }
   }
 
   nsListenerStruct* ls;
   PRUint32 count = mListeners.Length();
   for (PRUint32 i = 0; i < count; i++) {
     ls = &mListeners.ElementAt(i);
     if (ls->mListener == aListener && ls->mFlags == aFlags &&
-        ls->mGroupFlags == group &&
         (EVENT_TYPE_EQUALS(ls, aType, aTypeAtom) ||
          EVENT_TYPE_DATA_EQUALS(aTypeData, ls->mTypeData))) {
       return NS_OK;
     }
   }
 
   mNoListenerForEvent = NS_EVENT_TYPE_NULL;
   mNoListenerForEventAtom = nsnull;
 
   ls = mListeners.AppendElement();
   ls->mListener = aListener;
   ls->mEventType = aType;
   ls->mTypeAtom = aTypeAtom;
   ls->mFlags = aFlags;
-  ls->mGroupFlags = group;
   ls->mHandlerIsString = PR_FALSE;
   ls->mTypeData = aTypeData;
+
+  if (aFlags & NS_EVENT_FLAG_SYSTEM_EVENT) {
+    mMayHaveSystemGroupListeners = PR_TRUE;
+  }
   if (aFlags & NS_EVENT_FLAG_CAPTURE) {
     mMayHaveCapturingListeners = PR_TRUE;
   }
 
   if (aType == NS_AFTERPAINT) {
     mMayHavePaintEventListener = PR_TRUE;
     nsPIDOMWindow* window = GetInnerWindowForTarget();
     if (window) {
@@ -520,35 +499,23 @@ nsEventListenerManager::RemoveEventListe
                                             const EventTypeData* aTypeData,
                                             PRInt32 aFlags,
                                             nsIDOMEventGroup* aEvtGrp)
 {
   if (!aListener || !(aType || aTypeData)) {
     return;
   }
 
-  PRBool isSame = PR_FALSE;
-  PRUint16 group = 0;
-  nsCOMPtr<nsIDOMEventGroup> sysGroup;
-  GetSystemEventGroupLM(getter_AddRefs(sysGroup));
-  if (sysGroup) {
-    sysGroup->IsSameEventGroup(aEvtGrp, &isSame);
-    if (isSame) {
-      group = NS_EVENT_FLAG_SYSTEM_EVENT;
-    }
-  }
-
   nsListenerStruct* ls;
   aFlags &= ~NS_PRIV_EVENT_UNTRUSTED_PERMITTED;
 
   PRUint32 count = mListeners.Length();
   for (PRUint32 i = 0; i < count; ++i) {
     ls = &mListeners.ElementAt(i);
     if (ls->mListener == aListener &&
-        ls->mGroupFlags == group &&
         ((ls->mFlags & ~NS_PRIV_EVENT_UNTRUSTED_PERMITTED) == aFlags) &&
         (EVENT_TYPE_EQUALS(ls, aType, aUserType) ||
          (!(ls->mEventType) &&
           EVENT_TYPE_DATA_EQUALS(ls->mTypeData, aTypeData)))) {
       nsRefPtr<nsEventListenerManager> kungFuDeathGrip = this;
       mListeners.RemoveElementAt(i);
       mNoListenerForEvent = NS_EVENT_TYPE_NULL;
       mNoListenerForEventAtom = nsnull;
@@ -1141,17 +1108,16 @@ nsEventListenerManager::HandleEventInter
                                             PRUint32 aFlags,
                                             nsEventStatus* aEventStatus,
                                             nsCxPusher* aPusher)
 {
   //Set the value of the internal PreventDefault flag properly based on aEventStatus
   if (*aEventStatus == nsEventStatus_eConsumeNoDefault) {
     aEvent->flags |= NS_EVENT_FLAG_NO_DEFAULT;
   }
-  PRUint16 currentGroup = aFlags & NS_EVENT_FLAG_SYSTEM_EVENT;
 
   const EventTypeData* typeData = nsnull;
   const EventDispatchData* dispData = nsnull;
   if (aEvent->message != NS_USER_DEFINED_EVENT) {
     // Check if this is the same type of event as what a listener manager
     // handled last time.
     if (aEvent->message == sLatestEventType) {
       typeData = sLatestEventTypeData;
@@ -1186,18 +1152,21 @@ found:
     PRBool useGenericInterface =
       (!useTypeInterface && ListenerCanHandle(ls, aEvent));
     // Don't fire the listener if it's been removed.
     // Check that the phase is same in event and event listener.
     // Handle only trusted events, except when listener permits untrusted events.
     if (useTypeInterface || useGenericInterface) {
       if (ls->mListener) {
         hasListener = PR_TRUE;
-        if (ls->mFlags & aFlags &&
-            ls->mGroupFlags == currentGroup &&
+        // XXX The (mFlags & aFlags) test here seems fragile. Shouldn't we
+        // specifically only test the capture/bubble flags.
+        if ((ls->mFlags & aFlags & ~NS_EVENT_FLAG_SYSTEM_EVENT) &&
+            (ls->mFlags & NS_EVENT_FLAG_SYSTEM_EVENT) ==
+            (aFlags & NS_EVENT_FLAG_SYSTEM_EVENT) &&
             (NS_IS_TRUSTED_EVENT(aEvent) ||
              ls->mFlags & NS_PRIV_EVENT_UNTRUSTED_PERMITTED)) {
           if (!*aDOMEvent) {
             nsEventDispatcher::CreateEvent(aPresContext, aEvent,
                                            EmptyString(), aDOMEvent);
           }
           if (*aDOMEvent) {
             if (!aEvent->currentTarget) {
@@ -1240,25 +1209,16 @@ found:
 void
 nsEventListenerManager::Disconnect()
 {
   mTarget = nsnull;
   RemoveAllListeners();
 }
 
 nsresult
-nsEventListenerManager::GetSystemEventGroupLM(nsIDOMEventGroup **aGroup)
-{
-  *aGroup = GetSystemEventGroup();
-  NS_ENSURE_TRUE(*aGroup, NS_ERROR_OUT_OF_MEMORY);
-  NS_ADDREF(*aGroup);
-  return NS_OK;
-}
-
-nsresult
 nsEventListenerManager::GetDOM2EventGroup(nsIDOMEventGroup **aGroup)
 {
   if (!gDOM2EventGroup) {
     nsresult result;
     nsCOMPtr<nsIDOMEventGroup> group(do_CreateInstance(kDOMEventGroupCID,&result));
     if (NS_FAILED(result))
       return result;
 
@@ -1416,17 +1376,17 @@ nsEventListenerManager::GetListenerInfo(
 {
   nsCOMPtr<nsIDOMEventTarget> target = do_QueryInterface(mTarget);
   NS_ENSURE_STATE(target);
   aList->Clear();
   PRUint32 count = mListeners.Length();
   for (PRUint32 i = 0; i < count; ++i) {
     const nsListenerStruct& ls = mListeners.ElementAt(i);
     PRBool capturing = !!(ls.mFlags & NS_EVENT_FLAG_CAPTURE);
-    PRBool systemGroup = !!(ls.mGroupFlags & NS_EVENT_FLAG_SYSTEM_EVENT);
+    PRBool systemGroup = !!(ls.mFlags & NS_EVENT_FLAG_SYSTEM_EVENT);
     PRBool allowsUntrusted = !!(ls.mFlags & NS_PRIV_EVENT_UNTRUSTED_PERMITTED);
     // If this is a script handler and we haven't yet
     // compiled the event handler itself
     if ((ls.mFlags & NS_PRIV_EVENT_FLAG_SCRIPT) && ls.mHandlerIsString) {
       nsCOMPtr<nsIJSEventListener> jslistener = do_QueryInterface(ls.mListener);
       if (jslistener) {
         CompileEventHandlerInternal(jslistener->GetEventContext(),
                                     jslistener->GetEventScope(),
--- a/content/events/src/nsEventListenerManager.h
+++ b/content/events/src/nsEventListenerManager.h
@@ -62,17 +62,16 @@ class nsPIDOMWindow;
 class nsCxPusher;
 class nsIEventListenerInfo;
 
 typedef struct {
   nsRefPtr<nsIDOMEventListener> mListener;
   PRUint32                      mEventType;
   nsCOMPtr<nsIAtom>             mTypeAtom;
   PRUint16                      mFlags;
-  PRUint16                      mGroupFlags;
   PRBool                        mHandlerIsString;
   const EventTypeData*          mTypeData;
 } nsListenerStruct;
 
 /*
  * Event listener manager
  */
 
@@ -164,18 +163,16 @@ public:
                            nsIDOMEvent** aDOMEvent,
                            nsIDOMEventTarget* aCurrentTarget,
                            PRUint32 aFlags,
                            nsEventStatus* aEventStatus,
                            nsCxPusher* aPusher);
 
   void Disconnect();
 
-  nsresult GetSystemEventGroupLM(nsIDOMEventGroup **aGroup);
-
   PRBool HasMutationListeners();
 
   PRBool HasUnloadListeners();
 
   PRUint32 MutationListenerBits();
 
   PRBool HasListenersFor(const nsAString& aEventName);
 
@@ -185,18 +182,16 @@ public:
 
   PRUint32 GetIdentifierForEvent(nsIAtom* aEvent);
 
   // nsIDOM3EventTarget
   NS_DECL_NSIDOM3EVENTTARGET
 
   static void Shutdown();
 
-  static nsIDOMEventGroup* GetSystemEventGroup();
-
   /**
    * Returns PR_TRUE if there may be a paint event listener registered,
    * PR_FALSE if there definitely isn't.
    */
   PRBool MayHavePaintEventListener() { return mMayHavePaintEventListener; }
 
   /**
    * Returns PR_TRUE if there may be a MozAudioAvailable event listener registered,
--- a/content/events/src/nsEventListenerService.cpp
+++ b/content/events/src/nsEventListenerService.cpp
@@ -261,22 +261,52 @@ nsEventListenerService::HasListenersFor(
                                         PRBool* aRetVal)
 {
   nsEventListenerManager* elm = aEventTarget->GetListenerManager(PR_FALSE);
   *aRetVal = elm && elm->HasListenersFor(aType);
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsEventListenerService::GetSystemEventGroup(nsIDOMEventGroup** aSystemGroup)
+nsEventListenerService::AddSystemEventListener(nsIDOMEventTarget *aTarget,
+                                               const nsAString& aType,
+                                               nsIDOMEventListener* aListener,
+                                               PRBool aUseCapture)
 {
-  NS_ENSURE_ARG_POINTER(aSystemGroup);
-  *aSystemGroup = nsEventListenerManager::GetSystemEventGroup();
-  NS_ENSURE_TRUE(*aSystemGroup, NS_ERROR_OUT_OF_MEMORY);
-  NS_ADDREF(*aSystemGroup);
+  NS_PRECONDITION(aTarget, "Missing target");
+  NS_PRECONDITION(aListener, "Missing listener");
+
+  nsEventListenerManager* manager = aTarget->GetListenerManager(PR_TRUE);
+  NS_ENSURE_STATE(manager);
+
+  PRInt32 flags = aUseCapture ? NS_EVENT_FLAG_CAPTURE |
+                                NS_EVENT_FLAG_SYSTEM_EVENT :
+                                NS_EVENT_FLAG_BUBBLE |
+                                NS_EVENT_FLAG_SYSTEM_EVENT;
+  return manager->AddEventListenerByType(aListener, aType, flags, nsnull);
+}
+
+NS_IMETHODIMP
+nsEventListenerService::RemoveSystemEventListener(nsIDOMEventTarget *aTarget,
+                                                  const nsAString& aType,
+                                                  nsIDOMEventListener* aListener,
+                                                  PRBool aUseCapture)
+{
+  NS_PRECONDITION(aTarget, "Missing target");
+  NS_PRECONDITION(aListener, "Missing listener");
+
+  nsEventListenerManager* manager = aTarget->GetListenerManager(PR_FALSE);
+  if (manager) {
+    PRInt32 flags = aUseCapture ? NS_EVENT_FLAG_CAPTURE |
+                                  NS_EVENT_FLAG_SYSTEM_EVENT :
+                                  NS_EVENT_FLAG_BUBBLE |
+                                  NS_EVENT_FLAG_SYSTEM_EVENT;
+    manager->RemoveEventListenerByType(aListener, aType, flags, nsnull);
+  }
+
   return NS_OK;
 }
 
 nsresult
 NS_NewEventListenerService(nsIEventListenerService** aResult)
 {
   *aResult = new nsEventListenerService();
   NS_ENSURE_TRUE(*aResult, NS_ERROR_OUT_OF_MEMORY);
--- a/content/html/content/src/nsTextEditorState.cpp
+++ b/content/html/content/src/nsTextEditorState.cpp
@@ -59,16 +59,17 @@
 #include "nsINativeKeyBindings.h"
 #include "nsIDocumentEncoder.h"
 #include "nsISelectionPrivate.h"
 #include "nsPIDOMWindow.h"
 #include "nsServiceManagerUtils.h"
 #include "nsIDOMEventGroup.h"
 #include "nsIEditor.h"
 #include "nsTextEditRules.h"
+#include "nsEventListenerManager.h"
 
 #include "nsTextEditorState.h"
 
 using namespace mozilla::dom;
 
 static NS_DEFINE_CID(kTextEditorCID, NS_TEXTEDITOR_CID);
 
 static nsINativeKeyBindings *sNativeInputBindings = nsnull;
@@ -1508,31 +1509,39 @@ nsTextEditorState::UnbindFromFrame(nsTex
     mSelCon->SetScrollableFrame(nsnull);
     mSelCon = nsnull;
   }
 
   if (mTextListener)
   {
     mTextListener->SetFrame(nsnull);
 
-    nsCOMPtr<nsIDOMEventGroup> systemGroup;
-    nsCOMPtr<nsIContent> content = do_QueryInterface(mTextCtrlElement);
-    content->GetSystemEventGroup(getter_AddRefs(systemGroup));
-    nsCOMPtr<nsIDOM3EventTarget> dom3Targ = do_QueryInterface(mTextCtrlElement);
-    if (dom3Targ) {
+    nsCOMPtr<nsIDOMEventTarget> target = do_QueryInterface(mTextCtrlElement);
+    nsEventListenerManager* manager =
+      target->GetListenerManager(PR_FALSE);
+    if (manager) {
       // cast because of ambiguous base
       nsIDOMEventListener *listener = static_cast<nsIDOMKeyListener*>
                                                  (mTextListener);
 
-      dom3Targ->RemoveGroupedEventListener(NS_LITERAL_STRING("keydown"),
-                                           listener, PR_FALSE, systemGroup);
-      dom3Targ->RemoveGroupedEventListener(NS_LITERAL_STRING("keypress"),
-                                           listener, PR_FALSE, systemGroup);
-      dom3Targ->RemoveGroupedEventListener(NS_LITERAL_STRING("keyup"),
-                                           listener, PR_FALSE, systemGroup);
+      manager->RemoveEventListenerByType(listener,
+                                         NS_LITERAL_STRING("keydown"),
+                                         NS_EVENT_FLAG_BUBBLE |
+                                         NS_EVENT_FLAG_SYSTEM_EVENT,
+                                         nsnull);
+      manager->RemoveEventListenerByType(listener,
+                                         NS_LITERAL_STRING("keypress"),
+                                         NS_EVENT_FLAG_BUBBLE |
+                                         NS_EVENT_FLAG_SYSTEM_EVENT,
+                                         nsnull);
+      manager->RemoveEventListenerByType(listener,
+                                         NS_LITERAL_STRING("keyup"),
+                                         NS_EVENT_FLAG_BUBBLE |
+                                         NS_EVENT_FLAG_SYSTEM_EVENT,
+                                         nsnull);
     }
 
     NS_RELEASE(mTextListener);
     mTextListener = nsnull;
   }
 
   mBoundFrame = nsnull;
 
@@ -1932,33 +1941,36 @@ nsTextEditorState::SetValue(const nsAStr
   ValueWasChanged(!!mRootNode);
 
   mTextCtrlElement->OnValueChanged(!!mRootNode);
 }
 
 void
 nsTextEditorState::InitializeKeyboardEventListeners()
 {
-  nsCOMPtr<nsIContent> content = do_QueryInterface(mTextCtrlElement);
-
   //register key listeners
-  nsCOMPtr<nsIDOMEventGroup> systemGroup;
-  content->GetSystemEventGroup(getter_AddRefs(systemGroup));
-  nsCOMPtr<nsIDOM3EventTarget> dom3Targ = do_QueryInterface(content);
-  if (dom3Targ) {
+  nsCOMPtr<nsIDOMEventTarget> target = do_QueryInterface(mTextCtrlElement);
+  nsEventListenerManager* manager = target->GetListenerManager(PR_TRUE);
+  if (manager) {
     // cast because of ambiguous base
     nsIDOMEventListener *listener = static_cast<nsIDOMKeyListener*>
                                                (mTextListener);
 
-    dom3Targ->AddGroupedEventListener(NS_LITERAL_STRING("keydown"),
-                                      listener, PR_FALSE, systemGroup);
-    dom3Targ->AddGroupedEventListener(NS_LITERAL_STRING("keypress"),
-                                      listener, PR_FALSE, systemGroup);
-    dom3Targ->AddGroupedEventListener(NS_LITERAL_STRING("keyup"),
-                                      listener, PR_FALSE, systemGroup);
+    manager->AddEventListenerByType(listener, NS_LITERAL_STRING("keydown"),
+                                    NS_EVENT_FLAG_BUBBLE |
+                                    NS_EVENT_FLAG_SYSTEM_EVENT,
+                                    nsnull);
+    manager->AddEventListenerByType(listener, NS_LITERAL_STRING("keypress"),
+                                    NS_EVENT_FLAG_BUBBLE |
+                                    NS_EVENT_FLAG_SYSTEM_EVENT,
+                                    nsnull);
+    manager->AddEventListenerByType(listener, NS_LITERAL_STRING("keyup"),
+                                    NS_EVENT_FLAG_BUBBLE |
+                                    NS_EVENT_FLAG_SYSTEM_EVENT,
+                                    nsnull);
   }
 
   mSelCon->SetScrollableFrame(do_QueryFrame(mBoundFrame->GetFirstChild(nsnull)));
 }
 
 /* static */ void
 nsTextEditorState::ShutDown()
 {
--- a/content/smil/nsSMILTimeValueSpec.cpp
+++ b/content/smil/nsSMILTimeValueSpec.cpp
@@ -332,55 +332,50 @@ nsSMILTimeValueSpec::RegisterEventListen
 
   if (!aTarget)
     return;
 
   if (!mEventListener) {
     mEventListener = new EventListener(this);
   }
 
-  nsCOMPtr<nsIDOMEventGroup> sysGroup;
-  nsEventListenerManager* elm =
-    GetEventListenerManager(aTarget, getter_AddRefs(sysGroup));
+  nsEventListenerManager* elm = GetEventListenerManager(aTarget);
   if (!elm)
     return;
   
   elm->AddEventListenerByType(mEventListener,
                               nsDependentAtomString(mParams.mEventSymbol),
                               NS_EVENT_FLAG_BUBBLE |
-                              NS_PRIV_EVENT_UNTRUSTED_PERMITTED,
-                              sysGroup);
+                              NS_PRIV_EVENT_UNTRUSTED_PERMITTED |
+                              NS_EVENT_FLAG_SYSTEM_EVENT,
+                              nsnull);
 }
 
 void
 nsSMILTimeValueSpec::UnregisterEventListener(Element* aTarget)
 {
   if (!aTarget || !mEventListener)
     return;
 
-  nsCOMPtr<nsIDOMEventGroup> sysGroup;
-  nsEventListenerManager* elm =
-    GetEventListenerManager(aTarget, getter_AddRefs(sysGroup));
+  nsEventListenerManager* elm = GetEventListenerManager(aTarget);
   if (!elm)
     return;
 
   elm->RemoveEventListenerByType(mEventListener,
                                  nsDependentAtomString(mParams.mEventSymbol),
                                  NS_EVENT_FLAG_BUBBLE |
-                                 NS_PRIV_EVENT_UNTRUSTED_PERMITTED,
-                                 sysGroup);
+                                 NS_PRIV_EVENT_UNTRUSTED_PERMITTED |
+                                 NS_EVENT_FLAG_SYSTEM_EVENT,
+                                 nsnull);
 }
 
 nsEventListenerManager*
-nsSMILTimeValueSpec::GetEventListenerManager(Element* aTarget,
-                                             nsIDOMEventGroup** aSystemGroup)
+nsSMILTimeValueSpec::GetEventListenerManager(Element* aTarget)
 {
   NS_ABORT_IF_FALSE(aTarget, "null target; can't get EventListenerManager");
-  NS_ABORT_IF_FALSE(aSystemGroup && !*aSystemGroup,
-      "Bad out param for system group");
 
   nsCOMPtr<nsIDOMEventTarget> target;
 
   if (mParams.mType == nsSMILTimeValueSpecParams::ACCESSKEY) {
     nsIDocument* doc = aTarget->GetCurrentDoc();
     if (!doc)
       return nsnull;
     nsPIDOMWindow* win = doc->GetWindow();
@@ -388,25 +383,17 @@ nsSMILTimeValueSpec::GetEventListenerMan
       return nsnull;
     target = do_QueryInterface(win);
   } else {
     target = aTarget;
   }
   if (!target)
     return nsnull;
 
-  nsEventListenerManager* elm = target->GetListenerManager(PR_TRUE);
-  if (!elm)
-    return nsnull;
-
-  aTarget->GetSystemEventGroup(aSystemGroup);
-  if (!*aSystemGroup)
-    return nsnull;
-
-  return elm;
+  return target->GetListenerManager(PR_TRUE);
 }
 
 void
 nsSMILTimeValueSpec::HandleEvent(nsIDOMEvent* aEvent)
 {
   NS_ABORT_IF_FALSE(mEventListener, "Got event without an event listener");
   NS_ABORT_IF_FALSE(IsEventBased(),
                     "Got event for non-event nsSMILTimeValueSpec");
--- a/content/smil/nsSMILTimeValueSpec.h
+++ b/content/smil/nsSMILTimeValueSpec.h
@@ -90,18 +90,17 @@ public:
   void Unlink();
 
 protected:
   void UpdateReferencedElement(Element* aFrom, Element* aTo);
   void UnregisterFromReferencedElement(Element* aElement);
   nsSMILTimedElement* GetTimedElement(Element* aElement);
   void RegisterEventListener(Element* aElement);
   void UnregisterEventListener(Element* aElement);
-  nsEventListenerManager* GetEventListenerManager(Element* aElement,
-      nsIDOMEventGroup** aSystemGroup);
+  nsEventListenerManager* GetEventListenerManager(Element* aElement);
   void HandleEvent(nsIDOMEvent* aEvent);
   PRBool CheckEventDetail(nsIDOMEvent* aEvent);
   PRBool CheckRepeatEventDetail(nsIDOMEvent* aEvent);
   PRBool CheckAccessKeyEventDetail(nsIDOMEvent* aEvent);
   nsSMILTimeValue ConvertBetweenTimeContainers(const nsSMILTimeValue& aSrcTime,
                                       const nsSMILTimeContainer* aSrcContainer);
 
   nsSMILTimedElement*           mOwner;
--- a/content/xbl/src/nsXBLBinding.cpp
+++ b/content/xbl/src/nsXBLBinding.cpp
@@ -836,94 +836,83 @@ nsXBLBinding::InstallEventHandlers()
     nsXBLPrototypeHandler* handlerChain = mPrototypeBinding->GetPrototypeHandlers();
 
     if (handlerChain) {
       nsEventListenerManager* manager =
         mBoundElement->GetListenerManager(PR_TRUE);
       if (!manager)
         return;
 
-      nsCOMPtr<nsIDOMEventGroup> systemEventGroup;
       PRBool isChromeDoc =
         nsContentUtils::IsChromeDoc(mBoundElement->GetOwnerDoc());
       PRBool isChromeBinding = mPrototypeBinding->IsChrome();
       nsXBLPrototypeHandler* curr;
       for (curr = handlerChain; curr; curr = curr->GetNextHandler()) {
         // Fetch the event type.
         nsCOMPtr<nsIAtom> eventAtom = curr->GetEventName();
         if (!eventAtom ||
             eventAtom == nsGkAtoms::keyup ||
             eventAtom == nsGkAtoms::keydown ||
             eventAtom == nsGkAtoms::keypress)
           continue;
 
-        // If this is a command, add it in the system event group, otherwise 
-        // add it to the standard event group.
-
-        // This is a weak ref. systemEventGroup above is already a
-        // strong ref, so we are guaranteed it will not go away.
-        nsIDOMEventGroup* eventGroup = nsnull;
-        if ((curr->GetType() & (NS_HANDLER_TYPE_XBL_COMMAND | NS_HANDLER_TYPE_SYSTEM)) &&
-            (isChromeBinding || mBoundElement->IsInNativeAnonymousSubtree())) {
-          if (!systemEventGroup)
-            manager->GetSystemEventGroupLM(getter_AddRefs(systemEventGroup));
-          eventGroup = systemEventGroup;
-        }
-
         nsXBLEventHandler* handler = curr->GetEventHandler();
         if (handler) {
           // Figure out if we're using capturing or not.
           PRInt32 flags = (curr->GetPhase() == NS_PHASE_CAPTURING) ?
             NS_EVENT_FLAG_CAPTURE : NS_EVENT_FLAG_BUBBLE;
 
+          // If this is a command, add it in the system event group
+          if ((curr->GetType() & (NS_HANDLER_TYPE_XBL_COMMAND |
+                                  NS_HANDLER_TYPE_SYSTEM)) &&
+              (isChromeBinding || mBoundElement->IsInNativeAnonymousSubtree())) {
+            flags |= NS_EVENT_FLAG_SYSTEM_EVENT;
+          }
+
           PRBool hasAllowUntrustedAttr = curr->HasAllowUntrustedAttr();
           if ((hasAllowUntrustedAttr && curr->AllowUntrustedEvents()) ||
               (!hasAllowUntrustedAttr && !isChromeDoc)) {
             flags |= NS_PRIV_EVENT_UNTRUSTED_PERMITTED;
           }
 
           manager->AddEventListenerByType(handler,
                                           nsDependentAtomString(eventAtom),
-                                          flags, eventGroup);
+                                          flags, nsnull);
         }
       }
 
       const nsCOMArray<nsXBLKeyEventHandler>* keyHandlers =
         mPrototypeBinding->GetKeyEventHandlers();
       PRInt32 i;
       for (i = 0; i < keyHandlers->Count(); ++i) {
         nsXBLKeyEventHandler* handler = keyHandlers->ObjectAt(i);
         handler->SetIsBoundToChrome(isChromeDoc);
 
         nsAutoString type;
         handler->GetEventName(type);
 
         // If this is a command, add it in the system event group, otherwise 
         // add it to the standard event group.
 
-        // This is a weak ref. systemEventGroup above is already a
-        // strong ref, so we are guaranteed it will not go away.
-        nsIDOMEventGroup* eventGroup = nsnull;
-        if ((handler->GetType() & (NS_HANDLER_TYPE_XBL_COMMAND | NS_HANDLER_TYPE_SYSTEM)) &&
-            (isChromeBinding || mBoundElement->IsInNativeAnonymousSubtree())) {
-          if (!systemEventGroup)
-            manager->GetSystemEventGroupLM(getter_AddRefs(systemEventGroup));
-          eventGroup = systemEventGroup;
-        }
-
         // Figure out if we're using capturing or not.
         PRInt32 flags = (handler->GetPhase() == NS_PHASE_CAPTURING) ?
           NS_EVENT_FLAG_CAPTURE : NS_EVENT_FLAG_BUBBLE;
 
+        if ((handler->GetType() & (NS_HANDLER_TYPE_XBL_COMMAND |
+                                   NS_HANDLER_TYPE_SYSTEM)) &&
+            (isChromeBinding || mBoundElement->IsInNativeAnonymousSubtree())) {
+          flags |= NS_EVENT_FLAG_SYSTEM_EVENT;
+        }
+
         // For key handlers we have to set NS_PRIV_EVENT_UNTRUSTED_PERMITTED flag.
         // Whether the handling of the event is allowed or not is handled in
         // nsXBLKeyEventHandler::HandleEvent
         flags |= NS_PRIV_EVENT_UNTRUSTED_PERMITTED;
 
-        manager->AddEventListenerByType(handler, type, flags, eventGroup);
+        manager->AddEventListenerByType(handler, type, flags, nsnull);
       }
     }
   }
 
   if (mNextBinding)
     mNextBinding->InstallEventHandlers();
 }
 
@@ -998,17 +987,16 @@ nsXBLBinding::UnhookEventHandlers()
   if (handlerChain) {
     nsEventListenerManager* manager =
       mBoundElement->GetListenerManager(PR_FALSE);
     if (!manager) {
       return;
     }
                                       
     PRBool isChromeBinding = mPrototypeBinding->IsChrome();
-    nsCOMPtr<nsIDOMEventGroup> systemEventGroup;
     nsXBLPrototypeHandler* curr;
     for (curr = handlerChain; curr; curr = curr->GetNextHandler()) {
       nsXBLEventHandler* handler = curr->GetCachedEventHandler();
       if (!handler) {
         continue;
       }
       
       nsCOMPtr<nsIAtom> eventAtom = curr->GetEventName();
@@ -1020,29 +1008,25 @@ nsXBLBinding::UnhookEventHandlers()
 
       // Figure out if we're using capturing or not.
       PRInt32 flags = (curr->GetPhase() == NS_PHASE_CAPTURING) ?
         NS_EVENT_FLAG_CAPTURE : NS_EVENT_FLAG_BUBBLE;
 
       // If this is a command, remove it from the system event group,
       // otherwise remove it from the standard event group.
 
-      // This is a weak ref. systemEventGroup above is already a
-      // strong ref, so we are guaranteed it will not go away.
-      nsIDOMEventGroup* eventGroup = nsnull;
-      if ((curr->GetType() & (NS_HANDLER_TYPE_XBL_COMMAND | NS_HANDLER_TYPE_SYSTEM)) &&
+      if ((curr->GetType() & (NS_HANDLER_TYPE_XBL_COMMAND |
+                              NS_HANDLER_TYPE_SYSTEM)) &&
           (isChromeBinding || mBoundElement->IsInNativeAnonymousSubtree())) {
-        if (!systemEventGroup)
-          manager->GetSystemEventGroupLM(getter_AddRefs(systemEventGroup));
-        eventGroup = systemEventGroup;
+        flags |= NS_EVENT_FLAG_SYSTEM_EVENT;
       }
 
       manager->RemoveEventListenerByType(handler,
                                          nsDependentAtomString(eventAtom),
-                                         flags, eventGroup);
+                                         flags, nsnull);
     }
 
     const nsCOMArray<nsXBLKeyEventHandler>* keyHandlers =
       mPrototypeBinding->GetKeyEventHandlers();
     PRInt32 i;
     for (i = 0; i < keyHandlers->Count(); ++i) {
       nsXBLKeyEventHandler* handler = keyHandlers->ObjectAt(i);
 
@@ -1051,27 +1035,22 @@ nsXBLBinding::UnhookEventHandlers()
 
       // Figure out if we're using capturing or not.
       PRInt32 flags = (handler->GetPhase() == NS_PHASE_CAPTURING) ?
         NS_EVENT_FLAG_CAPTURE : NS_EVENT_FLAG_BUBBLE;
 
       // If this is a command, remove it from the system event group, otherwise 
       // remove it from the standard event group.
 
-      // This is a weak ref. systemEventGroup above is already a
-      // strong ref, so we are guaranteed it will not go away.
-      nsIDOMEventGroup* eventGroup = nsnull;
       if ((handler->GetType() & (NS_HANDLER_TYPE_XBL_COMMAND | NS_HANDLER_TYPE_SYSTEM)) &&
           (isChromeBinding || mBoundElement->IsInNativeAnonymousSubtree())) {
-        if (!systemEventGroup)
-          manager->GetSystemEventGroupLM(getter_AddRefs(systemEventGroup));
-        eventGroup = systemEventGroup;
+        flags |= NS_EVENT_FLAG_SYSTEM_EVENT;
       }
 
-      manager->RemoveEventListenerByType(handler, type, flags, eventGroup);
+      manager->RemoveEventListenerByType(handler, type, flags, nsnull);
     }
   }
 }
 
 void
 nsXBLBinding::ChangeDocument(nsIDocument* aOldDocument, nsIDocument* aNewDocument)
 {
   if (aOldDocument != aNewDocument) {
--- a/content/xbl/src/nsXBLService.cpp
+++ b/content/xbl/src/nsXBLService.cpp
@@ -714,45 +714,49 @@ nsXBLService::AttachGlobalKeyHandler(nsI
   // check if the receiver is a content node (not a document), and hook
   // it to the document if that is the case.
   nsCOMPtr<nsIDOMEventTarget> piTarget = aTarget;
   nsCOMPtr<nsIContent> contentNode(do_QueryInterface(aTarget));
   if (contentNode) {
     // Only attach if we're really in a document
     nsCOMPtr<nsIDocument> doc = contentNode->GetCurrentDoc();
     if (doc)
-      piTarget = do_QueryInterface(doc); // We're a XUL keyset. Attach to our document.
+      piTarget = doc; // We're a XUL keyset. Attach to our document.
   }
+
+  nsEventListenerManager* manager = piTarget->GetListenerManager(PR_TRUE);
     
-  if (!piTarget)
+  if (!piTarget || !manager)
     return NS_ERROR_FAILURE;
 
   // the listener already exists, so skip this
   if (contentNode && contentNode->GetProperty(nsGkAtoms::listener))
     return NS_OK;
     
   nsCOMPtr<nsIDOMElement> elt(do_QueryInterface(contentNode));
 
   // Create the key handler
   nsXBLWindowKeyHandler* handler;
   NS_NewXBLWindowKeyHandler(elt, piTarget, &handler); // This addRef's
   if (!handler)
     return NS_ERROR_FAILURE;
 
   // listen to these events
-  nsCOMPtr<nsIDOMEventGroup> systemGroup;
-  piTarget->GetSystemEventGroup(getter_AddRefs(systemGroup));
-  nsCOMPtr<nsIDOM3EventTarget> target = do_QueryInterface(piTarget);
-
-  target->AddGroupedEventListener(NS_LITERAL_STRING("keydown"), handler,
-                                  PR_FALSE, systemGroup);
-  target->AddGroupedEventListener(NS_LITERAL_STRING("keyup"), handler, 
-                                  PR_FALSE, systemGroup);
-  target->AddGroupedEventListener(NS_LITERAL_STRING("keypress"), handler, 
-                                  PR_FALSE, systemGroup);
+  manager->AddEventListenerByType(handler, NS_LITERAL_STRING("keydown"),
+                                  NS_EVENT_FLAG_BUBBLE |
+                                  NS_EVENT_FLAG_SYSTEM_EVENT,
+                                  nsnull);
+  manager->AddEventListenerByType(handler, NS_LITERAL_STRING("keyup"),
+                                  NS_EVENT_FLAG_BUBBLE |
+                                  NS_EVENT_FLAG_SYSTEM_EVENT,
+                                  nsnull);
+  manager->AddEventListenerByType(handler, NS_LITERAL_STRING("keypress"),
+                                  NS_EVENT_FLAG_BUBBLE |
+                                  NS_EVENT_FLAG_SYSTEM_EVENT,
+                                  nsnull);
 
   if (contentNode)
     return contentNode->SetProperty(nsGkAtoms::listener, handler,
                                     nsPropertyTable::SupportsDtorFunc, PR_TRUE);
 
   // release the handler. The reference will be maintained by the event target,
   // and, if there is a content node, the property.
   NS_RELEASE(handler);
@@ -771,34 +775,39 @@ nsXBLService::DetachGlobalKeyHandler(nsI
   nsCOMPtr<nsIContent> contentNode(do_QueryInterface(aTarget));
   if (!contentNode) // detaching is only supported for content nodes
     return NS_ERROR_FAILURE;
 
   // Only attach if we're really in a document
   nsCOMPtr<nsIDocument> doc = contentNode->GetCurrentDoc();
   if (doc)
     piTarget = do_QueryInterface(doc);
-  if (!piTarget)
+
+  nsEventListenerManager* manager = piTarget->GetListenerManager(PR_TRUE);
+    
+  if (!piTarget || !manager)
     return NS_ERROR_FAILURE;
 
   nsIDOMEventListener* handler =
     static_cast<nsIDOMEventListener*>(contentNode->GetProperty(nsGkAtoms::listener));
   if (!handler)
     return NS_ERROR_FAILURE;
 
-  nsCOMPtr<nsIDOMEventGroup> systemGroup;
-  piTarget->GetSystemEventGroup(getter_AddRefs(systemGroup));
-  nsCOMPtr<nsIDOM3EventTarget> target = do_QueryInterface(piTarget);
-
-  target->RemoveGroupedEventListener(NS_LITERAL_STRING("keydown"), handler,
-                                     PR_FALSE, systemGroup);
-  target->RemoveGroupedEventListener(NS_LITERAL_STRING("keyup"), handler, 
-                                     PR_FALSE, systemGroup);
-  target->RemoveGroupedEventListener(NS_LITERAL_STRING("keypress"), handler, 
-                                     PR_FALSE, systemGroup);
+  manager->RemoveEventListenerByType(handler, NS_LITERAL_STRING("keydown"),
+                                     NS_EVENT_FLAG_BUBBLE |
+                                     NS_EVENT_FLAG_SYSTEM_EVENT,
+                                     nsnull);
+  manager->RemoveEventListenerByType(handler, NS_LITERAL_STRING("keyup"),
+                                     NS_EVENT_FLAG_BUBBLE |
+                                     NS_EVENT_FLAG_SYSTEM_EVENT,
+                                     nsnull);
+  manager->RemoveEventListenerByType(handler, NS_LITERAL_STRING("keypress"),
+                                     NS_EVENT_FLAG_BUBBLE |
+                                     NS_EVENT_FLAG_SYSTEM_EVENT,
+                                     nsnull);
 
   contentNode->DeleteProperty(nsGkAtoms::listener);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsXBLService::Observe(nsISupports* aSubject, const char* aTopic, const PRUnichar* aSomeData)
--- a/content/xul/content/src/nsXULElement.cpp
+++ b/content/xul/content/src/nsXULElement.cpp
@@ -2182,29 +2182,29 @@ static void
 PopupListenerPropertyDtor(void* aObject, nsIAtom* aPropertyName,
                           void* aPropertyValue, void* aData)
 {
   nsIDOMEventListener* listener =
     static_cast<nsIDOMEventListener*>(aPropertyValue);
   if (!listener) {
     return;
   }
-  nsCOMPtr<nsIDOM3EventTarget> target =
-    do_QueryInterface(static_cast<nsINode*>(aObject));
-  if (target) {
-    nsCOMPtr<nsIDOMEventGroup> systemGroup;
-    static_cast<nsIDOMEventTarget*>(aObject)->
-      GetSystemEventGroup(getter_AddRefs(systemGroup));
-    if (systemGroup) {
-      target->RemoveGroupedEventListener(NS_LITERAL_STRING("mousedown"),
-                                         listener, PR_FALSE, systemGroup);
-
-      target->RemoveGroupedEventListener(NS_LITERAL_STRING("contextmenu"),
-                                         listener, PR_FALSE, systemGroup);
-    }
+  nsEventListenerManager* manager = static_cast<nsINode*>(aObject)->
+    GetListenerManager(PR_FALSE);
+  if (manager) {
+    manager->RemoveEventListenerByType(listener,
+                                       NS_LITERAL_STRING("mousedown"),
+                                       NS_EVENT_FLAG_BUBBLE |
+                                       NS_EVENT_FLAG_SYSTEM_EVENT,
+                                       nsnull);
+    manager->RemoveEventListenerByType(listener,
+                                       NS_LITERAL_STRING("contextmenu"),
+                                       NS_EVENT_FLAG_BUBBLE |
+                                       NS_EVENT_FLAG_SYSTEM_EVENT,
+                                       nsnull);
   }
   NS_RELEASE(listener);
 }
 
 nsresult
 nsXULElement::AddPopupListener(nsIAtom* aName)
 {
     // Add a popup listener to the element
@@ -2216,41 +2216,43 @@ nsXULElement::AddPopupListener(nsIAtom* 
 
     nsCOMPtr<nsIDOMEventListener> popupListener =
         static_cast<nsIDOMEventListener*>(GetProperty(listenerAtom));
     if (popupListener) {
         // Popup listener is already installed.
         return NS_OK;
     }
 
-    nsCOMPtr<nsIDOMEventGroup> systemGroup;
-    GetSystemEventGroup(getter_AddRefs(systemGroup));
-    NS_ENSURE_STATE(systemGroup);
-
     nsresult rv = NS_NewXULPopupListener(this, isContext,
                                          getter_AddRefs(popupListener));
     if (NS_FAILED(rv))
         return rv;
 
     // Add the popup as a listener on this element.
-    nsCOMPtr<nsIDOM3EventTarget> target(do_QueryInterface(static_cast<nsIContent *>(this)));
-    NS_ENSURE_TRUE(target, NS_ERROR_FAILURE);
+    nsEventListenerManager* manager = GetListenerManager(PR_TRUE);
+    NS_ENSURE_TRUE(manager, NS_ERROR_FAILURE);
     rv = SetProperty(listenerAtom, popupListener, PopupListenerPropertyDtor,
                      PR_TRUE);
     NS_ENSURE_SUCCESS(rv, rv);
     // Want the property to have a reference to the listener.
     nsIDOMEventListener* listener = nsnull;
     popupListener.swap(listener);
 
     if (isContext) {
-      target->AddGroupedEventListener(NS_LITERAL_STRING("contextmenu"),
-                                      listener, PR_FALSE, systemGroup);
+      manager->AddEventListenerByType(listener,
+                                      NS_LITERAL_STRING("contextmenu"),
+                                      NS_EVENT_FLAG_BUBBLE |
+                                      NS_EVENT_FLAG_SYSTEM_EVENT,
+                                      nsnull);
     } else {
-      target->AddGroupedEventListener(NS_LITERAL_STRING("mousedown"),
-                                      listener, PR_FALSE, systemGroup);
+      manager->AddEventListenerByType(listener,
+                                      NS_LITERAL_STRING("mousedown"),
+                                      NS_EVENT_FLAG_BUBBLE |
+                                      NS_EVENT_FLAG_SYSTEM_EVENT,
+                                      nsnull);
     }
     return NS_OK;
 }
 
 nsEventStates
 nsXULElement::IntrinsicState() const
 {
     nsEventStates state = nsStyledElement::IntrinsicState();
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -7360,24 +7360,16 @@ nsGlobalWindow::GetListenerManager(PRBoo
   if (!mListenerManager && aCreateIfNotFound) {
     mListenerManager =
       new nsEventListenerManager(static_cast<nsIDOMEventTarget*>(this));
   }
 
   return mListenerManager;
 }
 
-nsresult
-nsGlobalWindow::GetSystemEventGroup(nsIDOMEventGroup **aGroup)
-{
-  nsEventListenerManager* manager = GetListenerManager(PR_TRUE);
-  NS_ENSURE_STATE(manager);
-  return manager->GetSystemEventGroupLM(aGroup);
-}
-
 nsIScriptContext*
 nsGlobalWindow::GetContextForEventHandlers(nsresult* aRv)
 {
   nsIScriptContext* scx = GetContext();
   *aRv = scx ? NS_OK : NS_ERROR_UNEXPECTED;
   return scx;
 }
 
--- a/dom/base/nsWindowRoot.cpp
+++ b/dom/base/nsWindowRoot.cpp
@@ -212,24 +212,16 @@ nsWindowRoot::GetListenerManager(PRBool 
   if (!mListenerManager && aCreateIfNotFound) {
     mListenerManager =
       new nsEventListenerManager(static_cast<nsIDOMEventTarget*>(this));
   }
 
   return mListenerManager;
 }
 
-nsresult
-nsWindowRoot::GetSystemEventGroup(nsIDOMEventGroup **aGroup)
-{
-  nsEventListenerManager* manager = GetListenerManager(PR_TRUE);
-  NS_ENSURE_STATE(manager);
-  return manager->GetSystemEventGroupLM(aGroup);
-}
-
 nsIScriptContext*
 nsWindowRoot::GetContextForEventHandlers(nsresult* aRv)
 {
   *aRv = NS_OK;
   return nsnull;
 }
 
 nsresult
--- a/dom/interfaces/events/nsIDOMEventTarget.idl
+++ b/dom/interfaces/events/nsIDOMEventTarget.idl
@@ -255,21 +255,16 @@ interface nsIDOMEventTarget : nsISupport
   /**
    * Remove event listener for nsIID.
    */
   [noscript, nostdcall]
   void RemoveEventListenerByIID(in nsIDOMEventListener aListener,
                                 in nsIIDRef aIID);
 
   /**
-   * Get the system event group.
-   */
-  [noscript, nostdcall] nsIDOMEventGroup GetSystemEventGroup();
-
-  /**
    * Get the script context in which the event handlers should be run.
    * May return null.
    * @note Caller *must* check the value of aRv.
    */
   [notxpcom, nostdcall]
   nsIScriptContext GetContextForEventHandlers(out nsresult aRv);
 
   /**
--- a/dom/src/threads/nsDOMWorkerMessageHandler.cpp
+++ b/dom/src/threads/nsDOMWorkerMessageHandler.cpp
@@ -419,23 +419,16 @@ nsDOMWorkerMessageHandler::AddEventListe
 nsresult
 nsDOMWorkerMessageHandler::RemoveEventListenerByIID(nsIDOMEventListener *aListener,
                                                     const nsIID & aIID)
 {
   NS_ERROR("Should not be called");
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
-nsresult
-nsDOMWorkerMessageHandler::GetSystemEventGroup(nsIDOMEventGroup **_retval)
-{
-  NS_ERROR("Should not be called");
-  return NS_ERROR_NOT_IMPLEMENTED;
-}
-
 nsIScriptContext*
 nsDOMWorkerMessageHandler::GetContextForEventHandlers(nsresult *aRv)
 {
   NS_ERROR("Should not be called");
   *aRv = NS_ERROR_NOT_IMPLEMENTED;
   return nsnull;
 }
 
--- a/dom/src/threads/nsDOMWorkerMessageHandler.h
+++ b/dom/src/threads/nsDOMWorkerMessageHandler.h
@@ -163,14 +163,13 @@ private:
   virtual nsIDOMEventTarget * GetTargetForEventTargetChain(void) { return _to GetTargetForEventTargetChain(); } \
   virtual nsresult PreHandleEvent(nsEventChainPreVisitor & aVisitor) { return _to PreHandleEvent(aVisitor); } \
   virtual nsresult WillHandleEvent(nsEventChainPostVisitor & aVisitor) { return _to WillHandleEvent(aVisitor); } \
   virtual nsresult PostHandleEvent(nsEventChainPostVisitor & aVisitor) { return _to PostHandleEvent(aVisitor); } \
   virtual nsresult DispatchDOMEvent(nsEvent *aEvent, nsIDOMEvent *aDOMEvent, nsPresContext *aPresContext, nsEventStatus *aEventStatus) { return _to DispatchDOMEvent(aEvent, aDOMEvent, aPresContext, aEventStatus); } \
   virtual nsEventListenerManager * GetListenerManager(PRBool aMayCreate) { return _to GetListenerManager(aMayCreate); } \
   virtual nsresult AddEventListenerByIID(nsIDOMEventListener *aListener, const nsIID & aIID) { return _to AddEventListenerByIID(aListener, aIID); } \
   virtual nsresult RemoveEventListenerByIID(nsIDOMEventListener *aListener, const nsIID & aIID) { return _to RemoveEventListenerByIID(aListener, aIID); } \
-  virtual nsresult GetSystemEventGroup(nsIDOMEventGroup **_retval NS_OUTPARAM) { return _to GetSystemEventGroup(_retval); } \
   virtual nsIScriptContext * GetContextForEventHandlers(nsresult *aRv NS_OUTPARAM) { return _to GetContextForEventHandlers(aRv); } \
   virtual JSContext * GetJSContextForEventHandlers(void) { return _to GetJSContextForEventHandlers(); } 
 
 
 #endif /* __NSDOMWORKERMESSAGEHANDLER_H__ */
--- a/editor/libeditor/base/nsEditorEventListener.cpp
+++ b/editor/libeditor/base/nsEditorEventListener.cpp
@@ -125,51 +125,59 @@ nsEditorEventListener::InstallToEditor()
   NS_PRECONDITION(mEditor, "The caller must set mEditor");
 
   nsCOMPtr<nsIDOMEventTarget> piTarget = mEditor->GetDOMEventTarget();
   NS_ENSURE_TRUE(piTarget, NS_ERROR_FAILURE);
 
   nsresult rv;
 
   // register the event listeners with the listener manager
-  nsCOMPtr<nsIDOMEventGroup> sysGroup;
-  piTarget->GetSystemEventGroup(getter_AddRefs(sysGroup));
-  NS_ENSURE_STATE(sysGroup);
   nsEventListenerManager* elmP = piTarget->GetListenerManager(PR_TRUE);
   NS_ENSURE_STATE(elmP);
 
   nsCOMPtr<nsIDOMEventListener> listenerBase;
   CallQueryInterface(this, getter_AddRefs(listenerBase));
 
   rv = elmP->AddEventListenerByType(listenerBase,
                                     NS_LITERAL_STRING("keypress"),
                                     NS_EVENT_FLAG_BUBBLE |
-                                    NS_PRIV_EVENT_UNTRUSTED_PERMITTED,
-                                    sysGroup);
+                                    NS_PRIV_EVENT_UNTRUSTED_PERMITTED |
+                                    NS_EVENT_FLAG_SYSTEM_EVENT,
+                                    nsnull);
   NS_ENSURE_SUCCESS(rv, rv);
   // See bug 455215, we cannot use the standard dragstart event yet
   rv = elmP->AddEventListenerByType(listenerBase,
                                     NS_LITERAL_STRING("draggesture"),
-                                    NS_EVENT_FLAG_BUBBLE, sysGroup);
+                                    NS_EVENT_FLAG_BUBBLE |
+                                    NS_EVENT_FLAG_SYSTEM_EVENT,
+                                    nsnull);
   NS_ENSURE_SUCCESS(rv, rv);
   rv = elmP->AddEventListenerByType(listenerBase,
                                     NS_LITERAL_STRING("dragenter"),
-                                    NS_EVENT_FLAG_BUBBLE, sysGroup);
+                                    NS_EVENT_FLAG_BUBBLE |
+                                    NS_EVENT_FLAG_SYSTEM_EVENT,
+                                    nsnull);
   NS_ENSURE_SUCCESS(rv, rv);
   rv = elmP->AddEventListenerByType(listenerBase,
                                     NS_LITERAL_STRING("dragover"),
-                                    NS_EVENT_FLAG_BUBBLE, sysGroup);
+                                    NS_EVENT_FLAG_BUBBLE |
+                                    NS_EVENT_FLAG_SYSTEM_EVENT,
+                                    nsnull);
   NS_ENSURE_SUCCESS(rv, rv);
   rv = elmP->AddEventListenerByType(listenerBase,
                                     NS_LITERAL_STRING("dragexit"),
-                                    NS_EVENT_FLAG_BUBBLE, sysGroup);
+                                    NS_EVENT_FLAG_BUBBLE |
+                                    NS_EVENT_FLAG_SYSTEM_EVENT,
+                                    nsnull);
   NS_ENSURE_SUCCESS(rv, rv);
   rv = elmP->AddEventListenerByType(listenerBase,
                                     NS_LITERAL_STRING("drop"),
-                                    NS_EVENT_FLAG_BUBBLE, sysGroup);
+                                    NS_EVENT_FLAG_BUBBLE |
+                                    NS_EVENT_FLAG_SYSTEM_EVENT,
+                                    nsnull);
   NS_ENSURE_SUCCESS(rv, rv);
 
   rv = elmP->AddEventListenerByIID(listenerBase,
                                    NS_GET_IID(nsIDOMMouseListener),
                                    NS_EVENT_FLAG_CAPTURE);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Focus event doesn't bubble so adding the listener to capturing phase.
@@ -208,43 +216,50 @@ nsEditorEventListener::UninstallFromEdit
     return;
   }
 
   nsEventListenerManager* elmP =
     piTarget->GetListenerManager(PR_TRUE);
   if (!elmP) {
     return;
   }
-  nsCOMPtr<nsIDOMEventGroup> sysGroup;
-  piTarget->GetSystemEventGroup(getter_AddRefs(sysGroup));
-  if (!sysGroup) {
-    return;
-  }
 
   nsCOMPtr<nsIDOMEventListener> listenerBase;
   CallQueryInterface(this, getter_AddRefs(listenerBase));
 
   elmP->RemoveEventListenerByType(listenerBase,
                                   NS_LITERAL_STRING("keypress"),
-                                  NS_EVENT_FLAG_BUBBLE, sysGroup);
+                                  NS_EVENT_FLAG_BUBBLE |
+                                  NS_EVENT_FLAG_SYSTEM_EVENT,
+                                  nsnull);
   elmP->RemoveEventListenerByType(listenerBase,
                                   NS_LITERAL_STRING("draggesture"),
-                                  NS_EVENT_FLAG_BUBBLE, sysGroup);
+                                  NS_EVENT_FLAG_BUBBLE |
+                                  NS_EVENT_FLAG_SYSTEM_EVENT,
+                                  nsnull);
   elmP->RemoveEventListenerByType(listenerBase,
                                   NS_LITERAL_STRING("dragenter"),
-                                  NS_EVENT_FLAG_BUBBLE, sysGroup);
+                                  NS_EVENT_FLAG_BUBBLE |
+                                  NS_EVENT_FLAG_SYSTEM_EVENT,
+                                  nsnull);
   elmP->RemoveEventListenerByType(listenerBase,
                                   NS_LITERAL_STRING("dragover"),
-                                  NS_EVENT_FLAG_BUBBLE, sysGroup);
+                                  NS_EVENT_FLAG_BUBBLE |
+                                  NS_EVENT_FLAG_SYSTEM_EVENT,
+                                  nsnull);
   elmP->RemoveEventListenerByType(listenerBase,
                                   NS_LITERAL_STRING("dragexit"),
-                                  NS_EVENT_FLAG_BUBBLE, sysGroup);
+                                  NS_EVENT_FLAG_BUBBLE |
+                                  NS_EVENT_FLAG_SYSTEM_EVENT,
+                                  nsnull);
   elmP->RemoveEventListenerByType(listenerBase,
                                   NS_LITERAL_STRING("drop"),
-                                  NS_EVENT_FLAG_BUBBLE, sysGroup);
+                                  NS_EVENT_FLAG_BUBBLE |
+                                  NS_EVENT_FLAG_SYSTEM_EVENT,
+                                  nsnull);
 
   elmP->RemoveEventListenerByIID(listenerBase,
                                  NS_GET_IID(nsIDOMMouseListener),
                                  NS_EVENT_FLAG_CAPTURE);
 
   elmP->RemoveEventListenerByIID(listenerBase,
                                  NS_GET_IID(nsIDOMFocusListener),
                                  NS_EVENT_FLAG_CAPTURE);
--- a/editor/libeditor/html/tests/test_contenteditable_text_input_handling.html
+++ b/editor/libeditor/html/tests/test_contenteditable_text_input_handling.html
@@ -32,22 +32,19 @@ function runTests()
              getService(Components.interfaces.nsIFocusManager);
 
   var listener = {
     handleEvent: function _hv(aEvent)
     {
       aEvent.preventDefault(); // prevent the browser default behavior
     }
   };
-  var systemGroup =
-    Components.classes["@mozilla.org/eventlistenerservice;1"].
-      getService(Components.interfaces.nsIEventListenerService).
-      systemEventGroup;
-  window.QueryInterface(Components.interfaces.nsIDOM3EventTarget);
-  window.addGroupedEventListener("keypress", listener, false, systemGroup);
+  var els = Components.classes["@mozilla.org/eventlistenerservice;1"].
+    getService(Components.interfaces.nsIEventListenerService);
+  els.addSystemEventListener(window, "keypress", listener, false);
 
   var staticContent = document.getElementById("static");
   staticContent._defaultValue = getTextValue(staticContent);
   staticContent._isFocusable = false;
   staticContent._isEditable = false;
   staticContent._isContentEditable = false;
   staticContent._description = "non-editable p element";
   var inputInStatic = document.getElementById("inputInStatic");
@@ -319,17 +316,17 @@ function runTests()
   }
 
   testTextInput(inputInStatic);
   testTextInput(textareaInStatic);
   testTextInput(editor);
   testTextInput(inputInEditor);
   testTextInput(textareaInEditor);
 
-  window.removeGroupedEventListener("keypress", listener, false, systemGroup);
+  els.removeSystemEventListener(window, "keypress", listener, false);
 
   SimpleTest.finish();
 }
 
 </script>
 </body>
 
 </html>
--- a/editor/libeditor/html/tests/test_htmleditor_keyevent_handling.html
+++ b/editor/libeditor/html/tests/test_htmleditor_keyevent_handling.html
@@ -80,23 +80,18 @@ function runTests()
            " was consumed already, so, we cannot test the editor behavior actually");
       aPreventedOnBubbling = true;
     }
 
     is(bubblingPhase.prevented, aPreventedOnBubbling,
        getDesciption(aPreventedOnBubbling) + "prevented on bubbling phase");
   }
 
-  var systemGroup =
-    Components.classes["@mozilla.org/eventlistenerservice;1"].
-      getService(Components.interfaces.nsIEventListenerService).
-      systemEventGroup;
-  window.QueryInterface(Components.interfaces.nsIDOM3EventTarget);
-  window.addGroupedEventListener("keypress", listener, true, systemGroup);
-  window.addGroupedEventListener("keypress", listener, false, systemGroup);
+  SpecialPowers.addSystemEventListener(window, "keypress", listener, true);
+  SpecialPowers.addSystemEventListener(window, "keypress", listener, false);
 
   function doTest(aElement, aDescription,
                   aIsReadonly, aIsTabbable, aIsPlaintext)
   {
     function reset(aText)
     {
       capturingPhase.fired = false;
       capturingPhase.prevented = false;
@@ -655,18 +650,18 @@ function runTests()
 
   // readonly, plaintext and non-tabbable
   editor.flags = (flags | nsIPlaintextEditor.eEditorPlaintextMask |
                           nsIPlaintextEditor.eEditorReadonlyMask) &
                  ~(nsIPlaintextEditor.eEditorAllowInteraction);
   doTest(htmlEditor, "readonly and non-tabbable HTML editor but plaintext mode",
          true, false, true);
 
-  window.removeGroupedEventListener("keypress", listener, true, systemGroup);
-  window.removeGroupedEventListener("keypress", listener, false, systemGroup);
+  SpecialPowers.removeSystemEventListener(window, "keypress", listener, true);
+  SpecialPowers.removeSystemEventListener(window, "keypress", listener, false);
 
   SimpleTest.finish();
 }
 
 </script>
 </body>
 
 </html>
--- a/editor/libeditor/text/tests/test_bug569988.html
+++ b/editor/libeditor/text/tests/test_bug569988.html
@@ -55,34 +55,28 @@ function onPromptLoad(subject, topic, da
   gPromptInput.focus();
 }
 
 function onPromptFocus() {
   ok(true, "onPromptFocus is called");
   netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
   gPromptInput.removeEventListener("focus", onPromptFocus, false);
 
-  var systemGroup =
-    Components.classes["@mozilla.org/eventlistenerservice;1"].
-      getService(Components.interfaces.nsIEventListenerService).
-      systemEventGroup;
-  gPromptInput.QueryInterface(Components.interfaces.nsIDOM3EventTarget);
   var listener = {
     handleEvent: function _hv(aEvent)
     {
-      netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
       var isPrevented = aEvent.getPreventDefault();
       ok(!isPrevented, "ESC key event is prevented by editor");
-      gPromptInput.removeGroupedEventListener("keypress", listener, false,
-                                              systemGroup);
+      SpecialPowers.removeSystemEventListener(gPromptInput, "keypress",
+                                              listener, false);
       SimpleTest.finish();
     }
   };
-  gPromptInput.addGroupedEventListener("keypress", listener, false,
-                                       systemGroup);
+  SpecialPowers.addSystemEventListener(gPromptInput, "keypress", listener,
+                                       false);
   ok(true, "sending key");
   synthesizeKey("VK_ESCAPE", { }, gPromptInput.ownerDocument.defaultView);
 }
 
 </script>
 </pre>
 </body>
 </html>
--- a/editor/libeditor/text/tests/test_texteditor_keyevent_handling.html
+++ b/editor/libeditor/text/tests/test_texteditor_keyevent_handling.html
@@ -85,24 +85,21 @@ function runTests()
            " was consumed already, so, we cannot test the editor behavior actually");
       aPreventedOnBubbling = true;
     }
 
     is(bubblingPhase.prevented, aPreventedOnBubbling,
        getDesciption(aPreventedOnBubbling) + "prevented on bubbling phase");
   }
 
-  var systemGroup =
-    Components.classes["@mozilla.org/eventlistenerservice;1"].
-      getService(Components.interfaces.nsIEventListenerService).
-      systemEventGroup;
   var parentElement = document.getElementById("display");
-  parentElement.QueryInterface(Components.interfaces.nsIDOM3EventTarget);
-  parentElement.addGroupedEventListener("keypress", listener, true, systemGroup);
-  parentElement.addGroupedEventListener("keypress", listener, false, systemGroup);
+  SpecialPowers.addSystemEventListener(parentElement, "keypress", listener,
+                                       true);
+  SpecialPowers.addSystemEventListener(parentElement, "keypress", listener,
+                                       false);
 
   function doTest(aElement, aDescription, aIsSingleLine, aIsReadonly,
                   aIsTabbable)
   {
     function reset(aText)
     {
       capturingPhase.fired = false;
       capturingPhase.prevented = false;
@@ -402,18 +399,20 @@ function runTests()
                            nsIPlaintextEditor.eEditorAllowInteraction);
   doTest(textarea, "non-tabbable <textarea>", false, false, false);
 
   textarea.setAttribute("readonly", "readonly");
   doTest(textarea, "non-tabbable <textarea readonly>", false, true, false);
 
   editor.flags = flags;
 
-  parentElement.removeGroupedEventListener("keypress", listener, true, systemGroup);
-  parentElement.removeGroupedEventListener("keypress", listener, false, systemGroup);
+  SpecialPowers.removeSystemEventListener(parentElement, "keypress", listener,
+                                          true);
+  SpecialPowers.removeSystemEventListener(parentElement, "keypress", listener,
+                                          false);
 
   SimpleTest.finish();
 }
 
 </script>
 </body>
 
 </html>
--- a/embedding/browser/webBrowser/nsDocShellTreeOwner.cpp
+++ b/embedding/browser/webBrowser/nsDocShellTreeOwner.cpp
@@ -883,28 +883,28 @@ nsDocShellTreeOwner::AddChromeListeners(
         rv = NS_ERROR_OUT_OF_MEMORY;
     }
   }
 
   // register dragover and drop event listeners with the listener manager
   nsCOMPtr<nsIDOMEventTarget> target;
   GetDOMEventTarget(mWebBrowser, getter_AddRefs(target));
 
-  nsCOMPtr<nsIDOMEventGroup> sysGroup;
-  target->GetSystemEventGroup(getter_AddRefs(sysGroup));
   nsEventListenerManager* elmP = target->GetListenerManager(PR_TRUE);
-  if (sysGroup && elmP)
+  if (elmP)
   {
     rv = elmP->AddEventListenerByType(this, NS_LITERAL_STRING("dragover"),
-                                      NS_EVENT_FLAG_BUBBLE,
-                                      sysGroup);
+                                      NS_EVENT_FLAG_BUBBLE |
+                                      NS_EVENT_FLAG_SYSTEM_EVENT,
+                                      nsnull);
     NS_ENSURE_SUCCESS(rv, rv);
     rv = elmP->AddEventListenerByType(this, NS_LITERAL_STRING("drop"),
-                                      NS_EVENT_FLAG_BUBBLE,
-                                      sysGroup);
+                                      NS_EVENT_FLAG_BUBBLE |
+                                      NS_EVENT_FLAG_SYSTEM_EVENT,
+                                      nsnull);
   }
 
   return rv;
   
 } // AddChromeListeners
 
 
 NS_IMETHODIMP
@@ -919,27 +919,27 @@ nsDocShellTreeOwner::RemoveChromeListene
     NS_RELEASE(mChromeContextMenuListener);
   }
 
   nsCOMPtr<nsIDOMEventTarget> piTarget;
   GetDOMEventTarget(mWebBrowser, getter_AddRefs(piTarget));
   if (!piTarget)
     return NS_OK;
 
-  nsCOMPtr<nsIDOMEventGroup> sysGroup;
-  piTarget->GetSystemEventGroup(getter_AddRefs(sysGroup));
   nsEventListenerManager* elmP = piTarget->GetListenerManager(PR_TRUE);
-  if (sysGroup && elmP)
+  if (elmP)
   {
     elmP->RemoveEventListenerByType(this, NS_LITERAL_STRING("dragover"),
-                                    NS_EVENT_FLAG_BUBBLE,
-                                    sysGroup);
+                                    NS_EVENT_FLAG_BUBBLE |
+                                    NS_EVENT_FLAG_SYSTEM_EVENT,
+                                    nsnull);
     elmP->RemoveEventListenerByType(this, NS_LITERAL_STRING("drop"),
-                                    NS_EVENT_FLAG_BUBBLE,
-                                    sysGroup);
+                                    NS_EVENT_FLAG_BUBBLE |
+                                    NS_EVENT_FLAG_SYSTEM_EVENT,
+                                    nsnull);
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDocShellTreeOwner::HandleEvent(nsIDOMEvent* aEvent)
 {
--- a/layout/forms/nsFileControlFrame.cpp
+++ b/layout/forms/nsFileControlFrame.cpp
@@ -69,16 +69,17 @@
 #include "nsNodeInfoManager.h"
 #include "nsContentCreatorFunctions.h"
 #include "nsContentUtils.h"
 #include "nsDisplayList.h"
 #include "nsIDOMNSUIEvent.h"
 #include "nsIDOMEventGroup.h"
 #include "nsIDOM3EventTarget.h"
 #include "nsIDOMHTMLInputElement.h"
+#include "nsEventListenerManager.h"
 #ifdef ACCESSIBILITY
 #include "nsAccessibilityService.h"
 #endif
 
 #include "nsInterfaceHashtable.h"
 #include "nsURIHashKey.h"
 #include "nsILocalFile.h"
 #include "nsNetCID.h"
@@ -146,37 +147,33 @@ nsFileControlFrame::DestroyFrom(nsIFrame
                                     mMouseListener, PR_FALSE);
     dragTarget->RemoveEventListener(NS_LITERAL_STRING("dragover"),
                                     mMouseListener, PR_FALSE);
   }
 
   // remove mMouseListener as a mouse event listener (bug 40533, bug 355931)
   NS_NAMED_LITERAL_STRING(click, "click");
 
-  nsCOMPtr<nsIDOMEventGroup> systemGroup;
-  mContent->GetSystemEventGroup(getter_AddRefs(systemGroup));
-
-  nsCOMPtr<nsIDOM3EventTarget> dom3Capture = do_QueryInterface(mCapture);
-  if (dom3Capture) {
-    nsContentUtils::DestroyAnonymousContent(&mCapture);
-  }
+  nsContentUtils::DestroyAnonymousContent(&mCapture);
 
-  nsCOMPtr<nsIDOM3EventTarget> dom3Browse = do_QueryInterface(mBrowse);
-  if (dom3Browse) {
-    dom3Browse->RemoveGroupedEventListener(click, mMouseListener, PR_FALSE,
-                                           systemGroup);
-    nsContentUtils::DestroyAnonymousContent(&mBrowse);
+  nsEventListenerManager* elm = mBrowse->GetListenerManager(PR_FALSE);
+  if (elm) {
+    elm->RemoveEventListenerByType(mMouseListener, click,
+                                   NS_EVENT_FLAG_BUBBLE |
+                                   NS_EVENT_FLAG_SYSTEM_EVENT, nsnull);
   }
-  nsCOMPtr<nsIDOM3EventTarget> dom3TextContent =
-    do_QueryInterface(mTextContent);
-  if (dom3TextContent) {
-    dom3TextContent->RemoveGroupedEventListener(click, mMouseListener, PR_FALSE,
-                                                systemGroup);
-    nsContentUtils::DestroyAnonymousContent(&mTextContent);
+  nsContentUtils::DestroyAnonymousContent(&mBrowse);
+
+  elm = mTextContent->GetListenerManager(PR_FALSE);
+  if (elm) {
+    elm->RemoveEventListenerByType(mMouseListener, click,
+                                   NS_EVENT_FLAG_BUBBLE |
+                                   NS_EVENT_FLAG_SYSTEM_EVENT, nsnull);
   }
+  nsContentUtils::DestroyAnonymousContent(&mTextContent);
 
   mCaptureMouseListener->ForgetFrame();
   mMouseListener->ForgetFrame();
   nsBlockFrame::DestroyFrom(aDestructRoot);
 }
 
 struct CaptureCallbackData {
   nsICapturePicker* picker;
@@ -275,25 +272,24 @@ nsFileControlFrame::CreateAnonymousConte
   nsCOMPtr<nsIDOMEventTarget> dragTarget = do_QueryInterface(mContent);
   NS_ENSURE_STATE(dragTarget);
   dragTarget->AddEventListener(NS_LITERAL_STRING("drop"),
                                mMouseListener, PR_FALSE);
   dragTarget->AddEventListener(NS_LITERAL_STRING("dragover"),
                                mMouseListener, PR_FALSE);
 
   NS_NAMED_LITERAL_STRING(click, "click");
-  nsCOMPtr<nsIDOMEventGroup> systemGroup;
-  mContent->GetSystemEventGroup(getter_AddRefs(systemGroup));
-  nsCOMPtr<nsIDOM3EventTarget> dom3TextContent =
-    do_QueryInterface(mTextContent);
-  NS_ENSURE_STATE(dom3TextContent);
+  nsEventListenerManager* manager = mTextContent->GetListenerManager(PR_TRUE);
+  NS_ENSURE_STATE(manager);
   // Register as an event listener of the textbox
   // to open file dialog on mouse click
-  dom3TextContent->AddGroupedEventListener(click, mMouseListener, PR_FALSE,
-                                           systemGroup);
+  manager->AddEventListenerByType(mMouseListener, click,
+                                  NS_EVENT_FLAG_BUBBLE |
+                                  NS_EVENT_FLAG_SYSTEM_EVENT,
+                                  nsnull);
 
   // Create the browse button
   nodeInfo = doc->NodeInfoManager()->GetNodeInfo(nsGkAtoms::input, nsnull,
                                                  kNameSpaceID_XHTML,
                                                  nsIDOMNode::ELEMENT_NODE);
   NS_NewHTMLElement(getter_AddRefs(mBrowse), nodeInfo.forget(),
                     dom::NOT_FROM_PARSER);
   if (!mBrowse)
@@ -353,22 +349,26 @@ nsFileControlFrame::CreateAnonymousConte
   }
 
   if (!aElements.AppendElement(mBrowse))
     return NS_ERROR_OUT_OF_MEMORY;
 
   if (mCapture && !aElements.AppendElement(mCapture))
     return NS_ERROR_OUT_OF_MEMORY;
 
-  nsCOMPtr<nsIDOM3EventTarget> dom3Browse = do_QueryInterface(mBrowse);
-  NS_ENSURE_STATE(dom3Browse);
+  nsCOMPtr<nsIDOMEventTarget> target = do_QueryInterface(mBrowse);
+  NS_ENSURE_STATE(target);
+  manager = target->GetListenerManager(PR_TRUE);
+  NS_ENSURE_STATE(manager);
   // Register as an event listener of the button
   // to open file dialog on mouse click
-  dom3Browse->AddGroupedEventListener(click, mMouseListener, PR_FALSE,
-                                      systemGroup);
+  manager->AddEventListenerByType(mMouseListener, click,
+                                  NS_EVENT_FLAG_BUBBLE |
+                                  NS_EVENT_FLAG_SYSTEM_EVENT,
+                                  nsnull);
 
   SyncAttr(kNameSpaceID_None, nsGkAtoms::size,     SYNC_TEXT);
   SyncDisabledState();
 
   return NS_OK;
 }
 
 void
--- a/testing/mochitest/specialpowers/content/specialpowers.js
+++ b/testing/mochitest/specialpowers/content/specialpowers.js
@@ -285,16 +285,27 @@ SpecialPowers.prototype = {
 
   executeSoon: function(aFunc) {
     var tm = Cc["@mozilla.org/thread-manager;1"].getService(Ci.nsIThreadManager);
     tm.mainThread.dispatch({
       run: function() {
         aFunc();
       }
     }, Ci.nsIThread.DISPATCH_NORMAL);
+  },
+
+  addSystemEventListener: function(target, type, listener, useCapture) {
+    Components.classes["@mozilla.org/eventlistenerservice;1"].
+      getService(Components.interfaces.nsIEventListenerService).
+      addSystemEventListener(target, type, listener, useCapture);
+  },
+  removeSystemEventListener: function(target, type, listener, useCapture) {
+    Components.classes["@mozilla.org/eventlistenerservice;1"].
+      getService(Components.interfaces.nsIEventListenerService).
+      removeSystemEventListener(target, type, listener, useCapture);
   }
 };
 
 // Expose everything but internal APIs (starting with underscores) to
 // web content.
 SpecialPowers.prototype.__exposedProps__ = {};
 for each (i in Object.keys(SpecialPowers.prototype).filter(function(v) {return v.charAt(0) != "_";})) {
   SpecialPowers.prototype.__exposedProps__[i] = "r";