From 66c92d82af94a749e9cd92649a7ec873cb0a27b2 Mon Sep 17 00:00:00 2001 From: Olli Pettay Date: Mon, 28 May 2012 12:27:25 +0300 Subject: [PATCH] Bug 758401 - Add a way to get message manager from docshell, r=jst --- content/base/test/chrome/file_bug549682.xul | 16 ++++++++++++++++ docshell/base/nsDocShell.cpp | 17 +++++++++++++++++ dom/interfaces/base/nsITabChild.idl | 4 +++- dom/ipc/TabChild.cpp | 11 +++++++++++ dom/ipc/TabChild.h | 1 + dom/ipc/remote-test.js | 4 +++- 6 files changed, 51 insertions(+), 2 deletions(-) diff --git a/content/base/test/chrome/file_bug549682.xul b/content/base/test/chrome/file_bug549682.xul index e35f402101c3..16eee8d14637 100644 --- a/content/base/test/chrome/file_bug549682.xul +++ b/content/base/test/chrome/file_bug549682.xul @@ -91,6 +91,22 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=549682 function run() { var localmm = document.getElementById('ifr').messageManager; + + var wn = document.getElementById('ifr').contentWindow + .getInterface(Components.interfaces.nsIWebNavigation); + opener.wrappedJSObject.ok(wn, "Should have webnavigation"); + var cfmm = wn.getInterface(Components.interfaces.nsIContentFrameMessageManager); + opener.wrappedJSObject.ok(cfmm, "Should have content messageManager"); + + var didGetSyncMessage = false; + function syncContinueTestFn() { + didGetSyncMessage = true; + } + localmm.addMessageListener("syncContinueTest", syncContinueTestFn); + cfmm.sendSyncMessage("syncContinueTest", {}); + localmm.removeMessageListener("syncContinueTest", syncContinueTestFn); + opener.wrappedJSObject.ok(didGetSyncMessage, "Should have got sync message!"); + localmm.addMessageListener("lasync", localL); localmm.loadFrameScript("data:,sendAsyncMessage('lasync', { data: 2345 })", false); diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp index ae099894cbdf..39b6caa790e1 100644 --- a/docshell/base/nsDocShell.cpp +++ b/docshell/base/nsDocShell.cpp @@ -190,6 +190,7 @@ #include "nsDOMNavigationTiming.h" #include "nsITimedChannel.h" #include "mozilla/StartupTimeline.h" +#include "nsIFrameMessageManager.h" static NS_DEFINE_CID(kDOMScriptObjectFactoryCID, NS_DOM_SCRIPT_OBJECT_FACTORY_CID); @@ -1057,6 +1058,22 @@ NS_IMETHODIMP nsDocShell::GetInterface(const nsIID & aIID, void **aSink) return ir->GetInterface(aIID, aSink); } } + else if (aIID.Equals(NS_GET_IID(nsIContentFrameMessageManager))) { + nsCOMPtr tabChild = + do_GetInterface(static_cast(this)); + nsCOMPtr mm; + if (tabChild) { + tabChild-> + GetMessageManager(getter_AddRefs(mm)); + } else { + nsCOMPtr win = + do_GetInterface(static_cast(this)); + if (win) { + mm = do_QueryInterface(win->GetParentTarget()); + } + } + *aSink = mm.get(); + } else { return nsDocLoader::GetInterface(aIID, aSink); } diff --git a/dom/interfaces/base/nsITabChild.idl b/dom/interfaces/base/nsITabChild.idl index ac77e180dda7..5f09e1d85694 100644 --- a/dom/interfaces/base/nsITabChild.idl +++ b/dom/interfaces/base/nsITabChild.idl @@ -4,10 +4,12 @@ #include "domstubs.idl" +interface nsIContentFrameMessageManager; // Sole purpose is to be able to identify the concrete class nsTabChild -[uuid(a89f8ab5-ff71-492a-8ed5-71185446fa66)] +[uuid(bf1eddf9-731b-4a4b-bd65-9a712a892832)] interface nsITabChild : nsISupports { + readonly attribute nsIContentFrameMessageManager messageManager; }; diff --git a/dom/ipc/TabChild.cpp b/dom/ipc/TabChild.cpp index c37f64658a4f..9c0c0283af16 100644 --- a/dom/ipc/TabChild.cpp +++ b/dom/ipc/TabChild.cpp @@ -939,6 +939,17 @@ TabChild::SetBackgroundColor(const nscolor& aColor) } } +NS_IMETHODIMP +TabChild::GetMessageManager(nsIContentFrameMessageManager** aResult) +{ + if (mTabChildGlobal) { + NS_ADDREF(*aResult = mTabChildGlobal); + return NS_OK; + } + *aResult = nsnull; + return NS_ERROR_FAILURE; +} + static bool SendSyncMessageToParent(void* aCallbackData, const nsAString& aMessage, diff --git a/dom/ipc/TabChild.h b/dom/ipc/TabChild.h index 2b3491f821cc..72edc9612deb 100644 --- a/dom/ipc/TabChild.h +++ b/dom/ipc/TabChild.h @@ -152,6 +152,7 @@ public: NS_DECL_NSIINTERFACEREQUESTOR NS_DECL_NSIWINDOWPROVIDER NS_DECL_NSIDIALOGCREATOR + NS_DECL_NSITABCHILD virtual bool RecvLoadURL(const nsCString& uri); virtual bool RecvShow(const nsIntSize& size); diff --git a/dom/ipc/remote-test.js b/dom/ipc/remote-test.js index 6e5932fd5e46..dd21415cd740 100644 --- a/dom/ipc/remote-test.js +++ b/dom/ipc/remote-test.js @@ -28,7 +28,9 @@ addEventListener("click", dump(e.target + "\n"); if (e.target instanceof Components.interfaces.nsIDOMHTMLAnchorElement && dshell == docShell) { - var retval = sendSyncMessage("linkclick", { href: e.target.href }); + var retval = docShell.QueryInterface(Components.interfaces.nsIInterfaceRequestor). + getInterface(Components.interfaces.nsIContentFrameMessageManager). + sendSyncMessage("linkclick", { href: e.target.href }); dump(uneval(retval[0]) + "\n"); // Test here also that both retvals are the same sendAsyncMessage("linkclick-reply-object", uneval(retval[0]) == uneval(retval[1]) ? retval[0] : "");