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_MULTI_ZONE_JSHOLDER_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() {
55 JSObject
* MessageEvent::WrapObjectInternal(JSContext
* aCx
,
56 JS::Handle
<JSObject
*> aGivenProto
) {
57 return mozilla::dom::MessageEvent_Binding::Wrap(aCx
, this, aGivenProto
);
60 void MessageEvent::GetData(JSContext
* aCx
, JS::MutableHandle
<JS::Value
> aData
,
63 if (!JS_WrapValue(aCx
, aData
)) {
64 aRv
.Throw(NS_ERROR_FAILURE
);
68 void MessageEvent::GetOrigin(nsAString
& aOrigin
) const { aOrigin
= mOrigin
; }
70 void MessageEvent::GetLastEventId(nsAString
& aLastEventId
) const {
71 aLastEventId
= mLastEventId
;
74 void MessageEvent::GetSource(
75 Nullable
<OwningWindowProxyOrMessagePortOrServiceWorker
>& aValue
) const {
77 aValue
.SetValue().SetAsWindowProxy() = mWindowSource
;
78 } else if (mPortSource
) {
79 aValue
.SetValue().SetAsMessagePort() = mPortSource
;
80 } else if (mServiceWorkerSource
) {
81 aValue
.SetValue().SetAsServiceWorker() = mServiceWorkerSource
;
86 already_AddRefed
<MessageEvent
> MessageEvent::Constructor(
87 const GlobalObject
& aGlobal
, const nsAString
& aType
,
88 const MessageEventInit
& aParam
) {
89 nsCOMPtr
<EventTarget
> t
= do_QueryInterface(aGlobal
.GetAsSupports());
90 return Constructor(t
, aType
, aParam
);
94 already_AddRefed
<MessageEvent
> MessageEvent::Constructor(
95 EventTarget
* aEventTarget
, const nsAString
& aType
,
96 const MessageEventInit
& aParam
) {
97 RefPtr
<MessageEvent
> event
= new MessageEvent(aEventTarget
, nullptr, nullptr);
99 event
->InitEvent(aType
, aParam
.mBubbles
, aParam
.mCancelable
);
100 bool trusted
= event
->Init(aEventTarget
);
101 event
->SetTrusted(trusted
);
103 event
->mData
= aParam
.mData
;
105 mozilla::HoldJSObjects(event
.get());
107 event
->mOrigin
= aParam
.mOrigin
;
108 event
->mLastEventId
= aParam
.mLastEventId
;
110 if (!aParam
.mSource
.IsNull()) {
111 if (aParam
.mSource
.Value().IsWindowProxy()) {
112 event
->mWindowSource
= aParam
.mSource
.Value().GetAsWindowProxy().get();
113 } else if (aParam
.mSource
.Value().IsMessagePort()) {
114 event
->mPortSource
= aParam
.mSource
.Value().GetAsMessagePort();
116 event
->mServiceWorkerSource
= aParam
.mSource
.Value().GetAsServiceWorker();
119 MOZ_ASSERT(event
->mWindowSource
|| event
->mPortSource
||
120 event
->mServiceWorkerSource
);
123 event
->mPorts
.AppendElements(aParam
.mPorts
);
125 return event
.forget();
128 void MessageEvent::InitMessageEvent(
129 JSContext
* aCx
, const nsAString
& aType
, mozilla::CanBubble aCanBubble
,
130 mozilla::Cancelable aCancelable
, JS::Handle
<JS::Value
> aData
,
131 const nsAString
& aOrigin
, const nsAString
& aLastEventId
,
132 const Nullable
<WindowProxyOrMessagePortOrServiceWorker
>& aSource
,
133 const Sequence
<OwningNonNull
<MessagePort
>>& aPorts
) {
134 NS_ENSURE_TRUE_VOID(!mEvent
->mFlags
.mIsBeingDispatched
);
136 Event::InitEvent(aType
, aCanBubble
, aCancelable
);
138 mozilla::HoldJSObjects(this);
140 mLastEventId
= aLastEventId
;
142 mWindowSource
= nullptr;
143 mPortSource
= nullptr;
144 mServiceWorkerSource
= nullptr;
146 if (!aSource
.IsNull()) {
147 if (aSource
.Value().IsWindowProxy()) {
148 mWindowSource
= aSource
.Value().GetAsWindowProxy().get();
149 } else if (aSource
.Value().IsMessagePort()) {
150 mPortSource
= &aSource
.Value().GetAsMessagePort();
152 mServiceWorkerSource
= &aSource
.Value().GetAsServiceWorker();
157 mPorts
.AppendElements(aPorts
);
158 MessageEvent_Binding::ClearCachedPortsValue(this);
161 void MessageEvent::GetPorts(nsTArray
<RefPtr
<MessagePort
>>& aPorts
) {
162 aPorts
= mPorts
.Clone();
165 } // namespace mozilla::dom