Line data Source code
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/. */
6 :
7 : #include "mozilla/dom/MessageEvent.h"
8 : #include "mozilla/dom/MessageEventBinding.h"
9 : #include "mozilla/dom/MessagePort.h"
10 : #include "mozilla/dom/MessagePortBinding.h"
11 : #include "mozilla/dom/workers/bindings/ServiceWorker.h"
12 :
13 : #include "mozilla/HoldDropJSObjects.h"
14 : #include "jsapi.h"
15 : #include "nsGlobalWindow.h" // So we can assign an nsGlobalWindow* to mWindowSource
16 :
17 : namespace mozilla {
18 : namespace dom {
19 :
20 : NS_IMPL_CYCLE_COLLECTION_CLASS(MessageEvent)
21 :
22 0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(MessageEvent, Event)
23 0 : tmp->mData.setUndefined();
24 0 : NS_IMPL_CYCLE_COLLECTION_UNLINK(mWindowSource)
25 0 : NS_IMPL_CYCLE_COLLECTION_UNLINK(mPortSource)
26 0 : NS_IMPL_CYCLE_COLLECTION_UNLINK(mServiceWorkerSource)
27 0 : NS_IMPL_CYCLE_COLLECTION_UNLINK(mPorts)
28 0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_END
29 :
30 0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(MessageEvent, Event)
31 0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mWindowSource)
32 0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPortSource)
33 0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mServiceWorkerSource)
34 0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPorts)
35 0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
36 :
37 0 : NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(MessageEvent, Event)
38 0 : NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mData)
39 0 : NS_IMPL_CYCLE_COLLECTION_TRACE_END
40 :
41 0 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(MessageEvent)
42 0 : NS_INTERFACE_MAP_END_INHERITING(Event)
43 :
44 0 : NS_IMPL_ADDREF_INHERITED(MessageEvent, Event)
45 0 : NS_IMPL_RELEASE_INHERITED(MessageEvent, Event)
46 :
47 0 : MessageEvent::MessageEvent(EventTarget* aOwner,
48 : nsPresContext* aPresContext,
49 0 : WidgetEvent* aEvent)
50 : : Event(aOwner, aPresContext, aEvent)
51 0 : , mData(JS::UndefinedValue())
52 : {
53 0 : }
54 :
55 0 : MessageEvent::~MessageEvent()
56 : {
57 0 : mData.setUndefined();
58 0 : DropJSObjects(this);
59 0 : }
60 :
61 : JSObject*
62 0 : MessageEvent::WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
63 : {
64 0 : return mozilla::dom::MessageEventBinding::Wrap(aCx, this, aGivenProto);
65 : }
66 :
67 : void
68 0 : MessageEvent::GetData(JSContext* aCx, JS::MutableHandle<JS::Value> aData,
69 : ErrorResult& aRv)
70 : {
71 0 : aData.set(mData);
72 0 : if (!JS_WrapValue(aCx, aData)) {
73 0 : aRv.Throw(NS_ERROR_FAILURE);
74 : }
75 0 : }
76 :
77 : void
78 0 : MessageEvent::GetOrigin(nsAString& aOrigin) const
79 : {
80 0 : aOrigin = mOrigin;
81 0 : }
82 :
83 : void
84 0 : MessageEvent::GetLastEventId(nsAString& aLastEventId) const
85 : {
86 0 : aLastEventId = mLastEventId;
87 0 : }
88 :
89 : void
90 0 : MessageEvent::GetSource(Nullable<OwningWindowProxyOrMessagePortOrServiceWorker>& aValue) const
91 : {
92 0 : if (mWindowSource) {
93 0 : aValue.SetValue().SetAsWindowProxy() = mWindowSource;
94 0 : } else if (mPortSource) {
95 0 : aValue.SetValue().SetAsMessagePort() = mPortSource;
96 0 : } else if (mServiceWorkerSource) {
97 0 : aValue.SetValue().SetAsServiceWorker() = mServiceWorkerSource;
98 : }
99 0 : }
100 :
101 : /* static */ already_AddRefed<MessageEvent>
102 0 : MessageEvent::Constructor(const GlobalObject& aGlobal,
103 : const nsAString& aType,
104 : const MessageEventInit& aParam,
105 : ErrorResult& aRv)
106 : {
107 0 : nsCOMPtr<EventTarget> t = do_QueryInterface(aGlobal.GetAsSupports());
108 0 : return Constructor(t, aType, aParam);
109 : }
110 :
111 : /* static */ already_AddRefed<MessageEvent>
112 0 : MessageEvent::Constructor(EventTarget* aEventTarget,
113 : const nsAString& aType,
114 : const MessageEventInit& aParam)
115 : {
116 0 : RefPtr<MessageEvent> event = new MessageEvent(aEventTarget, nullptr, nullptr);
117 :
118 0 : event->InitEvent(aType, aParam.mBubbles, aParam.mCancelable);
119 0 : bool trusted = event->Init(aEventTarget);
120 0 : event->SetTrusted(trusted);
121 :
122 0 : event->mData = aParam.mData;
123 :
124 0 : mozilla::HoldJSObjects(event.get());
125 :
126 0 : event->mOrigin = aParam.mOrigin;
127 0 : event->mLastEventId = aParam.mLastEventId;
128 :
129 0 : if (!aParam.mSource.IsNull()) {
130 0 : if (aParam.mSource.Value().IsWindowProxy()) {
131 0 : event->mWindowSource = aParam.mSource.Value().GetAsWindowProxy();
132 0 : } else if (aParam.mSource.Value().IsMessagePort()) {
133 0 : event->mPortSource = aParam.mSource.Value().GetAsMessagePort();
134 : } else {
135 0 : event->mServiceWorkerSource = aParam.mSource.Value().GetAsServiceWorker();
136 : }
137 :
138 0 : MOZ_ASSERT(event->mWindowSource || event->mPortSource || event->mServiceWorkerSource);
139 : }
140 :
141 0 : event->mPorts.AppendElements(aParam.mPorts);
142 :
143 0 : return event.forget();
144 : }
145 :
146 : void
147 0 : MessageEvent::InitMessageEvent(JSContext* aCx, const nsAString& aType,
148 : bool aCanBubble, bool aCancelable,
149 : JS::Handle<JS::Value> aData,
150 : const nsAString& aOrigin,
151 : const nsAString& aLastEventId,
152 : const Nullable<WindowProxyOrMessagePortOrServiceWorker>& aSource,
153 : const Sequence<OwningNonNull<MessagePort>>& aPorts)
154 : {
155 0 : NS_ENSURE_TRUE_VOID(!mEvent->mFlags.mIsBeingDispatched);
156 :
157 0 : Event::InitEvent(aType, aCanBubble, aCancelable);
158 0 : mData = aData;
159 0 : mozilla::HoldJSObjects(this);
160 0 : mOrigin = aOrigin;
161 0 : mLastEventId = aLastEventId;
162 :
163 0 : mWindowSource = nullptr;
164 0 : mPortSource = nullptr;
165 0 : mServiceWorkerSource = nullptr;
166 :
167 0 : if (!aSource.IsNull()) {
168 0 : if (aSource.Value().IsWindowProxy()) {
169 0 : mWindowSource = aSource.Value().GetAsWindowProxy();
170 0 : } else if (aSource.Value().IsMessagePort()) {
171 0 : mPortSource = &aSource.Value().GetAsMessagePort();
172 : } else {
173 0 : mServiceWorkerSource = &aSource.Value().GetAsServiceWorker();
174 : }
175 : }
176 :
177 0 : mPorts.Clear();
178 0 : mPorts.AppendElements(aPorts);
179 0 : MessageEventBinding::ClearCachedPortsValue(this);
180 : }
181 :
182 : void
183 0 : MessageEvent::GetPorts(nsTArray<RefPtr<MessagePort>>& aPorts)
184 : {
185 0 : aPorts = mPorts;
186 0 : }
187 :
188 : } // namespace dom
189 : } // namespace mozilla
|