diff --git a/dom/base/nsContentUtils.cpp b/dom/base/nsContentUtils.cpp index da3207e9c9..624f9c502f 100644 --- a/dom/base/nsContentUtils.cpp +++ b/dom/base/nsContentUtils.cpp @@ -738,20 +738,40 @@ nsContentUtils::InitializeModifierStrings() sModifierSeparator = new nsString(modifierSeparator); } +mozilla::EventClassID +nsContentUtils::GetEventClassIDFromMessage(EventMessage aEventMessage) +{ + switch (aEventMessage) { +#define MESSAGE_TO_EVENT(name_, message_, type_, struct_) \ + case message_: return struct_; +#include "mozilla/EventNameList.h" +#undef MESSAGE_TO_EVENT + default: + MOZ_ASSERT_UNREACHABLE("Invalid event message?"); + return eBasicEventClass; + } +} + +static nsIAtom* +GetEventTypeFromMessage(EventMessage aEventMessage) +{ + switch (aEventMessage) { +#define MESSAGE_TO_EVENT(name_, message_, type_, struct_) \ + case message_: return nsGkAtoms::on##name_; +#include "mozilla/EventNameList.h" +#undef MESSAGE_TO_EVENT + default: + return nullptr; + } +} + // Because of SVG/SMIL we have several atoms mapped to the same // id, but we can rely on MESSAGE_TO_EVENT to map id to only one atom. static bool ShouldAddEventToStringEventTable(const EventNameMapping& aMapping) { - switch(aMapping.mMessage) { -#define MESSAGE_TO_EVENT(name_, message_, type_, struct_) \ - case message_: return nsGkAtoms::on##name_ == aMapping.mAtom; -#include "mozilla/EventNameList.h" -#undef MESSAGE_TO_EVENT - default: - break; - } - return false; + MOZ_ASSERT(aMapping.mAtom); + return GetEventTypeFromMessage(aMapping.mMessage) == aMapping.mAtom; } bool @@ -4149,10 +4169,12 @@ nsContentUtils::DispatchEventForPreloadURI(nsIDOMNode* aNode, // static nsresult -nsContentUtils::DispatchTrustedEvent(nsIDocument* aDoc, nsISupports* aTarget, +nsContentUtils::DispatchTrustedEvent(nsIDocument* aDoc, + nsISupports* aTarget, const nsAString& aEventName, - bool aCanBubble, bool aCancelable, - bool *aDefaultAction) + bool aCanBubble, + bool aCancelable, + bool* aDefaultAction) { return DispatchEvent(aDoc, aTarget, aEventName, aCanBubble, aCancelable, true, aDefaultAction); @@ -4160,10 +4182,12 @@ nsContentUtils::DispatchTrustedEvent(nsIDocument* aDoc, nsISupports* aTarget, // static nsresult -nsContentUtils::DispatchUntrustedEvent(nsIDocument* aDoc, nsISupports* aTarget, +nsContentUtils::DispatchUntrustedEvent(nsIDocument* aDoc, + nsISupports* aTarget, const nsAString& aEventName, - bool aCanBubble, bool aCancelable, - bool *aDefaultAction) + bool aCanBubble, + bool aCancelable, + bool* aDefaultAction) { return DispatchEvent(aDoc, aTarget, aEventName, aCanBubble, aCancelable, false, aDefaultAction); @@ -4171,10 +4195,13 @@ nsContentUtils::DispatchUntrustedEvent(nsIDocument* aDoc, nsISupports* aTarget, // static nsresult -nsContentUtils::DispatchEvent(nsIDocument* aDoc, nsISupports* aTarget, +nsContentUtils::DispatchEvent(nsIDocument* aDoc, + nsISupports* aTarget, const nsAString& aEventName, - bool aCanBubble, bool aCancelable, - bool aTrusted, bool *aDefaultAction, + bool aCanBubble, + bool aCancelable, + bool aTrusted, + bool* aDefaultAction, bool aOnlyChromeDispatch) { nsCOMPtr event; @@ -4189,12 +4216,50 @@ nsContentUtils::DispatchEvent(nsIDocument* aDoc, nsISupports* aTarget, return target->DispatchEvent(event, aDefaultAction ? aDefaultAction : &dummy); } +// static +nsresult +nsContentUtils::DispatchEvent(nsIDocument* aDoc, + nsISupports* aTarget, + WidgetEvent& aEvent, + EventMessage aEventMessage, + bool aCanBubble, + bool aCancelable, + bool aTrusted, + bool* aDefaultAction, + bool aOnlyChromeDispatch) +{ + MOZ_ASSERT_IF(aOnlyChromeDispatch, aTrusted); + + nsCOMPtr target(do_QueryInterface(aTarget)); + + aEvent.mTime = PR_Now(); + + aEvent.mSpecifiedEventType = GetEventTypeFromMessage(aEventMessage); + aEvent.SetDefaultComposed(); + aEvent.SetDefaultComposedInNativeAnonymousContent(); + + aEvent.mFlags.mBubbles = aCanBubble; + aEvent.mFlags.mCancelable = aCancelable; + aEvent.mFlags.mOnlyChromeDispatch = aOnlyChromeDispatch; + + aEvent.mTarget = target; + + nsEventStatus status = nsEventStatus_eIgnore; + nsresult rv = EventDispatcher::DispatchDOMEvent(target, &aEvent, nullptr, + nullptr, &status); + if (aDefaultAction) { + *aDefaultAction = (status != nsEventStatus_eConsumeNoDefault); + } + return rv; +} + nsresult nsContentUtils::DispatchChromeEvent(nsIDocument *aDoc, nsISupports *aTarget, const nsAString& aEventName, - bool aCanBubble, bool aCancelable, - bool *aDefaultAction) + bool aCanBubble, + bool aCancelable, + bool* aDefaultAction) { nsCOMPtr event; diff --git a/dom/base/nsContentUtils.h b/dom/base/nsContentUtils.h index 3d5476d7aa..37866aaf64 100644 --- a/dom/base/nsContentUtils.h +++ b/dom/base/nsContentUtils.h @@ -19,6 +19,7 @@ #include "js/TypeDecls.h" #include "js/Value.h" #include "js/RootingAPI.h" +#include "mozilla/BasicEvents.h" #include "mozilla/EventForwards.h" #include "mozilla/GuardObjects.h" #include "mozilla/TimeStamp.h" @@ -1208,6 +1209,33 @@ public: bool aCancelable, bool *aDefaultAction = nullptr); + /** + * This method creates and dispatches a trusted event using an event message. + * @param aDoc The document which will be used to create the event. + * @param aTarget The target of the event, should be QIable to + * EventTarget. + * @param aEventMessage The event message. + * @param aCanBubble Whether the event can bubble. + * @param aCancelable Is the event cancelable. + * @param aDefaultAction Set to true if default action should be taken, + * see nsIDOMEventTarget::DispatchEvent. + */ + template + static nsresult DispatchTrustedEvent(nsIDocument* aDoc, + nsISupports* aTarget, + mozilla::EventMessage aEventMessage, + bool aCanBubble, + bool aCancelable, + bool *aDefaultAction = nullptr, + bool aOnlyChromeDispatch = false) + { + WidgetEventType event(true, aEventMessage); + MOZ_ASSERT(GetEventClassIDFromMessage(aEventMessage) == event.mClass); + return DispatchEvent(aDoc, aTarget, event, aEventMessage, + aCanBubble, aCancelable, true, + aDefaultAction, aOnlyChromeDispatch); + } + /** * This method creates and dispatches a untrusted event. * Works only with events which can be created by calling @@ -1228,6 +1256,33 @@ public: bool aCancelable, bool *aDefaultAction = nullptr); + /** + * This method creates and dispatches a untrusted event using an event message. + * @param aDoc The document which will be used to create the event. + * @param aTarget The target of the event, should be QIable to + * EventTarget. + * @param aEventMessage The event message. + * @param aCanBubble Whether the event can bubble. + * @param aCancelable Is the event cancelable. + * @param aDefaultAction Set to true if default action should be taken, + * see nsIDOMEventTarget::DispatchEvent. + */ + template + static nsresult DispatchUntrustedEvent(nsIDocument* aDoc, + nsISupports* aTarget, + mozilla::EventMessage aEventMessage, + bool aCanBubble, + bool aCancelable, + bool *aDefaultAction = nullptr, + bool aOnlyChromeDispatch = false) + { + WidgetEventType event(false, aEventMessage); + MOZ_ASSERT(GetEventClassIDFromMessage(aEventMessage) == event.mClass); + return DispatchEvent(aDoc, aTarget, event, aEventMessage, + aCanBubble, aCancelable, false, + aDefaultAction, aOnlyChromeDispatch); + } + /** * This method creates and dispatches a trusted event to the chrome * event handler (the parent object of the DOM Window in the event target @@ -2883,6 +2938,16 @@ private: bool *aDefaultAction = nullptr, bool aOnlyChromeDispatch = false); + static nsresult DispatchEvent(nsIDocument* aDoc, + nsISupports* aTarget, + mozilla::WidgetEvent& aWidgetEvent, + mozilla::EventMessage aEventMessage, + bool aCanBubble, + bool aCancelable, + bool aTrusted, + bool *aDefaultAction = nullptr, + bool aOnlyChromeDispatch = false); + static void InitializeModifierStrings(); static void DropFragmentParsers(); @@ -2894,6 +2959,9 @@ private: static void* AllocClassMatchingInfo(nsINode* aRootNode, const nsString* aClasses); + static mozilla::EventClassID + GetEventClassIDFromMessage(mozilla::EventMessage aEventMessage); + // Fills in aInfo with the tokens from the supplied autocomplete attribute. static AutocompleteAttrState InternalSerializeAutocompleteAttribute(const nsAttrValue* aAttrVal, mozilla::dom::AutocompleteInfo& aInfo);