diff --git a/content/events/src/nsEventDispatcher.cpp b/content/events/src/nsEventDispatcher.cpp index 4453f78ca13f..875df64c5b69 100644 --- a/content/events/src/nsEventDispatcher.cpp +++ b/content/events/src/nsEventDispatcher.cpp @@ -50,6 +50,7 @@ #include "nsINode.h" #include "nsPIDOMWindow.h" #include "nsDOMPopStateEvent.h" +#include "nsFrameLoader.h" #define NS_TARGET_CHAIN_FORCE_CONTENT_DISPATCH (1 << 0) #define NS_TARGET_CHAIN_WANTS_WILL_HANDLE_EVENT (1 << 1) @@ -500,11 +501,22 @@ nsEventDispatcher::Dispatch(nsISupports* aTarget, if (!nsContentUtils::IsChromeDoc(doc)) { nsPIDOMWindow* win = doc ? doc->GetInnerWindow() : nsnull; // If we can't dispatch the event to chrome, do nothing. - NS_ENSURE_TRUE(win && win->GetChromeEventHandler(), NS_OK); + nsPIDOMEventTarget* piTarget = win ? win->GetChromeEventHandler() : nsnull; + NS_ENSURE_TRUE(piTarget, NS_OK); + + nsCOMPtr flo = do_QueryInterface(piTarget); + if (flo) { + nsRefPtr fl = flo->GetFrameLoader(); + if (fl) { + nsPIDOMEventTarget* t = fl->GetTabChildGlobalAsEventTarget(); + piTarget = t ? t : piTarget; + } + } + // Set the target to be the original dispatch target, aEvent->target = target; - // but use chrome event handler for event target chain. - target = do_QueryInterface(win->GetChromeEventHandler()); + // but use chrome event handler or TabChildGlobal for event target chain. + target = piTarget; } } diff --git a/content/events/test/test_bug508479.html b/content/events/test/test_bug508479.html index dfeede128ae6..e4b577cd4269 100644 --- a/content/events/test/test_bug508479.html +++ b/content/events/test/test_bug508479.html @@ -61,6 +61,11 @@ function fireDrop(element, shouldAllowDrop, shouldAllowOnlyChromeDrop) { ok(!ds.getCurrentSession(), "There shouldn't be a drag session anymore!"); } +var chromeGotEvent = false; +function chromeListener(e) { + chromeGotEvent = true; +} + function runTests() { var targetHandling = document.getElementById("handling_target"); @@ -73,9 +78,11 @@ function runTests() gGotHandlingDrop = false; gGotNotHandlingDrop = false; + SpecialPowers.addChromeEventListener("drop", chromeListener, true, false); var targetNotHandling = document.getElementById("nothandling_target"); fireDrop(targetNotHandling, true, true); - + SpecialPowers.removeChromeEventListener("drop", chromeListener, true); + ok(chromeGotEvent, "Chrome should have got drop event!"); is(gGotHandlingDrop, false, "Didn't get drop on accepting element (2)"); is(gGotNotHandlingDrop, false, "Didn't get drop on unaccepting element (2)");