Bug 496567 - Remove nsXULCommandEvent and nsIDOMXULListener, r=neil, sr=sicking
authorOlli Pettay <Olli.Pettay@helsinki.fi>
Tue, 30 Jun 2009 10:56:40 +0300
changeset 29844 b1b2f9a366ca7ce267b50d3ecb912dca44b0de30
parent 29843 90cb997e99270c9b9e02cca758e6ec6715ef4632
child 29845 55f283b8e70bd4bd699a0fdae0b04d6f7a46c025
push idunknown
push userunknown
push dateunknown
reviewersneil, sicking
bugs496567
milestone1.9.2a1pre
Bug 496567 - Remove nsXULCommandEvent and nsIDOMXULListener, r=neil, sr=sicking
accessible/src/base/nsRootAccessible.h
content/base/public/nsContentUtils.h
content/base/src/nsContentUtils.cpp
content/events/public/nsIPrivateDOMEvent.h
content/events/src/nsDOMEvent.cpp
content/events/src/nsDOMXULCommandEvent.cpp
content/events/src/nsDOMXULCommandEvent.h
content/events/src/nsEventDispatcher.cpp
content/events/src/nsEventListenerManager.cpp
content/xbl/src/nsXBLBinding.cpp
content/xbl/src/nsXBLPrototypeHandler.cpp
content/xul/content/src/nsXULElement.cpp
dom/public/coreEvents/Makefile.in
dom/public/coreEvents/nsIDOMXULListener.h
layout/base/nsIPresShell.h
layout/base/nsPresShell.cpp
layout/xul/base/src/nsButtonBoxFrame.cpp
layout/xul/base/src/nsResizerFrame.cpp
layout/xul/base/src/nsTitleBarFrame.cpp
layout/xul/base/src/nsXULPopupManager.cpp
layout/xul/base/src/nsXULTooltipListener.cpp
layout/xul/base/src/nsXULTooltipListener.h
widget/public/nsGUIEvent.h
widget/src/cocoa/nsMenuItemX.mm
widget/src/cocoa/nsMenuUtilsX.h
widget/src/cocoa/nsMenuUtilsX.mm
--- a/accessible/src/base/nsRootAccessible.h
+++ b/accessible/src/base/nsRootAccessible.h
@@ -46,17 +46,16 @@
 #include "nsXULTreeAccessible.h"
 #endif
 
 #include "nsHashtable.h"
 #include "nsCaretAccessible.h"
 #include "nsIDocument.h"
 #include "nsIDOMFocusListener.h"
 #include "nsIDOMFormListener.h"
-#include "nsIDOMXULListener.h"
 #include "nsITimer.h"
 
 #define NS_ROOTACCESSIBLE_IMPL_CID                      \
 {  /* 7565f0d1-1465-4b71-906c-a623ac279f5d */           \
   0x7565f0d1,                                           \
   0x1465,                                               \
   0x4b71,                                               \
   { 0x90, 0x6c, 0xa6, 0x23, 0xac, 0x27, 0x9f, 0x5d }    \
--- a/content/base/public/nsContentUtils.h
+++ b/content/base/public/nsContentUtils.h
@@ -101,16 +101,17 @@ template<class E> class nsCOMArray;
 class nsIPref;
 struct JSRuntime;
 class nsICaseConversion;
 class nsIUGenCategory;
 class nsIWidget;
 class nsIDragSession;
 class nsPIDOMWindow;
 class nsPIDOMEventTarget;
+class nsIPresShell;
 #ifdef MOZ_XTF
 class nsIXTFService;
 #endif
 #ifdef IBMBIDI
 class nsIBidiKeyboard;
 #endif
 class nsIMIMEHeaderParam;
 
@@ -1397,16 +1398,31 @@ public:
   static nsresult GetASCIIOrigin(nsIPrincipal* aPrincipal,
                                  nsCString& aOrigin);
   static nsresult GetASCIIOrigin(nsIURI* aURI, nsCString& aOrigin);
   static nsresult GetUTFOrigin(nsIPrincipal* aPrincipal,
                                nsString& aOrigin);
   static nsresult GetUTFOrigin(nsIURI* aURI, nsString& aOrigin);
 
   /**
+   * This method creates and dispatches "command" event, which implements
+   * nsIDOMXULCommandEvent.
+   * If aShell is not null, dispatching goes via
+   * nsIPresShell::HandleDOMEventWithTarget.
+   */
+  static nsresult DispatchXULCommand(nsIContent* aTarget,
+                                     PRBool aTrusted,
+                                     nsIDOMEvent* aSourceEvent = nsnull,
+                                     nsIPresShell* aShell = nsnull,
+                                     PRBool aCtrl = PR_FALSE,
+                                     PRBool aAlt = PR_FALSE,
+                                     PRBool aShift = PR_FALSE,
+                                     PRBool aMeta = PR_FALSE);
+
+  /**
    * Gets the nsIDocument given the script context. Will return nsnull on failure.
    *
    * @param aScriptContext the script context to get the document for; can be null
    *
    * @return the document associated with the script context
    */
   static already_AddRefed<nsIDocument>
   GetDocumentFromScriptContext(nsIScriptContext *aScriptContext);
--- a/content/base/src/nsContentUtils.cpp
+++ b/content/base/src/nsContentUtils.cpp
@@ -157,16 +157,18 @@ static NS_DEFINE_CID(kXTFServiceCID, NS_
 #include "nsIUGenCategory.h"
 #include "nsIDragService.h"
 #include "nsIChannelEventSink.h"
 #include "nsIInterfaceRequestor.h"
 #include "nsIOfflineCacheUpdate.h"
 #include "nsCPrefetchService.h"
 #include "nsIChromeRegistry.h"
 #include "nsIMIMEHeaderParam.h"
+#include "nsIDOMXULCommandEvent.h"
+#include "nsIDOMAbstractView.h"
 #include "nsIDOMDragEvent.h"
 #include "nsDOMDataTransfer.h"
 #include "nsHtml5Module.h"
 
 #ifdef IBMBIDI
 #include "nsIBidiKeyboard.h"
 #endif
 #include "nsCycleCollectionParticipant.h"
@@ -5039,8 +5041,47 @@ nsContentUtils::CanAccessNativeAnon()
   if (fp && fp->script &&
       (filename = fp->script->filename) &&
       !strncmp(filename, prefix, NS_ARRAY_LENGTH(prefix) - 1)) {
     return PR_TRUE;
   }
 
   return PR_FALSE;
 }
+
+/* static */ nsresult
+nsContentUtils::DispatchXULCommand(nsIContent* aTarget,
+                                   PRBool aTrusted,
+                                   nsIDOMEvent* aSourceEvent,
+                                   nsIPresShell* aShell,
+                                   PRBool aCtrl,
+                                   PRBool aAlt,
+                                   PRBool aShift,
+                                   PRBool aMeta)
+{
+  NS_ENSURE_STATE(aTarget);
+  nsIDocument* doc = aTarget->GetOwnerDoc();
+  nsCOMPtr<nsIDOMDocumentEvent> docEvent = do_QueryInterface(doc);
+  NS_ENSURE_STATE(docEvent);
+  nsCOMPtr<nsIDOMEvent> event;
+  docEvent->CreateEvent(NS_LITERAL_STRING("xulcommandevent"),
+                        getter_AddRefs(event));
+  nsCOMPtr<nsIDOMXULCommandEvent> xulCommand = do_QueryInterface(event);
+  nsCOMPtr<nsIPrivateDOMEvent> pEvent = do_QueryInterface(xulCommand);
+  NS_ENSURE_STATE(pEvent);
+  nsCOMPtr<nsIDOMAbstractView> view = do_QueryInterface(doc->GetWindow());
+  nsresult rv = xulCommand->InitCommandEvent(NS_LITERAL_STRING("command"),
+                                             PR_TRUE, PR_TRUE, view,
+                                             0, aCtrl, aAlt, aShift, aMeta,
+                                             aSourceEvent);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  if (aShell) {
+    nsEventStatus status = nsEventStatus_eIgnore;
+    nsCOMPtr<nsIPresShell> kungFuDeathGrip = aShell;
+    return aShell->HandleDOMEventWithTarget(aTarget, event, &status);
+  }
+
+  nsCOMPtr<nsIDOMEventTarget> target = do_QueryInterface(aTarget);
+  NS_ENSURE_STATE(target);
+  PRBool dummy;
+  return target->DispatchEvent(event, &dummy);
+}
--- a/content/events/public/nsIPrivateDOMEvent.h
+++ b/content/events/public/nsIPrivateDOMEvent.h
@@ -95,17 +95,17 @@ nsresult
 NS_NewDOMPageTransitionEvent(nsIDOMEvent** aResult, nsPresContext* aPresContext, nsEvent* aEvent);
 #ifdef MOZ_SVG
 nsresult
 NS_NewDOMSVGEvent(nsIDOMEvent** aResult, nsPresContext* aPresContext, class nsEvent* aEvent);
 nsresult
 NS_NewDOMSVGZoomEvent(nsIDOMEvent** aResult, nsPresContext* aPresContext, class nsGUIEvent* aEvent);
 #endif // MOZ_SVG
 nsresult
-NS_NewDOMXULCommandEvent(nsIDOMEvent** aResult, nsPresContext* aPresContext, class nsXULCommandEvent* aEvent);
+NS_NewDOMXULCommandEvent(nsIDOMEvent** aResult, nsPresContext* aPresContext, class nsInputEvent* aEvent);
 nsresult
 NS_NewDOMCommandEvent(nsIDOMEvent** aInstancePtrResult, nsPresContext* aPresContext, nsCommandEvent* aEvent);
 nsresult
 NS_NewDOMMessageEvent(nsIDOMEvent** aInstancePtrResult, nsPresContext* aPresContext, class nsEvent* aEvent);
 nsresult
 NS_NewDOMProgressEvent(nsIDOMEvent** aInstancePtrResult, nsPresContext* aPresContext, class nsEvent* aEvent);
 nsresult
 NS_NewDOMNotifyPaintEvent(nsIDOMEvent** aResult, nsPresContext* aPresContext,
--- a/content/events/src/nsDOMEvent.cpp
+++ b/content/events/src/nsDOMEvent.cpp
@@ -179,19 +179,16 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(ns
       case NS_MOUSE_SCROLL_EVENT:
       case NS_SIMPLE_GESTURE_EVENT:
         static_cast<nsMouseEvent_base*>(tmp->mEvent)->relatedTarget = nsnull;
         break;
       case NS_DRAG_EVENT:
         static_cast<nsDragEvent*>(tmp->mEvent)->dataTransfer = nsnull;
         static_cast<nsMouseEvent_base*>(tmp->mEvent)->relatedTarget = nsnull;
         break;
-      case NS_XUL_COMMAND_EVENT:
-        static_cast<nsXULCommandEvent*>(tmp->mEvent)->sourceEvent = nsnull;
-        break;
       case NS_MUTATION_EVENT:
         static_cast<nsMutationEvent*>(tmp->mEvent)->mRelatedNode = nsnull;
         break;
       default:
         break;
     }
   }
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mPresContext);
@@ -215,21 +212,16 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(
       case NS_DRAG_EVENT:
         NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mEvent->dataTransfer");
         cb.NoteXPCOMChild(
           static_cast<nsDragEvent*>(tmp->mEvent)->dataTransfer);
         NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mEvent->relatedTarget");
         cb.NoteXPCOMChild(
           static_cast<nsMouseEvent_base*>(tmp->mEvent)->relatedTarget);
         break;
-      case NS_XUL_COMMAND_EVENT:
-        NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mEvent->sourceEvent");
-        cb.NoteXPCOMChild(
-          static_cast<nsXULCommandEvent*>(tmp->mEvent)->sourceEvent);
-        break;
       case NS_MUTATION_EVENT:
         NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mEvent->mRelatedNode");
         cb.NoteXPCOMChild(
           static_cast<nsMutationEvent*>(tmp->mEvent)->mRelatedNode);
         break;
       default:
         break;
     }
