Issue #2472 - Part 1: Add helper method to directly dispatch events to widgets.

This commit is contained in:
Moonchild 2024-03-01 13:08:06 +01:00 committed by roytam1
commit 3058bef840
2 changed files with 152 additions and 19 deletions

View file

@ -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<nsIDOMEvent> 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<EventTarget> 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<nsIDOMEvent> event;

View file

@ -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 <class WidgetEventType>
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 <class WidgetEventType>
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);