From bf5b70fa3560461036872975a8bda514687a5448 Mon Sep 17 00:00:00 2001 From: Robert O'Callahan Date: Fri, 5 Mar 2010 13:10:32 +1300 Subject: [PATCH] Bug 545268. Decide whether to suppress a mouse event by looking at the suppression state of the document where the event is going to be delivered. r=smaug --- content/events/test/Makefile.in | 1 + content/events/test/test_bug545268.html | 151 ++++++++++++++++++++++++ layout/base/nsPresShell.cpp | 94 ++++++++------- 3 files changed, 202 insertions(+), 44 deletions(-) create mode 100644 content/events/test/test_bug545268.html diff --git a/content/events/test/Makefile.in b/content/events/test/Makefile.in index 0d302c8e02ec..e9b5bb115dfa 100644 --- a/content/events/test/Makefile.in +++ b/content/events/test/Makefile.in @@ -83,6 +83,7 @@ _TEST_FILES = \ test_bug508479.html \ test_bug517851.html \ test_bug534833.html \ + test_bug545268.html \ $(NULL) _CHROME_FILES = \ diff --git a/content/events/test/test_bug545268.html b/content/events/test/test_bug545268.html new file mode 100644 index 000000000000..cbd5487cd823 --- /dev/null +++ b/content/events/test/test_bug545268.html @@ -0,0 +1,151 @@ + + + + + Test for Bug 545268 + + + + + +Mozilla Bug 545268 +

+