@@ -583,17 +575,17 @@ nsDOMEvent::SetEventType(const nsAString
     if (atom == nsGkAtoms::onDOMActivate)
       mEvent->message = NS_UI_ACTIVATE;
     else if (atom == nsGkAtoms::onDOMFocusIn)
       mEvent->message = NS_UI_FOCUSIN;
     else if (atom == nsGkAtoms::onDOMFocusOut)
       mEvent->message = NS_UI_FOCUSOUT;
     else if (atom == nsGkAtoms::oninput)
       mEvent->message = NS_FORM_INPUT;
-  } else if (mEvent->eventStructType == NS_XUL_COMMAND_EVENT) {
+  } else if (mEvent->eventStructType == NS_INPUT_EVENT) {
     if (atom == nsGkAtoms::oncommand)
       mEvent->message = NS_XUL_COMMAND;
   }
 #ifdef MOZ_SVG
   else if (mEvent->eventStructType == NS_SVG_EVENT) {
     if (atom == nsGkAtoms::onSVGLoad)
       mEvent->message = NS_SVG_LOAD;
     else if (atom == nsGkAtoms::onSVGUnload)
@@ -953,26 +945,16 @@ NS_METHOD nsDOMEvent::DuplicatePrivateDa
     case NS_SVGZOOM_EVENT:
     {
       newEvent = new nsGUIEvent(PR_FALSE, msg, nsnull);
       NS_ENSURE_TRUE(newEvent, NS_ERROR_OUT_OF_MEMORY);
       newEvent->eventStructType = NS_SVGZOOM_EVENT;
       break;
     }
 #endif // MOZ_SVG
-    case NS_XUL_COMMAND_EVENT:
-    {
-      newEvent = new nsXULCommandEvent(PR_FALSE, msg, nsnull);
-      NS_ENSURE_TRUE(newEvent, NS_ERROR_OUT_OF_MEMORY);
-      isInputEvent = PR_TRUE;
-      newEvent->eventStructType = NS_XUL_COMMAND_EVENT;
-       static_cast<nsXULCommandEvent*>(newEvent)->sourceEvent =
-         static_cast<nsXULCommandEvent*>(mEvent)->sourceEvent;
-      break;
-    }
     case NS_SIMPLE_GESTURE_EVENT:
     {
       nsSimpleGestureEvent* oldSimpleGestureEvent = static_cast<nsSimpleGestureEvent*>(mEvent);
       nsSimpleGestureEvent* simpleGestureEvent = 
         new nsSimpleGestureEvent(PR_FALSE, msg, nsnull, 0, 0.0);
       NS_ENSURE_TRUE(simpleGestureEvent, NS_ERROR_OUT_OF_MEMORY);
       isInputEvent = PR_TRUE;
       simpleGestureEvent->direction = oldSimpleGestureEvent->direction;
@@ -1125,16 +1107,19 @@ nsDOMEvent::GetEventPopupControlState(ns
     // while handling user input. See
     // nsPresShell::HandleEventInternal() for details.
     if (nsEventStateManager::IsHandlingUserInput()) {
       switch(aEvent->message) {
       case NS_FORM_CHANGE :
         if (::PopupAllowedForEvent("change"))
           abuse = openControlled;
         break;
+      case NS_XUL_COMMAND:
+        abuse = openControlled;
+        break;
       }
     }
     break;
   case NS_KEY_EVENT :
     if (NS_IS_TRUSTED_EVENT(aEvent)) {
       PRUint32 key = static_cast<nsKeyEvent *>(aEvent)->keyCode;
       switch(aEvent->message) {
       case NS_KEY_PRESS :
@@ -1206,20 +1191,16 @@ nsDOMEvent::GetEventPopupControlState(ns
         break;
       case NS_FORM_RESET :
         if (::PopupAllowedForEvent("reset"))
           abuse = openControlled;
         break;
       }
     }
     break;
-  case NS_XUL_COMMAND_EVENT :
-    if (nsEventStateManager::IsHandlingUserInput()) {
-      abuse = openControlled;
-    }
   }
 
   return abuse;
 }
 
 // static
 void
 nsDOMEvent::PopupAllowedEventsChanged()
--- a/content/events/src/nsDOMXULCommandEvent.cpp
+++ b/content/events/src/nsDOMXULCommandEvent.cpp
@@ -35,42 +35,45 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsDOMXULCommandEvent.h"
 #include "nsContentUtils.h"
 
 nsDOMXULCommandEvent::nsDOMXULCommandEvent(nsPresContext* aPresContext,
-                                           nsXULCommandEvent* aEvent)
+                                           nsInputEvent* aEvent)
   : nsDOMUIEvent(aPresContext,
-                 aEvent ? aEvent : new nsXULCommandEvent(PR_FALSE, 0, nsnull))
+                 aEvent ? aEvent : new nsInputEvent(PR_FALSE, 0, nsnull))
 {
   if (aEvent) {
     mEventIsInternal = PR_FALSE;
   }
   else {
     mEventIsInternal = PR_TRUE;
     mEvent->time = PR_Now();
   }
 }
 
