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 #ifndef mozilla_dom_workers_serviceworkerevents_h__ 8 #define mozilla_dom_workers_serviceworkerevents_h__ 9 10 #include "mozilla/dom/Event.h" 11 #include "mozilla/dom/ExtendableEventBinding.h" 12 #include "mozilla/dom/ExtendableMessageEventBinding.h" 13 #include "mozilla/dom/FetchEventBinding.h" 14 #include "mozilla/dom/File.h" 15 #include "mozilla/dom/Promise.h" 16 #include "mozilla/dom/Response.h" 17 #include "mozilla/dom/workers/bindings/ServiceWorker.h" 18 #include "mozilla/dom/workers/Workers.h" 19 20 #include "nsProxyRelease.h" 21 #include "nsContentUtils.h" 22 23 class nsIInterceptedChannel; 24 25 namespace mozilla { 26 namespace dom { 27 class Blob; 28 class MessagePort; 29 class Request; 30 class ResponseOrPromise; 31 32 struct PushEventInit; 33 } // namespace dom 34 } // namespace mozilla 35 36 BEGIN_WORKERS_NAMESPACE 37 38 class ServiceWorkerRegistrationInfo; 39 40 class CancelChannelRunnable final : public Runnable 41 { 42 nsMainThreadPtrHandle<nsIInterceptedChannel> mChannel; 43 nsMainThreadPtrHandle<ServiceWorkerRegistrationInfo> mRegistration; 44 const nsresult mStatus; 45 public: 46 CancelChannelRunnable(nsMainThreadPtrHandle<nsIInterceptedChannel>& aChannel, 47 nsMainThreadPtrHandle<ServiceWorkerRegistrationInfo>& aRegistration, 48 nsresult aStatus); 49 50 NS_IMETHOD Run() override; 51 }; 52 53 class ExtendableEvent : public Event 54 { 55 protected: 56 nsTArray<RefPtr<Promise>> mPromises; 57 58 explicit ExtendableEvent(mozilla::dom::EventTarget* aOwner); ~ExtendableEvent()59 ~ExtendableEvent() {} 60 61 public: 62 NS_DECL_ISUPPORTS_INHERITED NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(ExtendableEvent,Event)63 NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(ExtendableEvent, Event) 64 NS_FORWARD_TO_EVENT 65 66 virtual JSObject* WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override 67 { 68 return mozilla::dom::ExtendableEventBinding::Wrap(aCx, this, aGivenProto); 69 } 70 71 static already_AddRefed<ExtendableEvent> Constructor(mozilla::dom::EventTarget * aOwner,const nsAString & aType,const EventInit & aOptions)72 Constructor(mozilla::dom::EventTarget* aOwner, 73 const nsAString& aType, 74 const EventInit& aOptions) 75 { 76 RefPtr<ExtendableEvent> e = new ExtendableEvent(aOwner); 77 bool trusted = e->Init(aOwner); 78 e->InitEvent(aType, aOptions.mBubbles, aOptions.mCancelable); 79 e->SetTrusted(trusted); 80 e->SetComposed(aOptions.mComposed); 81 return e.forget(); 82 } 83 84 static already_AddRefed<ExtendableEvent> Constructor(const GlobalObject & aGlobal,const nsAString & aType,const EventInit & aOptions,ErrorResult & aRv)85 Constructor(const GlobalObject& aGlobal, 86 const nsAString& aType, 87 const EventInit& aOptions, 88 ErrorResult& aRv) 89 { 90 nsCOMPtr<EventTarget> target = do_QueryInterface(aGlobal.GetAsSupports()); 91 return Constructor(target, aType, aOptions); 92 } 93 94 void 95 WaitUntil(JSContext* aCx, Promise& aPromise, ErrorResult& aRv); 96 97 already_AddRefed<Promise> 98 GetPromise(); 99 AsExtendableEvent()100 virtual ExtendableEvent* AsExtendableEvent() override 101 { 102 return this; 103 } 104 }; 105 106 class FetchEvent final : public ExtendableEvent 107 { 108 nsMainThreadPtrHandle<nsIInterceptedChannel> mChannel; 109 nsMainThreadPtrHandle<ServiceWorkerRegistrationInfo> mRegistration; 110 RefPtr<Request> mRequest; 111 nsCString mScriptSpec; 112 nsCString mPreventDefaultScriptSpec; 113 nsString mClientId; 114 uint32_t mPreventDefaultLineNumber; 115 uint32_t mPreventDefaultColumnNumber; 116 bool mIsReload; 117 bool mWaitToRespond; 118 protected: 119 explicit FetchEvent(EventTarget* aOwner); 120 ~FetchEvent(); 121 122 public: 123 NS_DECL_ISUPPORTS_INHERITED NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(FetchEvent,ExtendableEvent)124 NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(FetchEvent, ExtendableEvent) 125 126 // Note, we cannot use NS_FORWARD_TO_EVENT because we want a different 127 // PreventDefault(JSContext*) override. 128 NS_FORWARD_NSIDOMEVENT(Event::) 129 130 virtual JSObject* WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override 131 { 132 return FetchEventBinding::Wrap(aCx, this, aGivenProto); 133 } 134 135 void PostInit(nsMainThreadPtrHandle<nsIInterceptedChannel>& aChannel, 136 nsMainThreadPtrHandle<ServiceWorkerRegistrationInfo>& aRegistration, 137 const nsACString& aScriptSpec); 138 139 static already_AddRefed<FetchEvent> 140 Constructor(const GlobalObject& aGlobal, 141 const nsAString& aType, 142 const FetchEventInit& aOptions, 143 ErrorResult& aRv); 144 145 bool WaitToRespond()146 WaitToRespond() const 147 { 148 return mWaitToRespond; 149 } 150 151 Request* Request_()152 Request_() const 153 { 154 MOZ_ASSERT(mRequest); 155 return mRequest; 156 } 157 158 void GetClientId(nsAString & aClientId)159 GetClientId(nsAString& aClientId) const 160 { 161 aClientId = mClientId; 162 } 163 164 bool IsReload()165 IsReload() const 166 { 167 return mIsReload; 168 } 169 170 void 171 RespondWith(JSContext* aCx, Promise& aArg, ErrorResult& aRv); 172 173 already_AddRefed<Promise> 174 ForwardTo(const nsAString& aUrl); 175 176 already_AddRefed<Promise> 177 Default(); 178 179 void 180 PreventDefault(JSContext* aCx) override; 181 182 void 183 ReportCanceled(); 184 }; 185 186 class PushMessageData final : public nsISupports, 187 public nsWrapperCache 188 { 189 public: 190 NS_DECL_CYCLE_COLLECTING_ISUPPORTS 191 NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(PushMessageData) 192 193 virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override; 194 GetParentObject()195 nsISupports* GetParentObject() const { 196 return mOwner; 197 } 198 199 void Json(JSContext* cx, JS::MutableHandle<JS::Value> aRetval, 200 ErrorResult& aRv); 201 void Text(nsAString& aData); 202 void ArrayBuffer(JSContext* cx, JS::MutableHandle<JSObject*> aRetval, 203 ErrorResult& aRv); 204 already_AddRefed<mozilla::dom::Blob> Blob(ErrorResult& aRv); 205 206 PushMessageData(nsISupports* aOwner, nsTArray<uint8_t>&& aBytes); 207 private: 208 nsCOMPtr<nsISupports> mOwner; 209 nsTArray<uint8_t> mBytes; 210 nsString mDecodedText; 211 ~PushMessageData(); 212 213 nsresult EnsureDecodedText(); 214 uint8_t* GetContentsCopy(); 215 }; 216 217 class PushEvent final : public ExtendableEvent 218 { 219 RefPtr<PushMessageData> mData; 220 221 protected: 222 explicit PushEvent(mozilla::dom::EventTarget* aOwner); ~PushEvent()223 ~PushEvent() {} 224 225 public: 226 NS_DECL_ISUPPORTS_INHERITED 227 NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(PushEvent, ExtendableEvent) 228 NS_FORWARD_TO_EVENT 229 230 virtual JSObject* WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override; 231 232 static already_AddRefed<PushEvent> 233 Constructor(mozilla::dom::EventTarget* aOwner, 234 const nsAString& aType, 235 const PushEventInit& aOptions, 236 ErrorResult& aRv); 237 238 static already_AddRefed<PushEvent> Constructor(const GlobalObject & aGlobal,const nsAString & aType,const PushEventInit & aOptions,ErrorResult & aRv)239 Constructor(const GlobalObject& aGlobal, 240 const nsAString& aType, 241 const PushEventInit& aOptions, 242 ErrorResult& aRv) 243 { 244 nsCOMPtr<EventTarget> owner = do_QueryInterface(aGlobal.GetAsSupports()); 245 return Constructor(owner, aType, aOptions, aRv); 246 } 247 248 PushMessageData* GetData()249 GetData() const 250 { 251 return mData; 252 } 253 }; 254 255 class ExtendableMessageEvent final : public ExtendableEvent 256 { 257 JS::Heap<JS::Value> mData; 258 nsString mOrigin; 259 nsString mLastEventId; 260 RefPtr<ServiceWorkerClient> mClient; 261 RefPtr<ServiceWorker> mServiceWorker; 262 RefPtr<MessagePort> mMessagePort; 263 nsTArray<RefPtr<MessagePort>> mPorts; 264 265 protected: 266 explicit ExtendableMessageEvent(EventTarget* aOwner); 267 ~ExtendableMessageEvent(); 268 269 public: 270 NS_DECL_ISUPPORTS_INHERITED NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(ExtendableMessageEvent,ExtendableEvent)271 NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(ExtendableMessageEvent, 272 ExtendableEvent) 273 274 NS_FORWARD_TO_EVENT 275 276 virtual JSObject* WrapObjectInternal( 277 JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override 278 { 279 return mozilla::dom::ExtendableMessageEventBinding::Wrap(aCx, this, aGivenProto); 280 } 281 282 static already_AddRefed<ExtendableMessageEvent> 283 Constructor(mozilla::dom::EventTarget* aOwner, 284 const nsAString& aType, 285 const ExtendableMessageEventInit& aOptions, 286 ErrorResult& aRv); 287 288 static already_AddRefed<ExtendableMessageEvent> 289 Constructor(const GlobalObject& aGlobal, 290 const nsAString& aType, 291 const ExtendableMessageEventInit& aOptions, 292 ErrorResult& aRv); 293 294 void GetData(JSContext* aCx, JS::MutableHandle<JS::Value> aData, 295 ErrorResult& aRv); 296 297 void GetSource(Nullable<OwningClientOrServiceWorkerOrMessagePort>& aValue) const; 298 GetOrigin(nsAString & aOrigin)299 NS_IMETHOD GetOrigin(nsAString& aOrigin) 300 { 301 aOrigin = mOrigin; 302 return NS_OK; 303 } 304 GetLastEventId(nsAString & aLastEventId)305 NS_IMETHOD GetLastEventId(nsAString& aLastEventId) 306 { 307 aLastEventId = mLastEventId; 308 return NS_OK; 309 } 310 311 void GetPorts(nsTArray<RefPtr<MessagePort>>& aPorts); 312 }; 313 314 END_WORKERS_NAMESPACE 315 316 #endif /* mozilla_dom_workers_serviceworkerevents_h__ */ 317