1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "mozilla/dom/MessageEvent.h"
8 #include "mozilla/dom/BrowsingContext.h"
9 #include "mozilla/dom/MessageEventBinding.h"
10 #include "mozilla/dom/MessagePort.h"
11 #include "mozilla/dom/MessagePortBinding.h"
12 #include "mozilla/dom/ServiceWorker.h"
14 #include "mozilla/HoldDropJSObjects.h"
17 namespace mozilla::dom
{
19 NS_IMPL_CYCLE_COLLECTION_CLASS(MessageEvent
)
21 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(MessageEvent
, Event
)
22 tmp
->mData
.setUndefined();
23 NS_IMPL_CYCLE_COLLECTION_UNLINK(mWindowSource
)
24 NS_IMPL_CYCLE_COLLECTION_UNLINK(mPortSource
)
25 NS_IMPL_CYCLE_COLLECTION_UNLINK(mServiceWorkerSource
)
26 NS_IMPL_CYCLE_COLLECTION_UNLINK(mPorts
)
27 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
29 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(MessageEvent
, Event
)
30 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mWindowSource
)
31 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPortSource
)
32 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mServiceWorkerSource
)
33 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPorts
)
34 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
36 NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(MessageEvent
, Event
)
37 NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mData
)
38 NS_IMPL_CYCLE_COLLECTION_TRACE_END
40 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(MessageEvent
)
41 NS_INTERFACE_MAP_END_INHERITING(Event
)
43 NS_IMPL_ADDREF_INHERITED(MessageEvent
, Event
)
44 NS_IMPL_RELEASE_INHERITED(MessageEvent
, Event
)
46 MessageEvent::MessageEvent(EventTarget
* aOwner
, nsPresContext
* aPresContext
,
48 : Event(aOwner
, aPresContext
, aEvent
), mData(JS::UndefinedValue()) {}
50 MessageEvent::~MessageEvent() { DropJSObjects(this); }
52 JSObject
* MessageEvent::WrapObjectInternal(JSContext
* aCx
,
53 JS::Handle
<JSObject
*> aGivenProto
) {
54 return mozilla::dom::MessageEvent_Binding::Wrap(aCx
, this, aGivenProto
);
57 void MessageEvent::GetData(JSContext
* aCx
, JS::MutableHandle
<JS::Value
> aData
,
60 if (!JS_WrapValue(aCx
, aData
)) {
61 aRv
.Throw(NS_ERROR_FAILURE
);
65 void MessageEvent::GetOrigin(nsAString
& aOrigin
) const { aOrigin
= mOrigin
; }
67 void MessageEvent::GetLastEventId(nsAString
& aLastEventId
) const {
68 aLastEventId
= mLastEventId
;
71 void MessageEvent::GetSource(
72 Nullable
<OwningWindowProxyOrMessagePortOrServiceWorker
>& aValue
) const {
74 aValue
.SetValue().SetAsWindowProxy() = mWindowSource
;
75 } else if (mPortSource
) {
76 aValue
.SetValue().SetAsMessagePort() = mPortSource
;
77 } else if (mServiceWorkerSource
) {
78 aValue
.SetValue().SetAsServiceWorker() = mServiceWorkerSource
;
83 already_AddRefed
<MessageEvent
> MessageEvent::Constructor(
84 const GlobalObject
& aGlobal
, const nsAString
& aType
,
85 const MessageEventInit
& aParam
) {
86 nsCOMPtr
<EventTarget
> t
= do_QueryInterface(aGlobal
.GetAsSupports());
87 return Constructor(t
, aType
, aParam
);
91 already_AddRefed
<MessageEvent
> MessageEvent::Constructor(
92 EventTarget
* aEventTarget
, const nsAString
& aType
,
93 const MessageEventInit
& aParam
) {
94 RefPtr
<MessageEvent
> event
= new MessageEvent(aEventTarget
, nullptr, nullptr);
96 event
->InitEvent(aType
, aParam
.mBubbles
, aParam
.mCancelable
);
97 bool trusted
= event
->Init(aEventTarget
);
98 event
->SetTrusted(trusted
);
100 event
->mData
= aParam
.mData
;
102 mozilla::HoldJSObjects(event
.get());
104 event
->mOrigin
= aParam
.mOrigin
;
105 event
->mLastEventId
= aParam
.mLastEventId
;
107 if (!aParam
.mSource
.IsNull()) {
108 if (aParam
.mSource
.Value().IsWindowProxy()) {
109 event
->mWindowSource
= aParam
.mSource
.Value().GetAsWindowProxy().get();
110 } else if (aParam
.mSource
.Value().IsMessagePort()) {
111 event
->mPortSource
= aParam
.mSource
.Value().GetAsMessagePort();
113 event
->mServiceWorkerSource
= aParam
.mSource
.Value().GetAsServiceWorker();
116 MOZ_ASSERT(event
->mWindowSource
|| event
->mPortSource
||
117 event
->mServiceWorkerSource
);
120 event
->mPorts
.AppendElements(aParam
.mPorts
);
122 return event
.forget();
125 void MessageEvent::InitMessageEvent(
126 JSContext
* aCx
, const nsAString
& aType
, mozilla::CanBubble aCanBubble
,
127 mozilla::Cancelable aCancelable
, JS::Handle
<JS::Value
> aData
,
128 const nsAString
& aOrigin
, const nsAString
& aLastEventId
,
129 const Nullable
<WindowProxyOrMessagePortOrServiceWorker
>& aSource
,
130 const Sequence
<OwningNonNull
<MessagePort
>>& aPorts
) {
131 NS_ENSURE_TRUE_VOID(!mEvent
->mFlags
.mIsBeingDispatched
);
133 Event::InitEvent(aType
, aCanBubble
, aCancelable
);
135 mozilla::HoldJSObjects(this);
137 mLastEventId
= aLastEventId
;
139 mWindowSource
= nullptr;
140 mPortSource
= nullptr;
141 mServiceWorkerSource
= nullptr;
143 if (!aSource
.IsNull()) {
144 if (aSource
.Value().IsWindowProxy()) {
145 mWindowSource
= aSource
.Value().GetAsWindowProxy().get();
146 } else if (aSource
.Value().IsMessagePort()) {
147 mPortSource
= &aSource
.Value().GetAsMessagePort();
149 mServiceWorkerSource
= &aSource
.Value().GetAsServiceWorker();
154 mPorts
.AppendElements(aPorts
);
155 MessageEvent_Binding::ClearCachedPortsValue(this);
158 void MessageEvent::GetPorts(nsTArray
<RefPtr
<MessagePort
>>& aPorts
) {
159 aPorts
= mPorts
.Clone();
162 } // namespace mozilla::dom