-nsDOMXULCommandEvent::~nsDOMXULCommandEvent()
-{
-  if (mEventIsInternal) {
-    nsXULCommandEvent* command = static_cast<nsXULCommandEvent*>(mEvent);
-    delete command;
-    mEvent = nsnull;
-  }
-}
+NS_IMPL_CYCLE_COLLECTION_CLASS(nsDOMXULCommandEvent)
 
 NS_IMPL_ADDREF_INHERITED(nsDOMXULCommandEvent, nsDOMUIEvent)
 NS_IMPL_RELEASE_INHERITED(nsDOMXULCommandEvent, nsDOMUIEvent)
 
-NS_INTERFACE_MAP_BEGIN(nsDOMXULCommandEvent)
+NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsDOMXULCommandEvent,
+                                                nsDOMUIEvent)
+  NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mSourceEvent)
+NS_IMPL_CYCLE_COLLECTION_UNLINK_END
+
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsDOMXULCommandEvent,
+                                                  nsDOMUIEvent)
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mSourceEvent)
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
+
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsDOMXULCommandEvent)
   NS_INTERFACE_MAP_ENTRY(nsIDOMXULCommandEvent)
   NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(XULCommandEvent)
 NS_INTERFACE_MAP_END_INHERITING(nsDOMUIEvent)
 
 NS_IMETHODIMP
 nsDOMXULCommandEvent::GetAltKey(PRBool* aIsDown)
 {
   NS_ENSURE_ARG_POINTER(aIsDown);
@@ -101,47 +104,47 @@ nsDOMXULCommandEvent::GetMetaKey(PRBool*
   *aIsDown = Event()->isMeta;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMXULCommandEvent::GetSourceEvent(nsIDOMEvent** aSourceEvent)
 {
   NS_ENSURE_ARG_POINTER(aSourceEvent);
-  NS_IF_ADDREF(*aSourceEvent = Event()->sourceEvent);
+  NS_IF_ADDREF(*aSourceEvent = mSourceEvent);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMXULCommandEvent::InitCommandEvent(const nsAString& aType,
                                        PRBool aCanBubble, PRBool aCancelable,
                                        nsIDOMAbstractView *aView,
                                        PRInt32 aDetail,
                                        PRBool aCtrlKey, PRBool aAltKey,
                                        PRBool aShiftKey, PRBool aMetaKey,
                                        nsIDOMEvent* aSourceEvent)
 {
   nsresult rv = nsDOMUIEvent::InitUIEvent(aType, aCanBubble, aCancelable,
                                           aView, aDetail);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  nsXULCommandEvent *event = Event();
+  nsInputEvent *event = Event();
   event->isControl = aCtrlKey;
   event->isAlt = aAltKey;
   event->isShift = aShiftKey;
   event->isMeta = aMetaKey;
-  event->sourceEvent = aSourceEvent;
+  mSourceEvent = aSourceEvent;
 
   return NS_OK;
 }
 
 
 nsresult NS_NewDOMXULCommandEvent(nsIDOMEvent** aInstancePtrResult,
                                   nsPresContext* aPresContext,
-                                  nsXULCommandEvent *aEvent) 
+                                  nsInputEvent *aEvent) 
 {
   nsDOMXULCommandEvent* it = new nsDOMXULCommandEvent(aPresContext, aEvent);
   if (nsnull == it) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
   return CallQueryInterface(it, aInstancePtrResult);
 }
--- a/content/events/src/nsDOMXULCommandEvent.h
+++ b/content/events/src/nsDOMXULCommandEvent.h
@@ -43,25 +43,27 @@
 
 #include "nsDOMUIEvent.h"
 #include "nsIDOMXULCommandEvent.h"
 
 class nsDOMXULCommandEvent : public nsDOMUIEvent,
                              public nsIDOMXULCommandEvent
 {
 public:
-  nsDOMXULCommandEvent(nsPresContext* aPresContext, nsXULCommandEvent* aEvent);
-  virtual ~nsDOMXULCommandEvent();
+  nsDOMXULCommandEvent(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
 
-private:
+protected:
   // Convenience accessor for the event
-  nsXULCommandEvent* Event() {
-    return static_cast<nsXULCommandEvent*>(mEvent);
+  nsInputEvent* Event() {
+    return static_cast<nsInputEvent*>(mEvent);
   }
+
+  nsCOMPtr<nsIDOMEvent> mSourceEvent;
 };
 
 #endif  // nsDOMXULCommandEvent_h_
--- a/content/events/src/nsEventDispatcher.cpp
+++ b/content/events/src/nsEventDispatcher.cpp
@@ -645,20 +645,16 @@ nsEventDispatcher::CreateEvent(nsPresCon
     case NS_SVG_EVENT:
       return NS_NewDOMSVGEvent(aDOMEvent, aPresContext,
                                aEvent);
     case NS_SVGZOOM_EVENT:
       return NS_NewDOMSVGZoomEvent(aDOMEvent, aPresContext,
                                    static_cast<nsGUIEvent*>(aEvent));
 #endif // MOZ_SVG
 
-    case NS_XUL_COMMAND_EVENT:
-      return NS_NewDOMXULCommandEvent(aDOMEvent, aPresContext,
-                                      static_cast<nsXULCommandEvent*>
-                                                 (aEvent));
     case NS_COMMAND_EVENT:
       return NS_NewDOMCommandEvent(aDOMEvent, aPresContext,
                                    static_cast<nsCommandEvent*>(aEvent));
     case NS_SIMPLE_GESTURE_EVENT:
       return NS_NewDOMSimpleGestureEvent(aDOMEvent, aPresContext,
                                          static_cast<nsSimpleGestureEvent*>(aEvent));
     }
 
--- a/content/events/src/nsEventListenerManager.cpp
+++ b/content/events/src/nsEventListenerManager.cpp
@@ -46,17 +46,16 @@
 #include "nsIDOMMouseMotionListener.h"
 #include "nsIDOMContextMenuListener.h"
 #include "nsIDOMKeyListener.h"
 #include "nsIDOMFocusListener.h"
 #include "nsIDOMFormListener.h"
 #include "nsIDOMLoadListener.h"
 #include "nsIDOMTextListener.h"
 #include "nsIDOMCompositionListener.h"
-#include "nsIDOMXULListener.h"
 #include "nsIDOMUIListener.h"
 #include "nsITextControlFrame.h"
 #ifdef MOZ_SVG
 #include "nsGkAtoms.h"
 #endif // MOZ_SVG
 #include "nsIEventStateManager.h"
 #include "nsPIDOMWindow.h"
 #include "nsIPrivateDOMEvent.h"
@@ -239,27 +238,16 @@ static const EventDispatchData sFormEven
 
 static const EventDispatchData sLoadEvents[] = {
   { NS_LOAD,               HANDLER(&nsIDOMLoadListener::Load)         },
   { NS_PAGE_UNLOAD,        HANDLER(&nsIDOMLoadListener::Unload)       },
   { NS_LOAD_ERROR,         HANDLER(&nsIDOMLoadListener::Error)        },
   { NS_BEFORE_PAGE_UNLOAD, HANDLER(&nsIDOMLoadListener::BeforeUnload) }
 };
 
-static const EventDispatchData sXULEvents[] = {
-  { NS_XUL_POPUP_SHOWING,  HANDLER(&nsIDOMXULListener::PopupShowing)  },
-  { NS_XUL_POPUP_SHOWN,    HANDLER(&nsIDOMXULListener::PopupShown)    },
-  { NS_XUL_POPUP_HIDING,   HANDLER(&nsIDOMXULListener::PopupHiding)   },
-  { NS_XUL_POPUP_HIDDEN,   HANDLER(&nsIDOMXULListener::PopupHidden)   },
-  { NS_XUL_CLOSE,          HANDLER(&nsIDOMXULListener::Close)         },
-  { NS_XUL_COMMAND,        HANDLER(&nsIDOMXULListener::Command)       },
-  { NS_XUL_BROADCAST,      HANDLER(&nsIDOMXULListener::Broadcast)     },
-  { NS_XUL_COMMAND_UPDATE, HANDLER(&nsIDOMXULListener::CommandUpdate) }
-};
-
 static const EventDispatchData sUIEvents[] = {
   { NS_UI_ACTIVATE, HANDLER(&nsIDOMUIListener::Activate) },
   { NS_UI_FOCUSIN,  HANDLER(&nsIDOMUIListener::FocusIn)  },
   { NS_UI_FOCUSOUT, HANDLER(&nsIDOMUIListener::FocusOut) }
 };
 
 #define IMPL_EVENTTYPEDATA(type) \
 { \
@@ -275,17 +263,16 @@ static const EventTypeData sEventTypes[]
   IMPL_EVENTTYPEDATA(MouseMotion),
   IMPL_EVENTTYPEDATA(ContextMenu),
   IMPL_EVENTTYPEDATA(Key),
   IMPL_EVENTTYPEDATA(Load),
   IMPL_EVENTTYPEDATA(Focus),
   IMPL_EVENTTYPEDATA(Form),
   IMPL_EVENTTYPEDATA(Text),
   IMPL_EVENTTYPEDATA(Composition),
-  IMPL_EVENTTYPEDATA(XUL),
   IMPL_EVENTTYPEDATA(UI)
 };
 
 // Strong references to event groups
 nsIDOMEventGroup* gSystemEventGroup = nsnull;
 nsIDOMEventGroup* gDOM2EventGroup = nsnull;
 
 PRUint32 nsEventListenerManager::mInstanceCount = 0;
--- a/content/xbl/src/nsXBLBinding.cpp
+++ b/content/xbl/src/nsXBLBinding.cpp
@@ -74,17 +74,16 @@
 // Event listeners
 #include "nsIEventListenerManager.h"
 #include "nsIDOMMouseListener.h"
 #include "nsIDOMMouseMotionListener.h"
 #include "nsIDOMLoadListener.h"
 #include "nsIDOMFocusListener.h"
 #include "nsIDOMKeyListener.h"
 #include "nsIDOMFormListener.h"
-#include "nsIDOMXULListener.h"
 #include "nsIDOMContextMenuListener.h"
 #include "nsIDOMEventGroup.h"
 #include "nsAttrName.h"
 
 #include "nsGkAtoms.h"
 
 #include "nsIDOMAttr.h"
 #include "nsIDOMNamedNodeMap.h"
--- a/content/xbl/src/nsXBLPrototypeHandler.cpp
+++ b/content/xbl/src/nsXBLPrototypeHandler.cpp
@@ -523,41 +523,35 @@ nsXBLPrototypeHandler::DispatchXULKeyCom
                                   nsGkAtoms::_true,
                                   eCaseMatters)) {
     // Don't dispatch command events for disabled keys.
     return NS_OK;
   }
 
   aEvent->PreventDefault();
 
-  nsEventStatus status = nsEventStatus_eIgnore;
-  nsXULCommandEvent event(PR_TRUE, NS_XUL_COMMAND, nsnull);
-
   // Copy the modifiers from the key event.
   nsCOMPtr<nsIDOMKeyEvent> keyEvent = do_QueryInterface(aEvent);
   if (!keyEvent) {
     NS_ERROR("Trying to execute a key handler for a non-key event!");
     return NS_ERROR_FAILURE;
   }
 
-  keyEvent->GetAltKey(&event.isAlt);
-  keyEvent->GetCtrlKey(&event.isControl);
-  keyEvent->GetShiftKey(&event.isShift);
-  keyEvent->GetMetaKey(&event.isMeta);
+  PRBool isAlt = PR_FALSE;
+  PRBool isControl = PR_FALSE;
+  PRBool isShift = PR_FALSE;
+  PRBool isMeta = PR_FALSE;
+  keyEvent->GetAltKey(&isAlt);
+  keyEvent->GetCtrlKey(&isControl);
+  keyEvent->GetShiftKey(&isShift);
+  keyEvent->GetMetaKey(&isMeta);
 
-  nsPresContext *pc = nsnull;
-  nsIDocument *doc = handlerElement->GetCurrentDoc();
-  if (doc) {
-    nsIPresShell *shell = doc->GetPrimaryShell();
-    if (shell) {
-      pc = shell->GetPresContext();
-    }
-  }
-
-  nsEventDispatcher::Dispatch(handlerElement, pc, &event, nsnull, &status);
+  nsContentUtils::DispatchXULCommand(handlerElement, PR_TRUE,
+                                     nsnull, nsnull,
+                                     isControl, isAlt, isShift, isMeta);
   return NS_OK;
 }
 
 already_AddRefed<nsIAtom>
 nsXBLPrototypeHandler::GetEventName()
 {
   nsIAtom* eventName = mEventName;
   NS_IF_ADDREF(eventName);
--- a/content/xul/content/src/nsXULElement.cpp
+++ b/content/xul/content/src/nsXULElement.cpp
@@ -68,17 +68,16 @@
 #include "nsIDOMDocument.h"
 #include "nsIDOMElement.h"
 #include "nsIDOMMouseListener.h"
 #include "nsIDOMMouseMotionListener.h"
 #include "nsIDOMLoadListener.h"
 #include "nsIDOMFocusListener.h"
 #include "nsIDOMKeyListener.h"
 #include "nsIDOMFormListener.h"
-#include "nsIDOMXULListener.h"
 #include "nsIDOMContextMenuListener.h"
 #include "nsIDOMEventListener.h"
 #include "nsIDOMEventTarget.h"
 #include "nsIDOMNodeList.h"
 #include "nsIDOMXULCommandDispatcher.h"
 #include "nsIDOMXULElement.h"
 #include "nsIDOMElementCSSInlineStyle.h"
 #include "nsIDOMXULSelectCntrlItemEl.h"
@@ -1571,82 +1570,69 @@ nsXULElement::PreHandleEvent(nsEventChai
          aVisitor.mEvent->message == NS_XUL_COMMAND ||
          aVisitor.mEvent->message == NS_CONTEXTMENU)) {
         // Don't propagate these events from native anonymous scrollbar.
         aVisitor.mCanHandle = PR_TRUE;
         aVisitor.mParentTarget = nsnull;
         return NS_OK;
     }
     if (aVisitor.mEvent->message == NS_XUL_COMMAND &&
+        aVisitor.mEvent->eventStructType == NS_INPUT_EVENT &&
         aVisitor.mEvent->originalTarget == static_cast<nsIContent*>(this) &&
         tag != nsGkAtoms::command) {
+        // Check that we really have an xul command event. That will be handled
+        // in a special way.
+        nsCOMPtr<nsIDOMXULCommandEvent> xulEvent =
+            do_QueryInterface(aVisitor.mDOMEvent);
         // See if we have a command elt.  If so, we execute on the command
         // instead of on our content element.
         nsAutoString command;
-        GetAttr(kNameSpaceID_None, nsGkAtoms::command, command);
-        if (!command.IsEmpty()) {
+        if (xulEvent && GetAttr(kNameSpaceID_None, nsGkAtoms::command, command) &&
+            !command.IsEmpty()) {
             // Stop building the event target chain for the original event.
             // We don't want it to propagate to any DOM nodes.
             aVisitor.mCanHandle = PR_FALSE;
 
             // XXX sXBL/XBL2 issue! Owner or current document?
             nsCOMPtr<nsIDOMDocument> domDoc(do_QueryInterface(GetCurrentDoc()));
             NS_ENSURE_STATE(domDoc);
             nsCOMPtr<nsIDOMElement> commandElt;
             domDoc->GetElementById(command, getter_AddRefs(commandElt));
             nsCOMPtr<nsIContent> commandContent(do_QueryInterface(commandElt));
             if (commandContent) {
                 // Create a new command event to dispatch to the element
                 // pointed to by the command attribute.  The new event's
                 // sourceEvent will be the original command event that we're
                 // handling.
-
-                nsXULCommandEvent event(NS_IS_TRUSTED_EVENT(aVisitor.mEvent),
-                                        NS_XUL_COMMAND, nsnull);
-                if (aVisitor.mEvent->eventStructType == NS_XUL_COMMAND_EVENT) {
-                    nsXULCommandEvent *orig =
-                        static_cast<nsXULCommandEvent*>(aVisitor.mEvent);
-
-                    event.isShift = orig->isShift;
-                    event.isControl = orig->isControl;
-                    event.isAlt = orig->isAlt;
-                    event.isMeta = orig->isMeta;
-                } else {
-                    NS_WARNING("Incorrect eventStructType for command event");
-                }
-
-                if (!aVisitor.mDOMEvent) {
-                    // We need to create a new DOMEvent for the original event
-                    nsEventDispatcher::CreateEvent(aVisitor.mPresContext,
-                                                   aVisitor.mEvent,
-                                                   EmptyString(),
-                                                   &aVisitor.mDOMEvent);
-                }
-
                 nsCOMPtr<nsIDOMNSEvent> nsevent =
                     do_QueryInterface(aVisitor.mDOMEvent);
                 while (nsevent) {
                     nsCOMPtr<nsIDOMEventTarget> oTarget;
                     nsevent->GetOriginalTarget(getter_AddRefs(oTarget));
                     NS_ENSURE_STATE(!SameCOMIdentity(oTarget, commandContent));
                     nsCOMPtr<nsIDOMEvent> tmp;
                     nsCOMPtr<nsIDOMXULCommandEvent> commandEvent =
                         do_QueryInterface(nsevent);
                     if (commandEvent) {
                         commandEvent->GetSourceEvent(getter_AddRefs(tmp));
                     }
                     nsevent = do_QueryInterface(tmp);
                 }
 
-                event.sourceEvent = aVisitor.mDOMEvent;
-
-                nsEventStatus status = nsEventStatus_eIgnore;
-                nsEventDispatcher::Dispatch(commandContent,
-                                            aVisitor.mPresContext,
-                                            &event, nsnull, &status);
+                nsInputEvent* orig =
+                    static_cast<nsInputEvent*>(aVisitor.mEvent);
+                nsContentUtils::DispatchXULCommand(
+                  commandContent,
+                  NS_IS_TRUSTED_EVENT(aVisitor.mEvent),
+                  aVisitor.mDOMEvent,
+                  nsnull,
+                  orig->isControl,
+                  orig->isAlt,
+                  orig->isShift,
+                  orig->isMeta);
             } else {
                 NS_WARNING("A XUL element is attached to a command that doesn't exist!\n");
             }
             return NS_OK;
         }
     }
 
     return nsGenericElement::PreHandleEvent(aVisitor);
@@ -2127,25 +2113,17 @@ nsXULElement::Click()
     return DoCommand();
 }
 
 NS_IMETHODIMP
 nsXULElement::DoCommand()
 {
     nsCOMPtr<nsIDocument> doc = GetCurrentDoc(); // strong just in case
     if (doc) {
-        nsPresShellIterator iter(doc);
-        nsCOMPtr<nsIPresShell> shell;
-        while ((shell = iter.GetNextShell())) {
-            nsCOMPtr<nsPresContext> context = shell->GetPresContext();
-            nsEventStatus status = nsEventStatus_eIgnore;
-            nsXULCommandEvent event(PR_TRUE, NS_XUL_COMMAND, nsnull);
-            nsEventDispatcher::Dispatch(static_cast<nsIContent*>(this),
-                                        context, &event, nsnull, &status);
-        }
+        nsContentUtils::DispatchXULCommand(this, PR_TRUE);
     }
 
     return NS_OK;
 }
 
 nsIContent *
 nsXULElement::GetBindingParent() const
 {
--- a/dom/public/coreEvents/Makefile.in
+++ b/dom/public/coreEvents/Makefile.in
@@ -48,15 +48,14 @@ EXPORTS =				\
 	nsIDOMFocusListener.h		\
 	nsIDOMFormListener.h		\
 	nsIDOMKeyListener.h		\
 	nsIDOMLoadListener.h		\
 	nsIDOMMouseListener.h		\
 	nsIDOMMouseMotionListener.h	\
 	nsIDOMTextListener.h		\
 	nsIDOMCompositionListener.h	\
-	nsIDOMXULListener.h		\
 	nsIDOMContextMenuListener.h	\
 	nsIDOMUIListener.h		\
 	$(NULL)
 
 include $(topsrcdir)/config/rules.mk
 
deleted file mode 100644
--- a/dom/public/coreEvents/nsIDOMXULListener.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is mozilla.org code.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-
-#ifndef nsIDOMXULListener_h__
-#define nsIDOMXULListener_h__
-
-#include "nsIDOMEvent.h"
-#include "nsIDOMEventListener.h"
-
-// {0730C841-42F3-11d3-97FA-00400553EEF0}
-#define NS_IDOMXULLISTENER_IID \
-{ 0x730c841, 0x42f3, 0x11d3, { 0x97, 0xfa, 0x0, 0x40, 0x5, 0x53, 0xee, 0xf0 } }
-
-class nsIDOMXULListener : public nsIDOMEventListener {
-
-public:
-  NS_DECLARE_STATIC_IID_ACCESSOR(NS_IDOMXULLISTENER_IID)
-
-  NS_IMETHOD PopupShowing(nsIDOMEvent* aEvent) = 0;
-  NS_IMETHOD PopupShown(nsIDOMEvent* aEvent) = 0;
-  NS_IMETHOD PopupHiding(nsIDOMEvent* aEvent) = 0;
-  NS_IMETHOD PopupHidden(nsIDOMEvent* aEvent) = 0;
-
-  NS_IMETHOD Close(nsIDOMEvent* aEvent) = 0;
-  NS_IMETHOD Command(nsIDOMEvent* aEvent) = 0;
-  NS_IMETHOD Broadcast(nsIDOMEvent* aEvent) = 0;
-  NS_IMETHOD CommandUpdate(nsIDOMEvent* aEvent) = 0;
-};
-
-NS_DEFINE_STATIC_IID_ACCESSOR(nsIDOMXULListener, NS_IDOMXULLISTENER_IID)
-
-#endif // nsIDOMXULListener_h__
--- a/layout/base/nsIPresShell.h
+++ b/layout/base/nsIPresShell.h
@@ -92,24 +92,25 @@ class nsIStyleSheet;
 class nsCSSFrameConstructor;
 class nsISelection;
 template<class E> class nsCOMArray;
 class nsWeakFrame;
 class nsIScrollableFrame;
 class gfxASurface;
 class gfxContext;
 class nsPIDOMEventTarget;
+class nsIDOMEvent;
 
 typedef short SelectionType;
 typedef PRUint32 nsFrameState;
 
-// 41FE90F8-88DF-476E-A3B0-60916234F791
+// 189d234b-3823-4e8f-bbd2-63c0282b9fac
 #define NS_IPRESSHELL_IID \
-{ 0x41fe90f8, 0x88df, 0x476e, \
-  { 0xa3, 0xb0, 0x60, 0x91, 0x62, 0x34, 0xf7, 0x91 } }
+  { 0x189d234b, 0x3823, 0x4e8f, \
+    { 0xbb, 0xd2, 0x63, 0xc0, 0x28, 0x2b, 0x9f, 0xac } }
 
 // Constants for ScrollContentIntoView() function
 #define NS_PRESSHELL_SCROLL_TOP      0
 #define NS_PRESSHELL_SCROLL_BOTTOM   100
 #define NS_PRESSHELL_SCROLL_LEFT     0
 #define NS_PRESSHELL_SCROLL_RIGHT    100
 #define NS_PRESSHELL_SCROLL_CENTER   50
 #define NS_PRESSHELL_SCROLL_ANYWHERE -1
@@ -570,16 +571,24 @@ public:
    * Dispatch event to content only (NOT full processing)
    * @note The caller must have a strong reference to the PresShell.
    */
   NS_IMETHOD HandleDOMEventWithTarget(nsIContent* aTargetContent,
                                       nsEvent* aEvent,
                                       nsEventStatus* aStatus) = 0;
 
   /**
+   * Dispatch event to content only (NOT full processing)
+   * @note The caller must have a strong reference to the PresShell.
+   */
+  NS_IMETHOD HandleDOMEventWithTarget(nsIContent* aTargetContent,
+                                      nsIDOMEvent* aEvent,
+                                      nsEventStatus* aStatus) = 0;
+
+  /**
     * Gets the current target event frame from the PresShell
     */
   NS_IMETHOD GetEventTargetFrame(nsIFrame** aFrame) = 0;
 
   /**
     * Gets the current target event frame from the PresShell
     */
   NS_IMETHOD GetEventTargetContent(nsEvent* aEvent, nsIContent** aContent) = 0;
--- a/layout/base/nsPresShell.cpp
+++ b/layout/base/nsPresShell.cpp
@@ -914,16 +914,19 @@ public:
                                          const nsRect& aCopyRect,
                                          nsRegion*     aRepaintRegion);
   NS_IMETHOD HandleEvent(nsIView*        aView,
                          nsGUIEvent*     aEvent,
                          nsEventStatus*  aEventStatus);
   NS_IMETHOD HandleDOMEventWithTarget(nsIContent* aTargetContent,
                                       nsEvent* aEvent,
                                       nsEventStatus* aStatus);
+  NS_IMETHOD HandleDOMEventWithTarget(nsIContent* aTargetContent,
+                                      nsIDOMEvent* aEvent,
+                                      nsEventStatus* aStatus);
   NS_IMETHOD ResizeReflow(nsIView *aView, nscoord aWidth, nscoord aHeight);
   NS_IMETHOD_(PRBool) IsVisible();
   NS_IMETHOD_(void) WillPaint();
   NS_IMETHOD_(void) InvalidateFrameForView(nsIView *view);
   NS_IMETHOD_(void) DispatchSynthMouseMove(nsGUIEvent *aEvent,
                                            PRBool aFlushOnHoverChange);
 
   // caret handling
@@ -6376,16 +6379,33 @@ PresShell::HandleDOMEventWithTarget(nsIC
     nsEventDispatcher::Dispatch(aTargetContent, mPresContext, aEvent, nsnull,
                                 aStatus);
   }
 
   PopCurrentEventInfo();
   return NS_OK;
 }
 
