michael@0: /* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 8; -*- */ michael@0: /* vim: set sw=4 ts=8 et tw=80 : */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include "nsInProcessTabChildGlobal.h" michael@0: #include "nsContentUtils.h" michael@0: #include "nsIScriptSecurityManager.h" michael@0: #include "nsIInterfaceRequestorUtils.h" michael@0: #include "nsIComponentManager.h" michael@0: #include "nsIServiceManager.h" michael@0: #include "nsIJSRuntimeService.h" michael@0: #include "nsComponentManagerUtils.h" michael@0: #include "nsNetUtil.h" michael@0: #include "nsScriptLoader.h" michael@0: #include "nsFrameLoader.h" michael@0: #include "xpcpublic.h" michael@0: #include "nsIMozBrowserFrame.h" michael@0: #include "nsDOMClassInfoID.h" michael@0: #include "mozilla/EventDispatcher.h" michael@0: #include "mozilla/dom/StructuredCloneUtils.h" michael@0: #include "js/StructuredClone.h" michael@0: michael@0: using mozilla::dom::StructuredCloneData; michael@0: using mozilla::dom::StructuredCloneClosure; michael@0: using namespace mozilla; michael@0: michael@0: bool michael@0: nsInProcessTabChildGlobal::DoSendBlockingMessage(JSContext* aCx, michael@0: const nsAString& aMessage, michael@0: const dom::StructuredCloneData& aData, michael@0: JS::Handle aCpows, michael@0: nsIPrincipal* aPrincipal, michael@0: InfallibleTArray* aJSONRetVal, michael@0: bool aIsSync) michael@0: { michael@0: nsTArray > asyncMessages; michael@0: asyncMessages.SwapElements(mASyncMessages); michael@0: uint32_t len = asyncMessages.Length(); michael@0: for (uint32_t i = 0; i < len; ++i) { michael@0: nsCOMPtr async = asyncMessages[i]; michael@0: async->Run(); michael@0: } michael@0: if (mChromeMessageManager) { michael@0: SameProcessCpowHolder cpows(js::GetRuntime(aCx), aCpows); michael@0: nsRefPtr mm = mChromeMessageManager; michael@0: mm->ReceiveMessage(mOwner, aMessage, true, &aData, &cpows, aPrincipal, michael@0: aJSONRetVal); michael@0: } michael@0: return true; michael@0: } michael@0: michael@0: class nsAsyncMessageToParent : public nsSameProcessAsyncMessageBase, michael@0: public nsRunnable michael@0: { michael@0: public: michael@0: nsAsyncMessageToParent(JSContext* aCx, michael@0: nsInProcessTabChildGlobal* aTabChild, michael@0: const nsAString& aMessage, michael@0: const StructuredCloneData& aData, michael@0: JS::Handle aCpows, michael@0: nsIPrincipal* aPrincipal) michael@0: : nsSameProcessAsyncMessageBase(aCx, aMessage, aData, aCpows, aPrincipal), michael@0: mTabChild(aTabChild), mRun(false) michael@0: { michael@0: } michael@0: michael@0: NS_IMETHOD Run() michael@0: { michael@0: if (mRun) { michael@0: return NS_OK; michael@0: } michael@0: michael@0: mRun = true; michael@0: mTabChild->mASyncMessages.RemoveElement(this); michael@0: ReceiveMessage(mTabChild->mOwner, mTabChild->mChromeMessageManager); michael@0: return NS_OK; michael@0: } michael@0: nsRefPtr mTabChild; michael@0: // True if this runnable has already been called. This can happen if DoSendSyncMessage michael@0: // is called while waiting for an asynchronous message send. michael@0: bool mRun; michael@0: }; michael@0: michael@0: bool michael@0: nsInProcessTabChildGlobal::DoSendAsyncMessage(JSContext* aCx, michael@0: const nsAString& aMessage, michael@0: const StructuredCloneData& aData, michael@0: JS::Handle aCpows, michael@0: nsIPrincipal* aPrincipal) michael@0: { michael@0: nsCOMPtr ev = michael@0: new nsAsyncMessageToParent(aCx, this, aMessage, aData, aCpows, aPrincipal); michael@0: mASyncMessages.AppendElement(ev); michael@0: NS_DispatchToCurrentThread(ev); michael@0: return true; michael@0: } michael@0: michael@0: nsInProcessTabChildGlobal::nsInProcessTabChildGlobal(nsIDocShell* aShell, michael@0: nsIContent* aOwner, michael@0: nsFrameMessageManager* aChrome) michael@0: : mDocShell(aShell), mInitialized(false), mLoadingScript(false), michael@0: mOwner(aOwner), mChromeMessageManager(aChrome) michael@0: { michael@0: michael@0: // If owner corresponds to an