Bug 1905267 - part 1: Make PresShell manage event target frame and content with a struct r=smaug

`PresShell::mCurrentEventTargetContent` may be update to non-element node
when `PresShell::mCurrentEventTargetFrame` is destroyed.  Therefore, for
avoiding it, I'd like to add `EventMessage` to the group to consider whether
the content needs to be `Element`.  However, adding new members for current
and stack would make `PresShell` members more messy.  Therefore, I'd like to
group the data with the simple struct.

Differential Revision: https://phabricator.services.mozilla.com/D217204
This commit is contained in:
Masayuki Nakano
2024-07-30 00:06:09 +00:00
parent 84c538e41e
commit 66321dce9c
2 changed files with 119 additions and 88 deletions

View File

@@ -762,7 +762,6 @@ PresShell::PresShell(Document* aDocument)
#ifdef ACCESSIBILITY #ifdef ACCESSIBILITY
mDocAccessible(nullptr), mDocAccessible(nullptr),
#endif // ACCESSIBILITY #endif // ACCESSIBILITY
mCurrentEventFrame(nullptr),
mMouseLocation(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE), mMouseLocation(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE),
mLastResolutionChangeOrigin(ResolutionChangeOrigin::Apz), mLastResolutionChangeOrigin(ResolutionChangeOrigin::Apz),
mPaintCount(0), mPaintCount(0),
@@ -862,7 +861,7 @@ PresShell::~PresShell() {
Destroy(); Destroy();
} }
NS_ASSERTION(mCurrentEventContentStack.Count() == 0, NS_ASSERTION(mCurrentEventTargetStack.IsEmpty(),
"Huh, event content left on the stack in pres shell dtor!"); "Huh, event content left on the stack in pres shell dtor!");
NS_ASSERTION(mFirstCallbackEventRequest == nullptr && NS_ASSERTION(mFirstCallbackEventRequest == nullptr &&
mLastCallbackEventRequest == nullptr, mLastCallbackEventRequest == nullptr,
@@ -872,7 +871,6 @@ PresShell::~PresShell() {
"Some pres arena objects were not freed"); "Some pres arena objects were not freed");
mFrameConstructor = nullptr; mFrameConstructor = nullptr;
mCurrentEventContent = nullptr;
} }
/** /**
@@ -1297,11 +1295,10 @@ void PresShell::Destroy() {
// leave them in) and null out the mCurrentEventFrame pointer as // leave them in) and null out the mCurrentEventFrame pointer as
// well. // well.
mCurrentEventFrame = nullptr; mCurrentEventTarget.ClearFrame();
int32_t i, count = mCurrentEventFrameStack.Length(); for (EventTargetInfo& eventTargetInfo : mCurrentEventTargetStack) {
for (i = 0; i < count; i++) { eventTargetInfo.ClearFrame();
mCurrentEventFrameStack[i] = nullptr;
} }
mFramesToDirty.Clear(); mFramesToDirty.Clear();
@@ -2148,20 +2145,19 @@ void PresShell::NativeAnonymousContentRemoved(nsIContent* aAnonContent) {
if (mDocument->DevToolsAnonymousAndShadowEventsEnabled()) { if (mDocument->DevToolsAnonymousAndShadowEventsEnabled()) {
aAnonContent->QueueDevtoolsAnonymousEvent(/* aIsRemove = */ true); aAnonContent->QueueDevtoolsAnonymousEvent(/* aIsRemove = */ true);
} }
if (nsIContent* root = GetNativeAnonymousSubtreeRoot(mCurrentEventContent)) { if (nsIContent* root =
GetNativeAnonymousSubtreeRoot(mCurrentEventTarget.mContent)) {
if (aAnonContent == root) { if (aAnonContent == root) {
mCurrentEventContent = aAnonContent->GetFlattenedTreeParent(); mCurrentEventTarget.SetFrameAndContent(
mCurrentEventFrame = nullptr; nullptr, aAnonContent->GetFlattenedTreeParent());
} }
} }
for (unsigned int i = 0; i < mCurrentEventContentStack.Length(); i++) { for (EventTargetInfo& eventTargetInfo : mCurrentEventTargetStack) {
nsIContent* anon = nsIContent* anon = GetNativeAnonymousSubtreeRoot(eventTargetInfo.mContent);
GetNativeAnonymousSubtreeRoot(mCurrentEventContentStack.ElementAt(i));
if (aAnonContent == anon) { if (aAnonContent == anon) {
mCurrentEventContentStack.ReplaceObjectAt( eventTargetInfo.SetFrameAndContent(
aAnonContent->GetFlattenedTreeParent(), i); nullptr, aAnonContent->GetFlattenedTreeParent());
mCurrentEventFrameStack[i] = nullptr;
} }
} }
} }
@@ -2193,18 +2189,15 @@ void PresShell::NotifyDestroyingFrame(nsIFrame* aFrame) {
// Remove frame properties // Remove frame properties
aFrame->RemoveAllProperties(); aFrame->RemoveAllProperties();
if (aFrame == mCurrentEventFrame) { if (aFrame == mCurrentEventTarget.mFrame) {
mCurrentEventContent = aFrame->GetContent(); mCurrentEventTarget.SetFrameAndContent(nullptr, aFrame->GetContent());
mCurrentEventFrame = nullptr;
} }
for (unsigned int i = 0; i < mCurrentEventFrameStack.Length(); i++) { for (EventTargetInfo& eventTargetInfo : mCurrentEventTargetStack) {
if (aFrame == mCurrentEventFrameStack.ElementAt(i)) { if (aFrame == eventTargetInfo.mFrame) {
// One of our stack frames was deleted. Get its content so that when we // One of our stack frames was deleted. Get its content so that when we
// pop it we can still get its new frame from its content // pop it we can still get its new frame from its content
nsIContent* currentEventContent = aFrame->GetContent(); eventTargetInfo.SetFrameAndContent(nullptr, aFrame->GetContent());
mCurrentEventContentStack.ReplaceObjectAt(currentEventContent, i);
mCurrentEventFrameStack[i] = nullptr;
} }
} }
@@ -6550,12 +6543,11 @@ void PresShell::SetCapturingContent(nsIContent* aContent, CaptureFlags aFlags,
} }
nsIContent* PresShell::GetCurrentEventContent() { nsIContent* PresShell::GetCurrentEventContent() {
if (mCurrentEventContent && if (mCurrentEventTarget.mContent &&
mCurrentEventContent->GetComposedDoc() != mDocument) { mCurrentEventTarget.mContent->GetComposedDoc() != mDocument) {
mCurrentEventContent = nullptr; mCurrentEventTarget.Clear();
mCurrentEventFrame = nullptr;
} }
return mCurrentEventContent; return mCurrentEventTarget.mContent;
} }
nsIFrame* PresShell::GetCurrentEventFrame() { nsIFrame* PresShell::GetCurrentEventFrame() {
@@ -6568,12 +6560,13 @@ nsIFrame* PresShell::GetCurrentEventFrame() {
// frame shouldn't get an event, nor should we even assume its safe // frame shouldn't get an event, nor should we even assume its safe
// to try and find the frame. // to try and find the frame.
nsIContent* content = GetCurrentEventContent(); nsIContent* content = GetCurrentEventContent();
if (!mCurrentEventFrame && content) { if (!mCurrentEventTarget.mFrame && content) {
mCurrentEventFrame = content->GetPrimaryFrame(); mCurrentEventTarget.mFrame = content->GetPrimaryFrame();
MOZ_ASSERT(!mCurrentEventFrame || MOZ_ASSERT_IF(
mCurrentEventFrame->PresContext()->GetPresShell() == this); mCurrentEventTarget.mFrame,
mCurrentEventTarget.mFrame->PresContext()->GetPresShell() == this);
} }
return mCurrentEventFrame; return mCurrentEventTarget.mFrame;
} }
already_AddRefed<nsIContent> PresShell::GetEventTargetContent( already_AddRefed<nsIContent> PresShell::GetEventTargetContent(
@@ -6590,30 +6583,33 @@ already_AddRefed<nsIContent> PresShell::GetEventTargetContent(
return content.forget(); return content.forget();
} }
void PresShell::PushCurrentEventInfo(nsIFrame* aFrame, nsIContent* aContent) { void PresShell::PushCurrentEventInfo(const EventTargetInfo& aInfo) {
if (mCurrentEventFrame || mCurrentEventContent) { if (mCurrentEventTarget.IsSet()) {
mCurrentEventFrameStack.InsertElementAt(0, mCurrentEventFrame); // XXX Why do we insert first item instead of append it? This requires to
mCurrentEventContentStack.InsertObjectAt(mCurrentEventContent, 0); // move the previous items...
mCurrentEventTargetStack.InsertElementAt(0, std::move(mCurrentEventTarget));
} }
mCurrentEventFrame = aFrame; mCurrentEventTarget = aInfo;
mCurrentEventContent = aContent; }
void PresShell::PushCurrentEventInfo(EventTargetInfo&& aInfo) {
if (mCurrentEventTarget.IsSet()) {
mCurrentEventTargetStack.InsertElementAt(0, std::move(mCurrentEventTarget));
}
mCurrentEventTarget = std::move(aInfo);
} }
void PresShell::PopCurrentEventInfo() { void PresShell::PopCurrentEventInfo() {
mCurrentEventFrame = nullptr; mCurrentEventTarget.Clear();
mCurrentEventContent = nullptr;
if (0 != mCurrentEventFrameStack.Length()) { if (!mCurrentEventTargetStack.IsEmpty()) {
mCurrentEventFrame = mCurrentEventFrameStack.ElementAt(0); mCurrentEventTarget = std::move(mCurrentEventTargetStack[0]);
mCurrentEventFrameStack.RemoveElementAt(0); mCurrentEventTargetStack.RemoveElementAt(0);
mCurrentEventContent = mCurrentEventContentStack.ObjectAt(0);
mCurrentEventContentStack.RemoveObjectAt(0);
// Don't use it if it has moved to a different document. // Don't use it if it has moved to a different document.
if (mCurrentEventContent && if (mCurrentEventTarget.mContent &&
mCurrentEventContent->GetComposedDoc() != mDocument) { mCurrentEventTarget.mContent->GetComposedDoc() != mDocument) {
mCurrentEventContent = nullptr; mCurrentEventTarget.Clear();
mCurrentEventFrame = nullptr;
} }
} }
} }
@@ -8208,7 +8204,10 @@ nsresult PresShell::EventHandler::HandleEventAtFocusedContent(
RefPtr<Element> eventTargetElement = RefPtr<Element> eventTargetElement =
ComputeFocusedEventTargetElement(aGUIEvent); ComputeFocusedEventTargetElement(aGUIEvent);
mPresShell->mCurrentEventFrame = nullptr; // mCurrentEventTarget is cleared by eventInfoSetter and
// ComputeFocusedEventTargetElement shouldn't set it again.
MOZ_ASSERT(!mPresShell->mCurrentEventTarget.IsSet());
if (eventTargetElement) { if (eventTargetElement) {
nsresult rv = NS_OK; nsresult rv = NS_OK;
if (MaybeHandleEventWithAnotherPresShell(eventTargetElement, aGUIEvent, if (MaybeHandleEventWithAnotherPresShell(eventTargetElement, aGUIEvent,
@@ -8219,10 +8218,11 @@ nsresult PresShell::EventHandler::HandleEventAtFocusedContent(
// If we cannot handle the event with mPresShell, let's try to handle it // If we cannot handle the event with mPresShell, let's try to handle it
// with parent PresShell. // with parent PresShell.
mPresShell->mCurrentEventContent = eventTargetElement; mPresShell->mCurrentEventTarget.SetFrameAndContent(nullptr,
eventTargetElement);
if (!mPresShell->GetCurrentEventContent() || if (!mPresShell->GetCurrentEventContent() ||
!mPresShell->GetCurrentEventFrame() || !mPresShell->GetCurrentEventFrame() ||
InZombieDocument(mPresShell->mCurrentEventContent)) { InZombieDocument(mPresShell->mCurrentEventTarget.mContent)) {
return RetargetEventToParent(aGUIEvent, aEventStatus); return RetargetEventToParent(aGUIEvent, aEventStatus);
} }
@@ -8320,8 +8320,8 @@ nsresult PresShell::EventHandler::HandleEventWithFrameForPresShell(
MOZ_ASSERT(!aGUIEvent->IsTargetedAtFocusedContent()); MOZ_ASSERT(!aGUIEvent->IsTargetedAtFocusedContent());
MOZ_ASSERT(aEventStatus); MOZ_ASSERT(aEventStatus);
AutoCurrentEventInfoSetter eventInfoSetter(*this, aFrameForPresShell, AutoCurrentEventInfoSetter eventInfoSetter(
nullptr); *this, EventTargetInfo(aFrameForPresShell, nullptr));
nsresult rv = NS_OK; nsresult rv = NS_OK;
if (mPresShell->GetCurrentEventFrame()) { if (mPresShell->GetCurrentEventFrame()) {
@@ -8386,8 +8386,8 @@ nsresult PresShell::EventHandler::HandleEventWithTarget(
} }
AutoPointerEventTargetUpdater updater(mPresShell, aEvent, aNewEventFrame, AutoPointerEventTargetUpdater updater(mPresShell, aEvent, aNewEventFrame,
aNewEventContent, aTargetContent); aNewEventContent, aTargetContent);
AutoCurrentEventInfoSetter eventInfoSetter(*this, aNewEventFrame, AutoCurrentEventInfoSetter eventInfoSetter(
aNewEventContent); *this, EventTargetInfo(aNewEventFrame, aNewEventContent));
nsresult rv = HandleEventWithCurrentEventInfo(aEvent, aEventStatus, false, nsresult rv = HandleEventWithCurrentEventInfo(aEvent, aEventStatus, false,
aOverrideClickTarget); aOverrideClickTarget);
return rv; return rv;
@@ -8451,12 +8451,13 @@ nsresult PresShell::EventHandler::HandleEventWithCurrentEventInfo(
return NS_OK; return NS_OK;
} }
if (mPresShell->mCurrentEventContent && aEvent->IsTargetedAtFocusedWindow() && if (mPresShell->mCurrentEventTarget.mContent &&
aEvent->IsTargetedAtFocusedWindow() &&
aEvent->AllowFlushingPendingNotifications()) { aEvent->AllowFlushingPendingNotifications()) {
if (RefPtr<nsFocusManager> fm = nsFocusManager::GetFocusManager()) { if (RefPtr<nsFocusManager> fm = nsFocusManager::GetFocusManager()) {
// This may run script now. So, mPresShell might be destroyed after here. // This may run script now. So, mPresShell might be destroyed after here.
nsCOMPtr<nsIContent> currentEventContent = nsCOMPtr<nsIContent> currentEventContent =
mPresShell->mCurrentEventContent; mPresShell->mCurrentEventTarget.mContent;
fm->FlushBeforeEventHandlingIfNeeded(currentEventContent); fm->FlushBeforeEventHandlingIfNeeded(currentEventContent);
} }
} }
@@ -8513,10 +8514,11 @@ nsresult PresShell::EventHandler::DispatchEvent(
// generation of synthetic events. // generation of synthetic events.
{ // Scope for presContext { // Scope for presContext
RefPtr<nsPresContext> presContext = GetPresContext(); RefPtr<nsPresContext> presContext = GetPresContext();
nsCOMPtr<nsIContent> eventContent = mPresShell->mCurrentEventContent; nsCOMPtr<nsIContent> eventContent =
mPresShell->mCurrentEventTarget.mContent;
nsresult rv = aEventStateManager->PreHandleEvent( nsresult rv = aEventStateManager->PreHandleEvent(
presContext, aEvent, mPresShell->mCurrentEventFrame, eventContent, presContext, aEvent, mPresShell->mCurrentEventTarget.mFrame,
aEventStatus, aOverrideClickTarget); eventContent, aEventStatus, aOverrideClickTarget);
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
return rv; return rv;
} }
@@ -8641,7 +8643,8 @@ bool PresShell::EventHandler::PrepareToDispatchEvent(
case eTouchCancel: case eTouchCancel:
case eTouchPointerCancel: case eTouchPointerCancel:
return mPresShell->mTouchManager.PreHandleEvent( return mPresShell->mTouchManager.PreHandleEvent(
aEvent, aEventStatus, *aTouchIsNew, mPresShell->mCurrentEventContent); aEvent, aEventStatus, *aTouchIsNew,
mPresShell->mCurrentEventTarget.mContent);
default: default:
return true; return true;
} }
@@ -8724,7 +8727,7 @@ void PresShell::EventHandler::MaybeHandleKeyboardEventBeforeDispatch(
// If we're in fullscreen mode, exit from it forcibly when Escape key is // If we're in fullscreen mode, exit from it forcibly when Escape key is
// pressed. // pressed.
Document* doc = mPresShell->GetCurrentEventContent() Document* doc = mPresShell->GetCurrentEventContent()
? mPresShell->mCurrentEventContent->OwnerDoc() ? mPresShell->mCurrentEventTarget.mContent->OwnerDoc()
: nullptr; : nullptr;
Document* root = nsContentUtils::GetInProcessSubtreeRootDocument(doc); Document* root = nsContentUtils::GetInProcessSubtreeRootDocument(doc);
if (root && root->GetFullscreenElement()) { if (root && root->GetFullscreenElement()) {
@@ -8920,12 +8923,12 @@ nsresult PresShell::EventHandler::DispatchEventToDOM(
WidgetEvent* aEvent, nsEventStatus* aEventStatus, WidgetEvent* aEvent, nsEventStatus* aEventStatus,
nsPresShellEventCB* aEventCB) { nsPresShellEventCB* aEventCB) {
nsresult rv = NS_OK; nsresult rv = NS_OK;
nsCOMPtr<nsINode> eventTarget = mPresShell->mCurrentEventContent; nsCOMPtr<nsINode> eventTarget = mPresShell->mCurrentEventTarget.mContent;
nsPresShellEventCB* eventCBPtr = aEventCB; nsPresShellEventCB* eventCBPtr = aEventCB;
if (!eventTarget) { if (!eventTarget) {
nsCOMPtr<nsIContent> targetContent; nsCOMPtr<nsIContent> targetContent;
if (mPresShell->mCurrentEventFrame) { if (mPresShell->mCurrentEventTarget.mFrame) {
rv = mPresShell->mCurrentEventFrame->GetContentForEvent( rv = mPresShell->mCurrentEventTarget.mFrame->GetContentForEvent(
aEvent, getter_AddRefs(targetContent)); aEvent, getter_AddRefs(targetContent));
} }
if (NS_SUCCEEDED(rv) && targetContent) { if (NS_SUCCEEDED(rv) && targetContent) {
@@ -9054,8 +9057,8 @@ void PresShell::EventHandler::DispatchTouchEventToDOM(
if (contentPresShell) { if (contentPresShell) {
// XXXsmaug huge hack. Pushing possibly capturing content, // XXXsmaug huge hack. Pushing possibly capturing content,
// even though event target is something else. // even though event target is something else.
contentPresShell->PushCurrentEventInfo(content->GetPrimaryFrame(), contentPresShell->PushCurrentEventInfo(
content); EventTargetInfo(content->GetPrimaryFrame(), content));
} }
} }
@@ -9098,7 +9101,7 @@ nsresult PresShell::HandleDOMEventWithTarget(nsIContent* aTargetContent,
nsEventStatus* aStatus) { nsEventStatus* aStatus) {
nsresult rv = NS_OK; nsresult rv = NS_OK;
PushCurrentEventInfo(nullptr, aTargetContent); PushCurrentEventInfo(EventTargetInfo(nullptr, aTargetContent));
// Bug 41013: Check if the event should be dispatched to content. // Bug 41013: Check if the event should be dispatched to content.
// It's possible that we are in the middle of destroying the window // It's possible that we are in the middle of destroying the window
@@ -9122,7 +9125,7 @@ nsresult PresShell::HandleDOMEventWithTarget(nsIContent* aTargetContent,
nsEventStatus* aStatus) { nsEventStatus* aStatus) {
nsresult rv = NS_OK; nsresult rv = NS_OK;
PushCurrentEventInfo(nullptr, aTargetContent); PushCurrentEventInfo(EventTargetInfo(nullptr, aTargetContent));
nsCOMPtr<nsISupports> container = mPresContext->GetContainerWeak(); nsCOMPtr<nsISupports> container = mPresContext->GetContainerWeak();
if (container) { if (container) {
rv = EventDispatcher::DispatchDOMEvent(aTargetContent, nullptr, aEvent, rv = EventDispatcher::DispatchDOMEvent(aTargetContent, nullptr, aEvent,
@@ -9153,8 +9156,8 @@ bool PresShell::EventHandler::AdjustContextMenuKeyEvent(
itemFrame->PresContext()->AppUnitsPerDevPixel()) - itemFrame->PresContext()->AppUnitsPerDevPixel()) -
widgetPoint; widgetPoint;
mPresShell->mCurrentEventContent = itemFrame->GetContent(); mPresShell->mCurrentEventTarget.SetFrameAndContent(
mPresShell->mCurrentEventFrame = itemFrame; itemFrame, itemFrame->GetContent());
return true; return true;
} }
@@ -9217,8 +9220,8 @@ bool PresShell::EventHandler::AdjustContextMenuKeyEvent(
currentFocus, getter_AddRefs(currentPointElement), currentFocus, getter_AddRefs(currentPointElement),
aMouseEvent->mRefPoint, MOZ_KnownLive(aMouseEvent->mWidget)); aMouseEvent->mRefPoint, MOZ_KnownLive(aMouseEvent->mWidget));
if (currentPointElement) { if (currentPointElement) {
mPresShell->mCurrentEventContent = currentPointElement; mPresShell->mCurrentEventTarget.SetFrameAndContent(nullptr,
mPresShell->mCurrentEventFrame = nullptr; currentPointElement);
mPresShell->GetCurrentEventFrame(); mPresShell->GetCurrentEventFrame();
} }
} }

View File

@@ -1798,7 +1798,28 @@ class PresShell final : public nsStubDocumentObserver,
#endif #endif
} }
void PushCurrentEventInfo(nsIFrame* aFrame, nsIContent* aContent); struct EventTargetInfo {
EventTargetInfo() = default;
EventTargetInfo(nsIFrame* aFrame, nsIContent* aContent)
: mFrame(aFrame), mContent(aContent) {}
[[nodiscard]] bool IsSet() const { return mFrame || mContent; }
void Clear() {
mFrame = nullptr;
mContent = nullptr;
}
void ClearFrame() { mFrame = nullptr; }
void SetFrameAndContent(nsIFrame* aFrame, nsIContent* aContent) {
mFrame = aFrame;
mContent = aContent;
}
nsIFrame* mFrame = nullptr;
nsCOMPtr<nsIContent> mContent;
};
void PushCurrentEventInfo(const EventTargetInfo& aInfo);
void PushCurrentEventInfo(EventTargetInfo&& aInfo);
void PopCurrentEventInfo(); void PopCurrentEventInfo();
nsIContent* GetCurrentEventContent(); nsIContent* GetCurrentEventContent();
@@ -2616,7 +2637,8 @@ class PresShell final : public nsStubDocumentObserver,
nsresult HandleRetargetedEvent(WidgetGUIEvent* aGUIEvent, nsresult HandleRetargetedEvent(WidgetGUIEvent* aGUIEvent,
nsEventStatus* aEventStatus, nsEventStatus* aEventStatus,
nsIContent* aTarget) { nsIContent* aTarget) {
AutoCurrentEventInfoSetter eventInfoSetter(*this, nullptr, aTarget); AutoCurrentEventInfoSetter eventInfoSetter(
*this, EventTargetInfo(nullptr, aTarget));
if (!mPresShell->GetCurrentEventFrame()) { if (!mPresShell->GetCurrentEventFrame()) {
return NS_OK; return NS_OK;
} }
@@ -2819,22 +2841,30 @@ class PresShell final : public nsStubDocumentObserver,
: mEventHandler(aEventHandler) { : mEventHandler(aEventHandler) {
MOZ_DIAGNOSTIC_ASSERT(!mEventHandler.mCurrentEventInfoSetter); MOZ_DIAGNOSTIC_ASSERT(!mEventHandler.mCurrentEventInfoSetter);
mEventHandler.mCurrentEventInfoSetter = this; mEventHandler.mCurrentEventInfoSetter = this;
mEventHandler.mPresShell->PushCurrentEventInfo(nullptr, nullptr); mEventHandler.mPresShell->PushCurrentEventInfo(EventTargetInfo());
} }
AutoCurrentEventInfoSetter(EventHandler& aEventHandler, nsIFrame* aFrame, AutoCurrentEventInfoSetter(EventHandler& aEventHandler,
nsIContent* aContent) const EventTargetInfo& aInfo)
: mEventHandler(aEventHandler) { : mEventHandler(aEventHandler) {
MOZ_DIAGNOSTIC_ASSERT(!mEventHandler.mCurrentEventInfoSetter); MOZ_DIAGNOSTIC_ASSERT(!mEventHandler.mCurrentEventInfoSetter);
mEventHandler.mCurrentEventInfoSetter = this; mEventHandler.mCurrentEventInfoSetter = this;
mEventHandler.mPresShell->PushCurrentEventInfo(aFrame, aContent); mEventHandler.mPresShell->PushCurrentEventInfo(aInfo);
}
AutoCurrentEventInfoSetter(EventHandler& aEventHandler,
EventTargetInfo&& aInfo)
: mEventHandler(aEventHandler) {
MOZ_DIAGNOSTIC_ASSERT(!mEventHandler.mCurrentEventInfoSetter);
mEventHandler.mCurrentEventInfoSetter = this;
mEventHandler.mPresShell->PushCurrentEventInfo(
std::forward<EventTargetInfo>(aInfo));
} }
AutoCurrentEventInfoSetter(EventHandler& aEventHandler, AutoCurrentEventInfoSetter(EventHandler& aEventHandler,
EventTargetData& aEventTargetData) EventTargetData& aEventTargetData)
: mEventHandler(aEventHandler) { : mEventHandler(aEventHandler) {
MOZ_DIAGNOSTIC_ASSERT(!mEventHandler.mCurrentEventInfoSetter); MOZ_DIAGNOSTIC_ASSERT(!mEventHandler.mCurrentEventInfoSetter);
mEventHandler.mCurrentEventInfoSetter = this; mEventHandler.mCurrentEventInfoSetter = this;
mEventHandler.mPresShell->PushCurrentEventInfo( mEventHandler.mPresShell->PushCurrentEventInfo(EventTargetInfo(
aEventTargetData.GetFrame(), aEventTargetData.GetContent()); aEventTargetData.GetFrame(), aEventTargetData.GetContent()));
} }
~AutoCurrentEventInfoSetter() { ~AutoCurrentEventInfoSetter() {
mEventHandler.mPresShell->PopCurrentEventInfo(); mEventHandler.mPresShell->PopCurrentEventInfo();
@@ -3005,10 +3035,8 @@ class PresShell final : public nsStubDocumentObserver,
a11y::DocAccessible* mDocAccessible; a11y::DocAccessible* mDocAccessible;
#endif // #ifdef ACCESSIBILITY #endif // #ifdef ACCESSIBILITY
nsIFrame* mCurrentEventFrame; EventTargetInfo mCurrentEventTarget;
nsCOMPtr<nsIContent> mCurrentEventContent; nsTArray<EventTargetInfo> mCurrentEventTargetStack;
nsTArray<nsIFrame*> mCurrentEventFrameStack;
nsCOMArray<nsIContent> mCurrentEventContentStack;
// Set of frames that we should mark with NS_FRAME_HAS_DIRTY_CHILDREN after // Set of frames that we should mark with NS_FRAME_HAS_DIRTY_CHILDREN after
// we finish reflowing mCurrentReflowRoot. // we finish reflowing mCurrentReflowRoot.
nsTHashSet<nsIFrame*> mFramesToDirty; nsTHashSet<nsIFrame*> mFramesToDirty;