+// See the method above.
+NS_IMETHODIMP
+PresShell::HandleDOMEventWithTarget(nsIContent* aTargetContent,
+                                    nsIDOMEvent* aEvent,
+                                    nsEventStatus* aStatus)
+{
+  PushCurrentEventInfo(nsnull, aTargetContent);
+  nsCOMPtr<nsISupports> container = mPresContext->GetContainer();
+  if (container) {
+    nsEventDispatcher::DispatchDOMEvent(aTargetContent, nsnull, aEvent,
+                                        mPresContext, aStatus);
+  }
+
+  PopCurrentEventInfo();
+  return NS_OK;
+}
+
 PRBool
 PresShell::AdjustContextMenuKeyEvent(nsMouseEvent* aEvent)
 {
 #ifdef MOZ_XUL
   // if a menu is open, open the context menu relative to the active item on the menu.
   // XXXndeakin Mac doesn't fire mouse-triggered context menus while another
   // menu is open. Maybe we should prevent keyboard-tiggered context menu events too. 
   nsXULPopupManager* pm = nsXULPopupManager::GetInstance();
--- a/layout/xul/base/src/nsButtonBoxFrame.cpp
+++ b/layout/xul/base/src/nsButtonBoxFrame.cpp
@@ -46,16 +46,17 @@
 #include "nsGkAtoms.h"
 #include "nsINameSpaceManager.h"
 #include "nsPresContext.h"
 #include "nsIPresShell.h"
 #include "nsGUIEvent.h"
 #include "nsIEventStateManager.h"
 #include "nsIDOMElement.h"
 #include "nsDisplayList.h"
+#include "nsContentUtils.h"
 
 //
 // NS_NewXULButtonFrame
 //
 // Creates a new Button frame and returns it
 //
 nsIFrame*
 NS_NewButtonBoxFrame (nsIPresShell* aPresShell, nsStyleContext* aContext)
@@ -144,24 +145,29 @@ void
 nsButtonBoxFrame::DoMouseClick(nsGUIEvent* aEvent, PRBool aTrustEvent) 
 {
   // Don't execute if we're disabled.
   if (mContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::disabled,
                             nsGkAtoms::_true, eCaseMatters))
     return;
 
   // Execute the oncommand event handler.
-  nsEventStatus status = nsEventStatus_eIgnore;
-  nsXULCommandEvent event(aEvent ? NS_IS_TRUSTED_EVENT(aEvent) : aTrustEvent,
-                          NS_XUL_COMMAND, nsnull);
+  PRBool isShift = PR_FALSE;
+  PRBool isControl = PR_FALSE;
+  PRBool isAlt = PR_FALSE;
+  PRBool isMeta = PR_FALSE;
   if(aEvent) {
-    event.isShift = ((nsInputEvent*)(aEvent))->isShift;
-    event.isControl = ((nsInputEvent*)(aEvent))->isControl;
-    event.isAlt = ((nsInputEvent*)(aEvent))->isAlt;
-    event.isMeta = ((nsInputEvent*)(aEvent))->isMeta;
+    isShift = ((nsInputEvent*)(aEvent))->isShift;
+    isControl = ((nsInputEvent*)(aEvent))->isControl;
+    isAlt = ((nsInputEvent*)(aEvent))->isAlt;
+    isMeta = ((nsInputEvent*)(aEvent))->isMeta;
   }
 
   // Have the content handle the event, propagating it according to normal DOM rules.
   nsCOMPtr<nsIPresShell> shell = PresContext()->GetPresShell();
   if (shell) {
-    shell->HandleDOMEventWithTarget(mContent, &event, &status);
+    nsContentUtils::DispatchXULCommand(mContent,
+                                       aEvent ?
+                                         NS_IS_TRUSTED_EVENT(aEvent) : aTrustEvent,
+                                       nsnull, shell,
+                                       isControl, isAlt, isShift, isMeta);
   }
 }
