/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef mozilla_dom_PostMessageEvent_h #define mozilla_dom_PostMessageEvent_h #include "js/StructuredClone.h" #include "js/TypeDecls.h" #include "mozilla/dom/DOMTypes.h" #include "mozilla/dom/ipc/StructuredCloneData.h" #include "mozilla/dom/StructuredCloneHolder.h" #include "nsCOMPtr.h" #include "mozilla/Maybe.h" #include "mozilla/MaybeOneOf.h" #include "mozilla/RefPtr.h" #include "nsThreadUtils.h" class nsGlobalWindowOuter; class nsGlobalWindowInner; class nsIPrincipal; class nsIURI; namespace mozilla { class ErrorResult; namespace dom { class BrowsingContext; class Event; class EventTarget; /** * Class used to represent events generated by calls to Window.postMessage, * which asynchronously creates and dispatches events. */ class PostMessageEvent final : public Runnable { public: NS_DECL_NSIRUNNABLE // aCallerWindowID should not be 0. PostMessageEvent(BrowsingContext* aSource, const nsAString& aCallerOrigin, nsGlobalWindowOuter* aTargetWindow, nsIPrincipal* aProvidedPrincipal, uint64_t aCallerWindowID, nsIURI* aCallerURI, const nsCString& aScriptLocation, const Maybe& aCallerAgentClusterId) : PostMessageEvent(aSource, aCallerOrigin, aTargetWindow, aProvidedPrincipal, aCallerWindowID, aCallerURI, aScriptLocation, false, aCallerAgentClusterId) {} // To be used when the caller's window lives in a different process. PostMessageEvent(BrowsingContext* aSource, const nsAString& aCallerOrigin, nsGlobalWindowOuter* aTargetWindow, nsIPrincipal* aProvidedPrincipal, uint64_t aCallerWindowID, nsIURI* aCallerURI, const nsCString& aScriptLocation, bool aIsFromPrivateWindow) : PostMessageEvent(aSource, aCallerOrigin, aTargetWindow, aProvidedPrincipal, aCallerWindowID, aCallerURI, aScriptLocation, aIsFromPrivateWindow, Nothing()) {} void Write(JSContext* aCx, JS::Handle aMessage, JS::Handle aTransfer, const JS::CloneDataPolicy& aClonePolicy, ErrorResult& aError) { mHolder.construct( StructuredCloneHolder::CloningSupported, StructuredCloneHolder::TransferringSupported, JS::StructuredCloneScope::SameProcess); mHolder.ref().Write(aCx, aMessage, aTransfer, aClonePolicy, aError); } void UnpackFrom(const ClonedOrErrorMessageData& aMessageData) { if (aMessageData.type() != ClonedOrErrorMessageData::TClonedMessageData) { return; } mHolder.construct(); // FIXME Want to steal! // See https://bugzilla.mozilla.org/show_bug.cgi?id=1516349. mHolder.ref().CopyFromClonedMessageData( aMessageData); } void DispatchToTargetThread(ErrorResult& aError); private: PostMessageEvent(BrowsingContext* aSource, const nsAString& aCallerOrigin, nsGlobalWindowOuter* aTargetWindow, nsIPrincipal* aProvidedPrincipal, uint64_t aCallerWindowID, nsIURI* aCallerURI, const nsCString& aScriptLocation, bool aIsFromPrivateWindow, const Maybe& aCallerAgentClusterId); ~PostMessageEvent(); MOZ_CAN_RUN_SCRIPT void Dispatch(nsGlobalWindowInner* aTargetWindow, Event* aEvent); // TODO: Convert this to MOZ_CAN_RUN_SCRIPT (bug 1415230) MOZ_CAN_RUN_SCRIPT_BOUNDARY void DispatchError( JSContext* aCx, nsGlobalWindowInner* aTargetWindow, mozilla::dom::EventTarget* aEventTarget); RefPtr mSource; nsString mCallerOrigin; RefPtr mTargetWindow; nsCOMPtr mProvidedPrincipal; // If the postMessage call was made on a WindowProxy whose Window lives in a // separate process then mHolder will contain a StructuredCloneData, else // it'll contain a StructuredCloneHolder. MaybeOneOf mHolder; uint64_t mCallerWindowID; const Maybe mCallerAgentClusterId; nsCOMPtr mCallerURI; // if callerURI is null, then we can use script location for reporting errors // to console const Maybe mScriptLocation; // This is only set to a relevant value if mCallerWindowID doesn't contain a // value. bool mIsFromPrivateWindow; }; } // namespace dom } // namespace mozilla #endif // mozilla_dom_PostMessageEvent_h