summaryrefslogtreecommitdiffstats
path: root/dom/base/PostMessageEvent.h
blob: 66dc029d1d62c2f788996efcd0a9a4025decb00a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
/* -*- 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<nsID>& 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<JS::Value> aMessage,
             JS::Handle<JS::Value> aTransfer,
             const JS::CloneDataPolicy& aClonePolicy, ErrorResult& aError) {
    mHolder.construct<StructuredCloneHolder>(
        StructuredCloneHolder::CloningSupported,
        StructuredCloneHolder::TransferringSupported,
        JS::StructuredCloneScope::SameProcess);
    mHolder.ref<StructuredCloneHolder>().Write(aCx, aMessage, aTransfer,
                                               aClonePolicy, aError);
  }
  void UnpackFrom(const ClonedOrErrorMessageData& aMessageData) {
    if (aMessageData.type() != ClonedOrErrorMessageData::TClonedMessageData) {
      return;
    }

    mHolder.construct<ipc::StructuredCloneData>();
    // FIXME Want to steal!
    //       See https://bugzilla.mozilla.org/show_bug.cgi?id=1516349.
    mHolder.ref<ipc::StructuredCloneData>().CopyFromClonedMessageDataForChild(
        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<nsID>& aCallerAgentClusterId);
  ~PostMessageEvent();

  void Dispatch(nsGlobalWindowInner* aTargetWindow, Event* aEvent);

  void DispatchError(JSContext* aCx, nsGlobalWindowInner* aTargetWindow,
                     mozilla::dom::EventTarget* aEventTarget);

  RefPtr<BrowsingContext> mSource;
  nsString mCallerOrigin;
  RefPtr<nsGlobalWindowOuter> mTargetWindow;
  nsCOMPtr<nsIPrincipal> 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<StructuredCloneHolder, ipc::StructuredCloneData> mHolder;
  uint64_t mCallerWindowID;
  const Maybe<nsID> mCallerAgentClusterId;
  nsCOMPtr<nsIURI> mCallerURI;
  // if callerURI is null, then we can use script location for reporting errors
  // to console
  const Maybe<nsCString> 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