--- a/layout/xul/base/src/nsResizerFrame.cpp
+++ b/layout/xul/base/src/nsResizerFrame.cpp
@@ -48,16 +48,17 @@
 #include "nsPresContext.h"
 #include "nsIDocShell.h"
 #include "nsIDocShellTreeItem.h"
 #include "nsIDocShellTreeOwner.h"
 #include "nsIBaseWindow.h"
 #include "nsPIDOMWindow.h"
 #include "nsGUIEvent.h"
 #include "nsEventDispatcher.h"
+#include "nsContentUtils.h"
 
 //
 // NS_NewResizerFrame
 //
 // Creates a new Resizer frame and returns it
 //
 nsIFrame*
 NS_NewResizerFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
@@ -254,15 +255,12 @@ nsResizerFrame::GetDirection()
   }
   return directions[index];
 }
 
 void
 nsResizerFrame::MouseClicked(nsPresContext* aPresContext, nsGUIEvent *aEvent)
 {
   // Execute the oncommand event handler.
-  nsEventStatus status = nsEventStatus_eIgnore;
-
-  nsXULCommandEvent event(aEvent ? NS_IS_TRUSTED_EVENT(aEvent) : PR_FALSE,
-                          NS_XUL_COMMAND, nsnull);
-
-  nsEventDispatcher::Dispatch(mContent, aPresContext, &event, nsnull, &status);
+  nsContentUtils::DispatchXULCommand(mContent,
+                                     aEvent ?
+                                       NS_IS_TRUSTED_EVENT(aEvent) : PR_FALSE);
 }
