MessageEvent.cpp (5584B)
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 9 #include "jsapi.h" 10 #include "mozilla/HoldDropJSObjects.h" 11 #include "mozilla/dom/BrowsingContext.h" 12 #include "mozilla/dom/MessageEventBinding.h" 13 #include "mozilla/dom/MessagePort.h" 14 #include "mozilla/dom/MessagePortBinding.h" 15 #include "mozilla/dom/ServiceWorker.h" 16 17 namespace mozilla::dom { 18 19 NS_IMPL_CYCLE_COLLECTION_CLASS(MessageEvent) 20 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 28 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 35 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 39 40 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(MessageEvent) 41 NS_INTERFACE_MAP_END_INHERITING(Event) 42 43 NS_IMPL_ADDREF_INHERITED(MessageEvent, Event) 44 NS_IMPL_RELEASE_INHERITED(MessageEvent, Event) 45 46 MessageEvent::MessageEvent(EventTarget* aOwner, nsPresContext* aPresContext, 47 WidgetEvent* aEvent) 48 : Event(aOwner, aPresContext, aEvent), mData(JS::UndefinedValue()) {} 49 50 MessageEvent::~MessageEvent() { DropJSObjects(this); } 51 52 JSObject* MessageEvent::WrapObjectInternal(JSContext* aCx, 53 JS::Handle<JSObject*> aGivenProto) { 54 return mozilla::dom::MessageEvent_Binding::Wrap(aCx, this, aGivenProto); 55 } 56 57 void MessageEvent::GetData(JSContext* aCx, JS::MutableHandle<JS::Value> aData, 58 ErrorResult& aRv) { 59 aData.set(mData); 60 if (!JS_WrapValue(aCx, aData)) { 61 aRv.Throw(NS_ERROR_FAILURE); 62 } 63 } 64 65 void MessageEvent::GetOrigin(nsAString& aOrigin) const { aOrigin = mOrigin; } 66 67 void MessageEvent::GetLastEventId(nsAString& aLastEventId) const { 68 aLastEventId = mLastEventId; 69 } 70 71 void MessageEvent::GetSource( 72 Nullable<OwningWindowProxyOrMessagePortOrServiceWorker>& aValue) const { 73 if (mWindowSource) { 74 aValue.SetValue().SetAsWindowProxy() = mWindowSource; 75 } else if (mPortSource) { 76 aValue.SetValue().SetAsMessagePort() = mPortSource; 77 } else if (mServiceWorkerSource) { 78 aValue.SetValue().SetAsServiceWorker() = mServiceWorkerSource; 79 } 80 } 81 82 /* static */ 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); 88 } 89 90 /* static */ 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); 95 96 event->InitEvent(aType, aParam.mBubbles, aParam.mCancelable); 97 bool trusted = event->Init(aEventTarget); 98 event->SetTrusted(trusted); 99 100 event->mData = aParam.mData; 101 102 mozilla::HoldJSObjects(event.get()); 103 104 event->mOrigin = aParam.mOrigin; 105 event->mLastEventId = aParam.mLastEventId; 106 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(); 112 } else { 113 event->mServiceWorkerSource = aParam.mSource.Value().GetAsServiceWorker(); 114 } 115 116 MOZ_ASSERT(event->mWindowSource || event->mPortSource || 117 event->mServiceWorkerSource); 118 } 119 120 event->mPorts.AppendElements(aParam.mPorts); 121 122 return event.forget(); 123 } 124 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); 132 133 Event::InitEvent(aType, aCanBubble, aCancelable); 134 mData = aData; 135 mozilla::HoldJSObjects(this); 136 mOrigin = aOrigin; 137 mLastEventId = aLastEventId; 138 139 mWindowSource = nullptr; 140 mPortSource = nullptr; 141 mServiceWorkerSource = nullptr; 142 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(); 148 } else { 149 mServiceWorkerSource = &aSource.Value().GetAsServiceWorker(); 150 } 151 } 152 153 mPorts.Clear(); 154 mPorts.AppendElements(aPorts); 155 MessageEvent_Binding::ClearCachedPortsValue(this); 156 } 157 158 void MessageEvent::GetPorts(nsTArray<RefPtr<MessagePort>>& aPorts) { 159 aPorts = mPorts.Clone(); 160 } 161 162 } // namespace mozilla::dom