ServiceWorkerContainer.h (5082B)
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_serviceworkercontainer_h__ 8 #define mozilla_dom_serviceworkercontainer_h__ 9 10 #include "mozilla/DOMEventTargetHelper.h" 11 #include "mozilla/ErrorResult.h" 12 #include "mozilla/dom/ServiceWorkerUtils.h" 13 14 class nsIGlobalWindow; 15 class nsIPrincipal; 16 17 namespace mozilla::dom { 18 19 class ClientPostMessageArgs; 20 struct MessageEventInit; 21 class Promise; 22 struct RegistrationOptions; 23 class ServiceWorker; 24 class ServiceWorkerContainerChild; 25 class TrustedScriptURLOrUSVString; 26 27 // Lightweight serviceWorker APIs collection. 28 class ServiceWorkerContainer final : public DOMEventTargetHelper { 29 public: 30 NS_DECL_ISUPPORTS_INHERITED 31 NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(ServiceWorkerContainer, 32 DOMEventTargetHelper) 33 34 IMPL_EVENT_HANDLER(controllerchange) 35 IMPL_EVENT_HANDLER(messageerror) 36 37 // Almost a manual expansion of IMPL_EVENT_HANDLER(message), but 38 // with the additional StartMessages() when setting the handler, as 39 // required by the spec. 40 inline mozilla::dom::EventHandlerNonNull* GetOnmessage() { 41 return GetEventHandler(nsGkAtoms::onmessage); 42 } 43 inline void SetOnmessage(mozilla::dom::EventHandlerNonNull* aCallback) { 44 SetEventHandler(nsGkAtoms::onmessage, aCallback); 45 StartMessages(); 46 } 47 48 static bool IsEnabled(JSContext* aCx, JSObject* aGlobal); 49 50 static already_AddRefed<ServiceWorkerContainer> Create( 51 nsIGlobalObject* aGlobal); 52 53 virtual JSObject* WrapObject(JSContext* aCx, 54 JS::Handle<JSObject*> aGivenProto) override; 55 56 MOZ_CAN_RUN_SCRIPT already_AddRefed<Promise> Register( 57 const TrustedScriptURLOrUSVString& aScriptURL, 58 const RegistrationOptions& aOptions, nsIPrincipal* aSubjectPrincipal, 59 ErrorResult& aRv); 60 61 already_AddRefed<ServiceWorker> GetController(); 62 63 already_AddRefed<Promise> GetRegistration(const nsAString& aDocumentURL, 64 ErrorResult& aRv); 65 66 already_AddRefed<Promise> GetRegistrations(ErrorResult& aRv); 67 68 void StartMessages(); 69 70 Promise* GetReady(ErrorResult& aRv); 71 72 // Testing only. 73 void GetScopeForUrl(const nsAString& aUrl, nsString& aScope, 74 ErrorResult& aRv); 75 76 // DOMEventTargetHelper 77 void DisconnectFromOwner() override; 78 79 // Invalidates |mControllerWorker| and dispatches a "controllerchange" 80 // event. 81 void ControllerChanged(ErrorResult& aRv); 82 83 void ReceiveMessage(const ClientPostMessageArgs& aArgs); 84 85 void RevokeActor(ServiceWorkerContainerChild* aActor); 86 87 private: 88 explicit ServiceWorkerContainer(nsIGlobalObject* aGlobal); 89 90 ~ServiceWorkerContainer(); 91 92 // Utility method to get the global if its present and if certain 93 // additional validaty checks pass. One of these additional checks 94 // verifies the global can access storage. Since storage access can 95 // vary based on user settings we want to often provide some error 96 // message if the storage check fails. This method takes an optional 97 // callback that can be used to report the storage failure to the 98 // devtools console. 99 nsIGlobalObject* GetGlobalIfValid( 100 ErrorResult& aRv, 101 const std::function<void(nsIGlobalObject*)>&& aStorageFailureCB = 102 nullptr) const; 103 104 struct ReceivedMessage; 105 106 // Dispatch a Runnable that dispatches the given message on this 107 // object. When the owner of this object is a Window, the Runnable 108 // is dispatched on the corresponding TabGroup. 109 void EnqueueReceivedMessageDispatch(RefPtr<ReceivedMessage> aMessage); 110 111 template <typename F> 112 void RunWithJSContext(F&& aCallable); 113 114 void DispatchMessage(RefPtr<ReceivedMessage> aMessage); 115 116 // When it fails, returning boolean means whether it's because deserailization 117 // failed or not. 118 static Result<Ok, bool> FillInMessageEventInit(JSContext* aCx, 119 nsIGlobalObject* aGlobal, 120 ReceivedMessage& aMessage, 121 MessageEventInit& aInit, 122 ErrorResult& aRv); 123 124 void Shutdown(); 125 126 RefPtr<ServiceWorkerContainerChild> mActor; 127 bool mShutdown; 128 129 // This only changes when a worker hijacks everything in its scope by calling 130 // claim. 131 RefPtr<ServiceWorker> mControllerWorker; 132 133 RefPtr<Promise> mReadyPromise; 134 MozPromiseRequestHolder<ServiceWorkerRegistrationPromise> mReadyPromiseHolder; 135 136 // Set after StartMessages() has been called. 137 bool mMessagesStarted = false; 138 139 // Queue holding messages posted from service worker as long as 140 // StartMessages() hasn't been called. 141 nsTArray<RefPtr<ReceivedMessage>> mPendingMessages; 142 }; 143 144 } // namespace mozilla::dom 145 146 #endif /* mozilla_dom_serviceworkercontainer_h__ */