--- a/layout/xul/base/src/nsTitleBarFrame.cpp
+++ b/layout/xul/base/src/nsTitleBarFrame.cpp
@@ -47,16 +47,17 @@
 #include "nsMenuPopupFrame.h"
 #include "nsPresContext.h"
 #include "nsIDocShellTreeItem.h"
 #include "nsPIDOMWindow.h"
 #include "nsIViewManager.h"
 #include "nsGUIEvent.h"
 #include "nsEventDispatcher.h"
 #include "nsDisplayList.h"
+#include "nsContentUtils.h"
 
 //
 // NS_NewTitleBarFrame
 //
 // Creates a new TitleBar frame and returns it
 //
 nsIFrame*
 NS_NewTitleBarFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
@@ -237,15 +238,12 @@ nsTitleBarFrame::CaptureMouseEvents(nsPr
 }
 
 
 
 void
 nsTitleBarFrame::MouseClicked(nsPresContext* aPresContext, nsGUIEvent* aEvent)
 {
   // Execute the oncommand event handler.
-  nsEventStatus status = nsEventStatus_eIgnore;
-
-  nsXULCommandEvent event(aEvent ? NS_IS_TRUSTED_EVENT(aEvent) : PR_FALSE,
-                          NS_XUL_COMMAND, nsnull);
-
-  nsEventDispatcher::Dispatch(mContent, aPresContext, &event, nsnull, &status);
+  nsContentUtils::DispatchXULCommand(mContent,
+                                     aEvent ?
+                                       NS_IS_TRUSTED_EVENT(aEvent) : PR_FALSE);
 }
