Skip to content

Commit

Permalink
Bug 1236979 part 2: Create an RAII helper-class to temporarily overri…
Browse files Browse the repository at this point in the history
…de an Event's mMessage (i.e. its DOM-exposed 'type') r=smaug
  • Loading branch information
dholbert committed Feb 2, 2016
1 parent ad2eec1 commit bbe7076
Showing 1 changed file with 44 additions and 0 deletions.
44 changes: 44 additions & 0 deletions dom/events/Event.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ namespace mozilla {
namespace dom {

class EventTarget;
class EventMessageAutoOverride;
class WantsPopupControlCheck;
#define GENERATED_EVENT(EventClass_) class EventClass_;
#include "mozilla/dom/GeneratedEventList.h"
Expand Down Expand Up @@ -239,6 +240,7 @@ class Event : public EventBase,
void SetEventType(const nsAString& aEventTypeArg);
already_AddRefed<nsIContent> GetTargetFromFrame();

friend class EventMessageAutoOverride;
friend class WantsPopupControlCheck;
void SetWantsPopupControlCheck(bool aCheck)
{
Expand Down Expand Up @@ -268,6 +270,48 @@ class Event : public EventBase,
bool mWantsPopupControlCheck;
};

/**
* RAII helper-class to override an event's message (i.e. its DOM-exposed
* type), for as long as the object is alive. Restores the original
* EventMessage when destructed.
*
* Notable requirements:
* - The original & overriding messages must be known (not eUnidentifiedEvent).
* - The original & overriding messages must be different.
* - The passed-in nsIDOMEvent must outlive this RAII helper.
*/
class MOZ_RAII EventMessageAutoOverride
{
public:
explicit EventMessageAutoOverride(nsIDOMEvent* aEvent,
EventMessage aOverridingMessage)
: mEvent(aEvent->InternalDOMEvent()),
mOrigMessage(mEvent->mEvent->mMessage)
{
MOZ_ASSERT(aOverridingMessage != mOrigMessage,
"Don't use this class if you're not actually overriding");
MOZ_ASSERT(aOverridingMessage != eUnidentifiedEvent,
"Only use this class with a valid overriding EventMessage");
MOZ_ASSERT(mOrigMessage != eUnidentifiedEvent &&
mEvent->mEvent->typeString.IsEmpty(),
"Only use this class on events whose overridden type is "
"known (so we can restore it properly)");

mEvent->mEvent->mMessage = aOverridingMessage;
}

~EventMessageAutoOverride()
{
mEvent->mEvent->mMessage = mOrigMessage;
}

protected:
// Non-owning ref, which should be safe since we're a stack-allocated object
// with limited lifetime. Whoever creates us should keep mEvent alive.
Event* const MOZ_NON_OWNING_REF mEvent;
const EventMessage mOrigMessage;
};

class MOZ_STACK_CLASS WantsPopupControlCheck
{
public:
Expand Down

0 comments on commit bbe7076

Please sign in to comment.