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