--- a/layout/xul/base/src/nsXULPopupManager.cpp
+++ b/layout/xul/base/src/nsXULPopupManager.cpp
@@ -2086,24 +2086,18 @@ nsXULMenuCommandEvent::Run()
     nsCOMPtr<nsIPresShell> shell = presContext->PresShell();
     nsCOMPtr<nsIViewManager> kungFuDeathGrip = shell->GetViewManager();
 
     // Deselect ourselves.
     if (mCloseMenuMode != CloseMenuMode_None)
       menuFrame->SelectMenu(PR_FALSE);
 
     nsAutoHandlingUserInputStatePusher userInpStatePusher(mUserInput);
-
-    nsEventStatus status = nsEventStatus_eIgnore;
-    nsXULCommandEvent commandEvent(mIsTrusted, NS_XUL_COMMAND, nsnull);
-    commandEvent.isShift = mShift;
-    commandEvent.isControl = mControl;
-    commandEvent.isAlt = mAlt;
-    commandEvent.isMeta = mMeta;
-    shell->HandleDOMEventWithTarget(mMenu, &commandEvent, &status);
+    nsContentUtils::DispatchXULCommand(mMenu, mIsTrusted, nsnull, shell,
+                                       mControl, mAlt, mShift, mMeta);
   }
 
   if (popup && mCloseMenuMode != CloseMenuMode_None)
     pm->HidePopup(popup, mCloseMenuMode == CloseMenuMode_Auto, PR_TRUE, PR_FALSE);
 
   return NS_OK;
 }
 
--- a/layout/xul/base/src/nsXULTooltipListener.cpp
+++ b/layout/xul/base/src/nsXULTooltipListener.cpp
@@ -102,17 +102,16 @@ nsXULTooltipListener::~nsXULTooltipListe
                                            ToolbarTipsPrefChanged, nsnull);
   }
 }
 
 NS_INTERFACE_MAP_BEGIN(nsXULTooltipListener)
   NS_INTERFACE_MAP_ENTRY(nsIDOMMouseListener)
   NS_INTERFACE_MAP_ENTRY(nsIDOMMouseMotionListener)
   NS_INTERFACE_MAP_ENTRY(nsIDOMKeyListener)
-  NS_INTERFACE_MAP_ENTRY(nsIDOMXULListener)
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsIDOMEventListener, nsIDOMMouseListener)
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMMouseMotionListener)
 NS_INTERFACE_MAP_END
 
 NS_IMPL_ADDREF(nsXULTooltipListener)
 NS_IMPL_RELEASE(nsXULTooltipListener)
 
 //////////////////////////////////////////////////////////////////////////
@@ -307,16 +306,19 @@ nsXULTooltipListener::KeyDown(nsIDOMEven
 
 NS_IMETHODIMP
 nsXULTooltipListener::HandleEvent(nsIDOMEvent* aEvent)
 {
   nsAutoString type;
   aEvent->GetType(type);
   if (type.EqualsLiteral("DOMMouseScroll") || type.EqualsLiteral("dragstart"))
     HideTooltip();
+  else if (type.EqualsLiteral("popuphiding"))
+    DestroyTooltip();
+
   return NS_OK;
 }
 
 //////////////////////////////////////////////////////////////////////////
 //// nsXULTooltipListener
 
 // static
 int
@@ -324,23 +326,16 @@ nsXULTooltipListener::ToolbarTipsPrefCha
                                              void *aClosure)
 {
   sShowTooltips = nsContentUtils::GetBoolPref("browser.chrome.toolbar_tips",
                                               sShowTooltips);
 
   return 0;
 }
 
-NS_IMETHODIMP
-nsXULTooltipListener::PopupHiding(nsIDOMEvent* aEvent)
-{
-  DestroyTooltip();
-  return NS_OK;
-}
-
 //////////////////////////////////////////////////////////////////////////
 //// nsXULTooltipListener
 
 PRBool nsXULTooltipListener::sShowTooltips = PR_FALSE;
 PRUint32 nsXULTooltipListener::sTooltipListenerCount = 0;
 
 nsresult
 nsXULTooltipListener::AddTooltipSupport(nsIContent* aNode)
--- a/layout/xul/base/src/nsXULTooltipListener.h
+++ b/layout/xul/base/src/nsXULTooltipListener.h
@@ -37,32 +37,30 @@
 
 #ifndef nsXULTooltipListener_h__
 #define nsXULTooltipListener_h__
 
 #include "nsIDOMMouseListener.h"
 #include "nsIDOMMouseMotionListener.h"
 #include "nsIDOMKeyListener.h"
 #include "nsIDOMMouseEvent.h"
-#include "nsIDOMXULListener.h"
 #include "nsIContent.h"
 #include "nsIDOMElement.h"
 #include "nsITimer.h"
 #include "nsCOMPtr.h"
 #include "nsString.h"
 #ifdef MOZ_XUL
 #include "nsITreeBoxObject.h"
 #include "nsITreeColumns.h"
 #endif
 #include "nsWeakPtr.h"
 
 class nsXULTooltipListener : public nsIDOMMouseListener,
                              public nsIDOMMouseMotionListener,
