|
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
|
2 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
3 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
5 |
|
6 #include "mozilla/dom/MessageEvent.h" |
|
7 #include "mozilla/dom/MessageEventBinding.h" |
|
8 #include "mozilla/dom/MessagePort.h" |
|
9 #include "mozilla/dom/MessagePortBinding.h" |
|
10 #include "mozilla/dom/MessagePortList.h" |
|
11 #include "mozilla/dom/UnionTypes.h" |
|
12 |
|
13 #include "mozilla/HoldDropJSObjects.h" |
|
14 #include "jsapi.h" |
|
15 |
|
16 namespace mozilla { |
|
17 namespace dom { |
|
18 |
|
19 NS_IMPL_CYCLE_COLLECTION_CLASS(MessageEvent) |
|
20 |
|
21 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(MessageEvent, Event) |
|
22 tmp->mData = JSVAL_VOID; |
|
23 NS_IMPL_CYCLE_COLLECTION_UNLINK(mWindowSource) |
|
24 NS_IMPL_CYCLE_COLLECTION_UNLINK(mPortSource) |
|
25 NS_IMPL_CYCLE_COLLECTION_UNLINK(mPorts) |
|
26 NS_IMPL_CYCLE_COLLECTION_UNLINK_END |
|
27 |
|
28 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(MessageEvent, Event) |
|
29 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mWindowSource) |
|
30 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPortSource) |
|
31 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPorts) |
|
32 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END |
|
33 |
|
34 NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(MessageEvent, Event) |
|
35 NS_IMPL_CYCLE_COLLECTION_TRACE_JSVAL_MEMBER_CALLBACK(mData) |
|
36 NS_IMPL_CYCLE_COLLECTION_TRACE_END |
|
37 |
|
38 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(MessageEvent) |
|
39 NS_INTERFACE_MAP_ENTRY(nsIDOMMessageEvent) |
|
40 NS_INTERFACE_MAP_END_INHERITING(Event) |
|
41 |
|
42 NS_IMPL_ADDREF_INHERITED(MessageEvent, Event) |
|
43 NS_IMPL_RELEASE_INHERITED(MessageEvent, Event) |
|
44 |
|
45 MessageEvent::MessageEvent(EventTarget* aOwner, |
|
46 nsPresContext* aPresContext, |
|
47 WidgetEvent* aEvent) |
|
48 : Event(aOwner, aPresContext, aEvent) |
|
49 , mData(JSVAL_VOID) |
|
50 { |
|
51 } |
|
52 |
|
53 MessageEvent::~MessageEvent() |
|
54 { |
|
55 mData = JSVAL_VOID; |
|
56 DropJSObjects(this); |
|
57 } |
|
58 |
|
59 JSObject* |
|
60 MessageEvent::WrapObject(JSContext* aCx) |
|
61 { |
|
62 return mozilla::dom::MessageEventBinding::Wrap(aCx, this); |
|
63 } |
|
64 |
|
65 NS_IMETHODIMP |
|
66 MessageEvent::GetData(JSContext* aCx, JS::MutableHandle<JS::Value> aData) |
|
67 { |
|
68 ErrorResult rv; |
|
69 GetData(aCx, aData, rv); |
|
70 return rv.ErrorCode(); |
|
71 } |
|
72 |
|
73 void |
|
74 MessageEvent::GetData(JSContext* aCx, JS::MutableHandle<JS::Value> aData, |
|
75 ErrorResult& aRv) |
|
76 { |
|
77 JS::ExposeValueToActiveJS(mData); |
|
78 aData.set(mData); |
|
79 if (!JS_WrapValue(aCx, aData)) { |
|
80 aRv.Throw(NS_ERROR_FAILURE); |
|
81 } |
|
82 } |
|
83 |
|
84 NS_IMETHODIMP |
|
85 MessageEvent::GetOrigin(nsAString& aOrigin) |
|
86 { |
|
87 aOrigin = mOrigin; |
|
88 return NS_OK; |
|
89 } |
|
90 |
|
91 NS_IMETHODIMP |
|
92 MessageEvent::GetLastEventId(nsAString& aLastEventId) |
|
93 { |
|
94 aLastEventId = mLastEventId; |
|
95 return NS_OK; |
|
96 } |
|
97 |
|
98 NS_IMETHODIMP |
|
99 MessageEvent::GetSource(nsIDOMWindow** aSource) |
|
100 { |
|
101 NS_IF_ADDREF(*aSource = mWindowSource); |
|
102 return NS_OK; |
|
103 } |
|
104 |
|
105 void |
|
106 MessageEvent::GetSource(Nullable<OwningWindowProxyOrMessagePort>& aValue) const |
|
107 { |
|
108 if (mWindowSource) { |
|
109 aValue.SetValue().SetAsWindowProxy() = mWindowSource; |
|
110 } else if (mPortSource) { |
|
111 aValue.SetValue().SetAsMessagePort() = mPortSource; |
|
112 } |
|
113 } |
|
114 |
|
115 /* static */ already_AddRefed<MessageEvent> |
|
116 MessageEvent::Constructor(const GlobalObject& aGlobal, |
|
117 JSContext* aCx, const nsAString& aType, |
|
118 const MessageEventInit& aParam, |
|
119 ErrorResult& aRv) |
|
120 { |
|
121 nsCOMPtr<EventTarget> t = do_QueryInterface(aGlobal.GetAsSupports()); |
|
122 nsRefPtr<MessageEvent> event = new MessageEvent(t, nullptr, nullptr); |
|
123 |
|
124 aRv = event->InitEvent(aType, aParam.mBubbles, aParam.mCancelable); |
|
125 if (aRv.Failed()) { |
|
126 return nullptr; |
|
127 } |
|
128 |
|
129 bool trusted = event->Init(t); |
|
130 event->SetTrusted(trusted); |
|
131 |
|
132 event->mData = aParam.mData; |
|
133 |
|
134 mozilla::HoldJSObjects(event.get()); |
|
135 |
|
136 if (aParam.mOrigin.WasPassed()) { |
|
137 event->mOrigin = aParam.mOrigin.Value(); |
|
138 } |
|
139 |
|
140 if (aParam.mLastEventId.WasPassed()) { |
|
141 event->mLastEventId = aParam.mLastEventId.Value(); |
|
142 } |
|
143 |
|
144 if (!aParam.mSource.IsNull()) { |
|
145 if (aParam.mSource.Value().IsWindowProxy()) { |
|
146 event->mWindowSource = aParam.mSource.Value().GetAsWindowProxy(); |
|
147 } else { |
|
148 event->mPortSource = aParam.mSource.Value().GetAsMessagePort(); |
|
149 } |
|
150 |
|
151 MOZ_ASSERT(event->mWindowSource || event->mPortSource); |
|
152 } |
|
153 |
|
154 if (aParam.mPorts.WasPassed() && !aParam.mPorts.Value().IsNull()) { |
|
155 nsTArray<nsRefPtr<MessagePortBase>> ports; |
|
156 for (uint32_t i = 0, len = aParam.mPorts.Value().Value().Length(); i < len; ++i) { |
|
157 ports.AppendElement(aParam.mPorts.Value().Value()[i].get()); |
|
158 } |
|
159 |
|
160 event->mPorts = new MessagePortList(static_cast<EventBase*>(event), ports); |
|
161 } |
|
162 |
|
163 return event.forget(); |
|
164 } |
|
165 |
|
166 NS_IMETHODIMP |
|
167 MessageEvent::InitMessageEvent(const nsAString& aType, |
|
168 bool aCanBubble, |
|
169 bool aCancelable, |
|
170 JS::Handle<JS::Value> aData, |
|
171 const nsAString& aOrigin, |
|
172 const nsAString& aLastEventId, |
|
173 nsIDOMWindow* aSource) |
|
174 { |
|
175 nsresult rv = Event::InitEvent(aType, aCanBubble, aCancelable); |
|
176 NS_ENSURE_SUCCESS(rv, rv); |
|
177 |
|
178 mData = aData; |
|
179 mozilla::HoldJSObjects(this); |
|
180 mOrigin = aOrigin; |
|
181 mLastEventId = aLastEventId; |
|
182 mWindowSource = aSource; |
|
183 |
|
184 return NS_OK; |
|
185 } |
|
186 |
|
187 void |
|
188 MessageEvent::SetPorts(MessagePortList* aPorts) |
|
189 { |
|
190 MOZ_ASSERT(!mPorts && aPorts); |
|
191 mPorts = aPorts; |
|
192 } |
|
193 |
|
194 } // namespace dom |
|
195 } // namespace mozilla |
|
196 |
|
197 using namespace mozilla; |
|
198 using namespace mozilla::dom; |
|
199 |
|
200 nsresult |
|
201 NS_NewDOMMessageEvent(nsIDOMEvent** aInstancePtrResult, |
|
202 EventTarget* aOwner, |
|
203 nsPresContext* aPresContext, |
|
204 WidgetEvent* aEvent) |
|
205 { |
|
206 MessageEvent* it = new MessageEvent(aOwner, aPresContext, aEvent); |
|
207 NS_ADDREF(it); |
|
208 *aInstancePtrResult = static_cast<Event*>(it); |
|
209 return NS_OK; |
|
210 } |