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:
@@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user