-                             public nsIDOMKeyListener,
-                             public nsIDOMXULListener
+                             public nsIDOMKeyListener
 {
 public:
   NS_DECL_ISUPPORTS
 
   // nsIDOMMouseListener
   NS_IMETHOD MouseDown(nsIDOMEvent* aMouseEvent);
   NS_IMETHOD MouseUp(nsIDOMEvent* aMouseEvent);
   NS_IMETHOD MouseClick(nsIDOMEvent* aMouseEvent) { return NS_OK; }
@@ -74,26 +72,16 @@ public:
   NS_IMETHOD DragMove(nsIDOMEvent* aMouseEvent) { return NS_OK; }
   NS_IMETHOD MouseMove(nsIDOMEvent* aMouseEvent);
 
   // nsIDOMKeyListener
   NS_IMETHOD KeyDown(nsIDOMEvent* aKeyEvent);
   NS_IMETHOD KeyUp(nsIDOMEvent* aKeyEvent) { return NS_OK; }
   NS_IMETHOD KeyPress(nsIDOMEvent* aKeyEvent) { return NS_OK; }
 
-  // nsIDOMXULListener
-  NS_IMETHOD PopupShowing(nsIDOMEvent* aEvent) { return NS_OK; }
-  NS_IMETHOD PopupShown(nsIDOMEvent* aEvent) { return NS_OK; }
-  NS_IMETHOD PopupHiding(nsIDOMEvent* aEvent);
-  NS_IMETHOD PopupHidden(nsIDOMEvent* aEvent) { return NS_OK; }
-  NS_IMETHOD Close(nsIDOMEvent* aEvent) { return NS_OK; }
-  NS_IMETHOD Command(nsIDOMEvent* aEvent) { return NS_OK; }
-  NS_IMETHOD Broadcast(nsIDOMEvent* aEvent) { return NS_OK; }
-  NS_IMETHOD CommandUpdate(nsIDOMEvent* aEvent) { return NS_OK; }
-
   // nsIDOMEventListener
   NS_IMETHOD HandleEvent(nsIDOMEvent* aEvent);
 
   nsresult AddTooltipSupport(nsIContent* aNode);
   nsresult RemoveTooltipSupport(nsIContent* aNode);
   static nsXULTooltipListener* GetInstance() {
     if (!mInstance)
       mInstance = new nsXULTooltipListener();
--- a/widget/public/nsGUIEvent.h
+++ b/widget/public/nsGUIEvent.h
@@ -57,17 +57,16 @@
 #include "nsITransferable.h"
 
 class nsIRenderingContext;
 class nsIRegion;
 class nsIMenuItem;
 class nsIAccessible;
 class nsIContent;
 class nsIURI;
-class nsIDOMEvent;
 class nsHashKey;
 
 /**
  * Event Struct Types
  */
 #define NS_EVENT                           1
 #define NS_GUI_EVENT                       2
 #define NS_SIZE_EVENT                      3
@@ -91,17 +90,17 @@ class nsHashKey;
 #define NS_COMMAND_EVENT                  24
 
 
 #define NS_UI_EVENT                       27
 #ifdef MOZ_SVG
 #define NS_SVG_EVENT                      30
 #define NS_SVGZOOM_EVENT                  31
 #endif // MOZ_SVG
-#define NS_XUL_COMMAND_EVENT              32
+
 #define NS_QUERY_CONTENT_EVENT            33
 #ifdef MOZ_MEDIA
 #define NS_MEDIA_EVENT                    34
 #endif // MOZ_MEDIA
 #define NS_DRAG_EVENT                     35
 #define NS_NOTIFYPAINT_EVENT              36
 #define NS_SIMPLE_GESTURE_EVENT           37
 #define NS_SELECTION_EVENT                38
@@ -1204,30 +1203,16 @@ public:
       detail(d)
   {
   }
 
   PRInt32 detail;
 };
 
 /**
- * XUL command event
- */
-class nsXULCommandEvent : public nsInputEvent
-{
-public:
-  nsXULCommandEvent(PRBool isTrusted, PRUint32 msg, nsIWidget *w)
-    : nsInputEvent(isTrusted, msg, w, NS_XUL_COMMAND_EVENT)
-  {
-  }
-
-  nsCOMPtr<nsIDOMEvent> sourceEvent;
-};
-
-/**
  * Simple gesture event
  */
 class nsSimpleGestureEvent : public nsMouseEvent_base
 {
 public:
   nsSimpleGestureEvent(PRBool isTrusted, PRUint32 msg, nsIWidget* w,
                          PRUint32 directionArg, PRFloat64 deltaArg)
     : nsMouseEvent_base(isTrusted, msg, w, NS_SIMPLE_GESTURE_EVENT),
--- a/widget/src/cocoa/nsMenuItemX.mm
+++ b/widget/src/cocoa/nsMenuItemX.mm
@@ -213,20 +213,17 @@ void nsMenuItemX::DoCommand()
   if (mType == eCheckboxMenuItemType ||
       (mType == eRadioMenuItemType && !mIsChecked)) {
     if (!mContent->AttrValueIs(kNameSpaceID_None, nsWidgetAtoms::autocheck,
                                nsWidgetAtoms::_false, eCaseMatters))
     SetChecked(!mIsChecked);
     /* the AttributeChanged code will update all the internal state */
   }
 
-  nsEventStatus status = nsEventStatus_eIgnore;
-  nsXULCommandEvent event(PR_TRUE, NS_XUL_COMMAND, nsnull);
-
-  mContent->DispatchDOMEvent(&event, nsnull, nsnull, &status);
+  nsMenuUtilsX::DispatchCommandTo(mContent);
 }
     
 
 nsresult nsMenuItemX::DispatchDOMEvent(const nsString &eventName, PRBool *preventDefaultCalled)
 {
   if (!mContent)
     return NS_ERROR_FAILURE;
 
--- a/widget/src/cocoa/nsMenuUtilsX.h
+++ b/widget/src/cocoa/nsMenuUtilsX.h
@@ -50,17 +50,17 @@ class nsIContent;
 class nsString;
 class nsMenuBarX;
 
 extern "C" MenuRef _NSGetCarbonMenu(NSMenu* aMenu);
 
 // Namespace containing utility functions used in our native menu implementation.
 namespace nsMenuUtilsX
 {
-  nsEventStatus DispatchCommandTo(nsIContent* aTargetContent);
+  void          DispatchCommandTo(nsIContent* aTargetContent);
   NSString*     GetTruncatedCocoaLabel(const nsString& itemLabel);
   PRUint8       GeckoModifiersForNodeAttribute(const nsString& modifiersAttribute);
   unsigned int  MacModifiersForGeckoModifiers(PRUint8 geckoModifiers);
   nsMenuBarX*   GetHiddenWindowMenuBar(); // returned object is not retained
   NSMenuItem*   GetStandardEditMenuItem(); // returned object is not retained
   PRBool        NodeIsHiddenOrCollapsed(nsIContent* inContent);
   int           CalculateNativeInsertionPoint(nsMenuObjectX* aParent, nsMenuObjectX* aChild);
 }
--- a/widget/src/cocoa/nsMenuUtilsX.mm
+++ b/widget/src/cocoa/nsMenuUtilsX.mm
@@ -39,29 +39,51 @@
 #include "nsMenuUtilsX.h"
 #include "nsMenuBarX.h"
 #include "nsMenuX.h"
 #include "nsMenuItemX.h"
 #include "nsObjCExceptions.h"
 #include "nsCocoaUtils.h"
 #include "nsCocoaWindow.h"
 #include "nsWidgetAtoms.h"
+#include "nsIDocument.h"
+#include "nsIDOMDocumentEvent.h"
+#include "nsIDOMEventTarget.h"
+#include "nsIDOMXULCommandEvent.h"
+#include "nsIPrivateDOMEvent.h"
+#include "nsPIDOMWindow.h"
+#include "nsIDOMAbstractView.h"
 
-nsEventStatus nsMenuUtilsX::DispatchCommandTo(nsIContent* aTargetContent)
+void nsMenuUtilsX::DispatchCommandTo(nsIContent* aTargetContent)
 {
   NS_PRECONDITION(aTargetContent, "null ptr");
 
-  nsEventStatus status = nsEventStatus_eConsumeNoDefault;
-  nsXULCommandEvent event(PR_TRUE, NS_XUL_COMMAND, nsnull);
+  nsIDocument* doc = aTargetContent->GetOwnerDoc();
+  nsCOMPtr<nsIDOMDocumentEvent> docEvent = do_QueryInterface(doc);
+  nsCOMPtr<nsIDOMEventTarget> target = do_QueryInterface(aTargetContent);
+  if (docEvent && target) {
+    nsCOMPtr<nsIDOMEvent> event;
+    docEvent->CreateEvent(NS_LITERAL_STRING("xulcommandevent"),
+                          getter_AddRefs(event));
+    nsCOMPtr<nsIDOMXULCommandEvent> command = do_QueryInterface(event);
+    nsCOMPtr<nsIPrivateDOMEvent> pEvent = do_QueryInterface(command);
+    nsCOMPtr<nsIDOMAbstractView> view = do_QueryInterface(doc->GetWindow());
 
-  // FIXME: Should probably figure out how to init this with the actual
-  // pressed keys, but this is a big old edge case anyway. -dwh
-
-  aTargetContent->DispatchDOMEvent(&event, nsnull, nsnull, &status);
-  return status;
+    // FIXME: Should probably figure out how to init this with the actual
+    // pressed keys, but this is a big old edge case anyway. -dwh
+    if (pEvent &&
+        NS_SUCCEEDED(command->InitCommandEvent(NS_LITERAL_STRING("command"),
+                                               PR_TRUE, PR_TRUE, view, 0,
+                                               PR_FALSE, PR_FALSE, PR_FALSE,
+                                               PR_FALSE, nsnull))) {
+      pEvent->SetTrusted(PR_TRUE);
+      PRBool dummy;
+      target->DispatchEvent(event, &dummy);
+    }
+  }
 }
 
 
 NSString* nsMenuUtilsX::GetTruncatedCocoaLabel(const nsString& itemLabel)
 {
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
 
 #ifdef __LP64__