diff --git a/content/events/src/nsEventDispatcher.cpp b/content/events/src/nsEventDispatcher.cpp index 65b165e48a17..2907d0a25e82 100644 --- a/content/events/src/nsEventDispatcher.cpp +++ b/content/events/src/nsEventDispatcher.cpp @@ -489,6 +489,21 @@ nsEventDispatcher::Dispatch(nsISupports* aTarget, nsCOMPtr target = do_QueryInterface(aTarget); + PRBool retargeted = PR_FALSE; + + if (aEvent->flags & NS_EVENT_RETARGET_TO_NON_NATIVE_ANONYMOUS) { + nsCOMPtr content = do_QueryInterface(target); + if (content && content->IsInNativeAnonymousSubtree()) { + nsCOMPtr newTarget = + do_QueryInterface(content->FindFirstNonNativeAnonymous()); + NS_ENSURE_STATE(newTarget); + + aEvent->originalTarget = target; + target = newTarget; + retargeted = PR_TRUE; + } + } + if (aEvent->flags & NS_EVENT_FLAG_ONLY_CHROME_DISPATCH) { nsCOMPtr node = do_QueryInterface(aTarget); if (!node) { @@ -579,7 +594,16 @@ nsEventDispatcher::Dispatch(nsISupports* aTarget, aEvent->target = aEvent->target->GetTargetForEventTargetChain(); NS_ENSURE_STATE(aEvent->target); } - aEvent->originalTarget = aEvent->target; + + if (retargeted) { + aEvent->originalTarget = + aEvent->originalTarget->GetTargetForEventTargetChain(); + NS_ENSURE_STATE(aEvent->originalTarget); + } + else { + aEvent->originalTarget = aEvent->target; + } + nsCOMPtr content = do_QueryInterface(aEvent->originalTarget); PRBool isInAnon = (content && content->IsInAnonymousSubtree()); diff --git a/content/events/test/Makefile.in b/content/events/test/Makefile.in index 5bf54dc49990..6578701ef939 100644 --- a/content/events/test/Makefile.in +++ b/content/events/test/Makefile.in @@ -130,6 +130,8 @@ _CHROME_FILES = \ bug415498-doc2.html \ bug602962.xul \ test_bug602962.xul \ + test_bug617528.xul \ + window_bug617528.xul \ $(NULL) libs:: $(_TEST_FILES) diff --git a/content/events/test/test_bug617528.xul b/content/events/test/test_bug617528.xul new file mode 100644 index 000000000000..e2aa8c3cf38f --- /dev/null +++ b/content/events/test/test_bug617528.xul @@ -0,0 +1,97 @@ + + + + + + + + diff --git a/content/events/test/window_bug617528.xul b/content/events/test/window_bug617528.xul new file mode 100644 index 000000000000..fc87f9d78813 --- /dev/null +++ b/content/events/test/window_bug617528.xul @@ -0,0 +1,9 @@ + + + + + + + diff --git a/layout/base/nsPresShell.cpp b/layout/base/nsPresShell.cpp index 2fc3fce00241..6d2fab0e421c 100644 --- a/layout/base/nsPresShell.cpp +++ b/layout/base/nsPresShell.cpp @@ -7104,6 +7104,9 @@ PresShell::HandleEventInternal(nsEvent* aEvent, nsIView *aView, !AdjustContextMenuKeyEvent(me)) { return NS_OK; } + if (me->isShift) + aEvent->flags |= NS_EVENT_FLAG_ONLY_CHROME_DISPATCH | + NS_EVENT_RETARGET_TO_NON_NATIVE_ANONYMOUS; } nsAutoHandlingUserInputStatePusher userInpStatePusher(isHandlingUserInput, diff --git a/widget/public/nsGUIEvent.h b/widget/public/nsGUIEvent.h index df2663e6ae27..3c7bb19ed029 100644 --- a/widget/public/nsGUIEvent.h +++ b/widget/public/nsGUIEvent.h @@ -161,6 +161,8 @@ class nsHashKey; #define NS_EVENT_FLAG_PREVENT_ANCHOR_ACTIONS 0x20000 +#define NS_EVENT_RETARGET_TO_NON_NATIVE_ANONYMOUS 0x40000 + #define NS_EVENT_CAPTURE_MASK (~(NS_EVENT_FLAG_BUBBLE | NS_EVENT_FLAG_NO_CONTENT_DISPATCH)) #define NS_EVENT_BUBBLE_MASK (~(NS_EVENT_FLAG_CAPTURE | NS_EVENT_FLAG_NO_CONTENT_DISPATCH))