+ +
+
+
+ + diff --git a/layout/base/nsPresShell.cpp b/layout/base/nsPresShell.cpp index d9bb2883ce03..3e6e16259591 100644 --- a/layout/base/nsPresShell.cpp +++ b/layout/base/nsPresShell.cpp @@ -6097,23 +6097,16 @@ PresShell::HandleEvent(nsIView *aView, return NS_OK; } - if (mDocument && mDocument->EventHandlingSuppressed()) { - nsDelayedEvent* event = nsnull; - if (aEvent->eventStructType == NS_KEY_EVENT) { - if (aEvent->message == NS_KEY_DOWN) { - mNoDelayedKeyEvents = PR_TRUE; - } else if (!mNoDelayedKeyEvents) { - event = new nsDelayedKeyEvent(static_cast(aEvent)); + if (aEvent->eventStructType == NS_KEY_EVENT && + mDocument && mDocument->EventHandlingSuppressed()) { + if (aEvent->message == NS_KEY_DOWN) { + mNoDelayedKeyEvents = PR_TRUE; + } else if (!mNoDelayedKeyEvents) { + nsDelayedEvent* event = + new nsDelayedKeyEvent(static_cast(aEvent)); + if (event && !mDelayedEvents.AppendElement(event)) { + delete event; } - } else if (aEvent->eventStructType == NS_MOUSE_EVENT) { - if (aEvent->message == NS_MOUSE_BUTTON_DOWN) { - mNoDelayedMouseEvents = PR_TRUE; - } else if (!mNoDelayedMouseEvents && aEvent->message == NS_MOUSE_BUTTON_UP) { - event = new nsDelayedMouseEvent(static_cast(aEvent)); - } - } - if (event && !mDelayedEvents.AppendElement(event)) { - delete event; } return NS_OK; } @@ -6159,7 +6152,7 @@ PresShell::HandleEvent(nsIView *aView, nsTArray popups = pm->GetVisiblePopups(); PRUint32 i; // Search from top to bottom - nsIDocument* doc = frame->PresContext()->GetPresShell()->GetDocument(); + nsIDocument* doc = framePresContext->GetPresShell()->GetDocument(); for (i = 0; i < popups.Length(); i++) { nsIFrame* popup = popups[i]; if (popup->GetOverflowRect().Contains( @@ -6221,7 +6214,6 @@ PresShell::HandleEvent(nsIView *aView, // Get the frame at the event point. However, don't do this if we're // capturing and retargeting the event because the captured frame will // be used instead below. - nsIFrame* targetFrame = nsnull; if (!captureRetarget) { nsPoint eventPoint = nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, frame); @@ -6230,8 +6222,11 @@ PresShell::HandleEvent(nsIView *aView, if (aEvent->eventStructType == NS_MOUSE_EVENT) { ignoreRootScrollFrame = static_cast(aEvent)->ignoreRootScrollFrame; } - targetFrame = nsLayoutUtils::GetFrameForPoint(frame, eventPoint, - PR_FALSE, ignoreRootScrollFrame); + nsIFrame* target = nsLayoutUtils::GetFrameForPoint(frame, eventPoint, + PR_FALSE, ignoreRootScrollFrame); + if (target) { + frame = target; + } } } @@ -6240,9 +6235,8 @@ PresShell::HandleEvent(nsIView *aView, // capture retargeting is being used, no frame was found or the frame's // content is not a descendant of the capturing content. if (capturingContent && - (gCaptureInfo.mRetargetToElement || - !targetFrame || !targetFrame->GetContent() || - !nsContentUtils::ContentIsCrossDocDescendantOf(targetFrame->GetContent(), + (gCaptureInfo.mRetargetToElement || !frame->GetContent() || + !nsContentUtils::ContentIsCrossDocDescendantOf(frame->GetContent(), capturingContent))) { // A check was already done above to ensure that capturingContent is // in this presshell. @@ -6250,33 +6244,45 @@ PresShell::HandleEvent(nsIView *aView, "Unexpected document"); nsIFrame* capturingFrame = capturingContent->GetPrimaryFrame(); if (capturingFrame) { - targetFrame = capturingFrame; - aView = targetFrame->GetClosestView(); + frame = capturingFrame; + aView = frame->GetClosestView(); } } - if (targetFrame) { - PresShell* shell = - static_cast(targetFrame->PresContext()->PresShell()); - if (shell != this) { - // Handle the event in the correct shell. - // Prevent deletion until we're done with event handling (bug 336582). - nsCOMPtr kungFuDeathGrip(shell); - nsIView* subshellRootView; - shell->GetViewManager()->GetRootView(subshellRootView); - // We pass the subshell's root view as the view to start from. This is - // the only correct alternative; if the event was captured then it - // must have been captured by us or some ancestor shell and we - // now ask the subshell to dispatch it normally. - return shell->HandlePositionedEvent(subshellRootView, targetFrame, - aEvent, aEventStatus); + // Suppress mouse event if it's being targeted at an element inside + // a document which needs events suppressed + if (aEvent->eventStructType == NS_MOUSE_EVENT && + frame->PresContext()->Document()->EventHandlingSuppressed()) { + if (aEvent->message == NS_MOUSE_BUTTON_DOWN) { + mNoDelayedMouseEvents = PR_TRUE; + } else if (!mNoDelayedMouseEvents && aEvent->message == NS_MOUSE_BUTTON_UP) { + nsDelayedEvent* event = + new nsDelayedMouseEvent(static_cast(aEvent)); + if (!mDelayedEvents.AppendElement(event)) { + delete event; + } } + + return NS_OK; } - - if (!targetFrame) { - targetFrame = frame; + + PresShell* shell = + static_cast(frame->PresContext()->PresShell()); + if (shell != this) { + // Handle the event in the correct shell. + // Prevent deletion until we're done with event handling (bug 336582). + nsCOMPtr kungFuDeathGrip(shell); + nsIView* subshellRootView; + shell->GetViewManager()->GetRootView(subshellRootView); + // We pass the subshell's root view as the view to start from. This is + // the only correct alternative; if the event was captured then it + // must have been captured by us or some ancestor shell and we + // now ask the subshell to dispatch it normally. + return shell->HandlePositionedEvent(subshellRootView, frame, + aEvent, aEventStatus); } - return HandlePositionedEvent(aView, targetFrame, aEvent, aEventStatus); + + return HandlePositionedEvent(aView, frame, aEvent, aEventStatus); } nsresult rv = NS_OK;