зеркало из https://github.com/mozilla/gecko-dev.git
249 строки
7.4 KiB
C++
249 строки
7.4 KiB
C++
/* -*- 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/. */
|
|
|
|
#include "ServiceWorkerRegistration.h"
|
|
|
|
#include "mozilla/dom/Promise.h"
|
|
#include "mozilla/dom/PushManager.h"
|
|
#include "mozilla/dom/ServiceWorker.h"
|
|
#include "mozilla/dom/ServiceWorkerRegistrationBinding.h"
|
|
#include "mozilla/dom/WorkerPrivate.h"
|
|
#include "nsCycleCollectionParticipant.h"
|
|
#include "nsISupportsPrimitives.h"
|
|
#include "nsPIDOMWindow.h"
|
|
#include "ServiceWorkerRegistrationImpl.h"
|
|
|
|
namespace mozilla {
|
|
namespace dom {
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_INHERITED(ServiceWorkerRegistration,
|
|
DOMEventTargetHelper,
|
|
mInstallingWorker,
|
|
mWaitingWorker,
|
|
mActiveWorker,
|
|
mPushManager);
|
|
|
|
NS_IMPL_ADDREF_INHERITED(ServiceWorkerRegistration, DOMEventTargetHelper)
|
|
NS_IMPL_RELEASE_INHERITED(ServiceWorkerRegistration, DOMEventTargetHelper)
|
|
|
|
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ServiceWorkerRegistration)
|
|
NS_INTERFACE_MAP_ENTRY(ServiceWorkerRegistration)
|
|
NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
|
|
|
|
ServiceWorkerRegistration::ServiceWorkerRegistration(nsIGlobalObject* aGlobal,
|
|
const ServiceWorkerRegistrationDescriptor& aDescriptor,
|
|
ServiceWorkerRegistration::Inner* aInner)
|
|
: DOMEventTargetHelper(aGlobal)
|
|
, mDescriptor(aDescriptor)
|
|
, mInner(aInner)
|
|
{
|
|
MOZ_DIAGNOSTIC_ASSERT(mInner);
|
|
UpdateState(mDescriptor);
|
|
mInner->SetServiceWorkerRegistration(this);
|
|
}
|
|
|
|
ServiceWorkerRegistration::~ServiceWorkerRegistration()
|
|
{
|
|
if (mInner) {
|
|
mInner->ClearServiceWorkerRegistration(this);
|
|
}
|
|
}
|
|
|
|
JSObject*
|
|
ServiceWorkerRegistration::WrapObject(JSContext* aCx,
|
|
JS::Handle<JSObject*> aGivenProto)
|
|
{
|
|
return ServiceWorkerRegistrationBinding::Wrap(aCx, this, aGivenProto);
|
|
}
|
|
|
|
/* static */ already_AddRefed<ServiceWorkerRegistration>
|
|
ServiceWorkerRegistration::CreateForMainThread(nsPIDOMWindowInner* aWindow,
|
|
const ServiceWorkerRegistrationDescriptor& aDescriptor)
|
|
{
|
|
MOZ_ASSERT(aWindow);
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
|
|
RefPtr<Inner> inner = new ServiceWorkerRegistrationMainThread(aDescriptor);
|
|
|
|
RefPtr<ServiceWorkerRegistration> registration =
|
|
new ServiceWorkerRegistration(aWindow->AsGlobal(), aDescriptor, inner);
|
|
|
|
return registration.forget();
|
|
}
|
|
|
|
/* static */ already_AddRefed<ServiceWorkerRegistration>
|
|
ServiceWorkerRegistration::CreateForWorker(WorkerPrivate* aWorkerPrivate,
|
|
nsIGlobalObject* aGlobal,
|
|
const ServiceWorkerRegistrationDescriptor& aDescriptor)
|
|
{
|
|
MOZ_DIAGNOSTIC_ASSERT(aWorkerPrivate);
|
|
MOZ_DIAGNOSTIC_ASSERT(aGlobal);
|
|
aWorkerPrivate->AssertIsOnWorkerThread();
|
|
|
|
RefPtr<Inner> inner =
|
|
new ServiceWorkerRegistrationWorkerThread(aWorkerPrivate, aDescriptor);
|
|
|
|
RefPtr<ServiceWorkerRegistration> registration =
|
|
new ServiceWorkerRegistration(aGlobal, aDescriptor, inner);
|
|
|
|
return registration.forget();
|
|
}
|
|
|
|
void
|
|
ServiceWorkerRegistration::DisconnectFromOwner()
|
|
{
|
|
mInner->ClearServiceWorkerRegistration(this);
|
|
mInner = nullptr;
|
|
DOMEventTargetHelper::DisconnectFromOwner();
|
|
}
|
|
|
|
already_AddRefed<ServiceWorker>
|
|
ServiceWorkerRegistration::GetInstalling() const
|
|
{
|
|
RefPtr<ServiceWorker> ref = mInstallingWorker;
|
|
return ref.forget();
|
|
}
|
|
|
|
already_AddRefed<ServiceWorker>
|
|
ServiceWorkerRegistration::GetWaiting() const
|
|
{
|
|
RefPtr<ServiceWorker> ref = mWaitingWorker;
|
|
return ref.forget();
|
|
}
|
|
|
|
already_AddRefed<ServiceWorker>
|
|
ServiceWorkerRegistration::GetActive() const
|
|
{
|
|
RefPtr<ServiceWorker> ref = mActiveWorker;
|
|
return ref.forget();
|
|
}
|
|
|
|
void
|
|
ServiceWorkerRegistration::UpdateState(const ServiceWorkerRegistrationDescriptor& aDescriptor)
|
|
{
|
|
MOZ_DIAGNOSTIC_ASSERT(MatchesDescriptor(aDescriptor));
|
|
|
|
mDescriptor = aDescriptor;
|
|
|
|
nsCOMPtr<nsIGlobalObject> global = GetParentObject();
|
|
|
|
// Clear all workers if the registration has been detached from the global.
|
|
// Also, we cannot expose ServiceWorker objects on worker threads yet, so
|
|
// do the same on when off-main-thread. This main thread check should be
|
|
// removed as part of bug 1113522.
|
|
if (!global || !NS_IsMainThread()) {
|
|
mInstallingWorker = nullptr;
|
|
mWaitingWorker = nullptr;
|
|
mActiveWorker = nullptr;
|
|
return;
|
|
}
|
|
|
|
Maybe<ServiceWorkerDescriptor> active = aDescriptor.GetActive();
|
|
if (active.isSome()) {
|
|
mActiveWorker = global->GetOrCreateServiceWorker(active.ref());
|
|
} else {
|
|
mActiveWorker = nullptr;
|
|
}
|
|
|
|
Maybe<ServiceWorkerDescriptor> waiting = aDescriptor.GetWaiting();
|
|
if (waiting.isSome()) {
|
|
mWaitingWorker = global->GetOrCreateServiceWorker(waiting.ref());
|
|
} else {
|
|
mWaitingWorker = nullptr;
|
|
}
|
|
|
|
Maybe<ServiceWorkerDescriptor> installing = aDescriptor.GetInstalling();
|
|
if (installing.isSome()) {
|
|
mInstallingWorker = global->GetOrCreateServiceWorker(installing.ref());
|
|
} else {
|
|
mInstallingWorker = nullptr;
|
|
}
|
|
}
|
|
|
|
bool
|
|
ServiceWorkerRegistration::MatchesDescriptor(const ServiceWorkerRegistrationDescriptor& aDescriptor) const
|
|
{
|
|
return aDescriptor.Id() == mDescriptor.Id() &&
|
|
aDescriptor.PrincipalInfo() == mDescriptor.PrincipalInfo() &&
|
|
aDescriptor.Scope() == mDescriptor.Scope();
|
|
}
|
|
|
|
void
|
|
ServiceWorkerRegistration::GetScope(nsAString& aScope) const
|
|
{
|
|
CopyUTF8toUTF16(mDescriptor.Scope(), aScope);
|
|
}
|
|
|
|
ServiceWorkerUpdateViaCache
|
|
ServiceWorkerRegistration::GetUpdateViaCache(ErrorResult& aRv) const
|
|
{
|
|
return mDescriptor.UpdateViaCache();
|
|
}
|
|
|
|
already_AddRefed<Promise>
|
|
ServiceWorkerRegistration::Update(ErrorResult& aRv)
|
|
{
|
|
if (!mInner) {
|
|
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
|
|
return nullptr;
|
|
}
|
|
return mInner->Update(aRv);
|
|
}
|
|
|
|
already_AddRefed<Promise>
|
|
ServiceWorkerRegistration::Unregister(ErrorResult& aRv)
|
|
{
|
|
if (!mInner) {
|
|
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
|
|
return nullptr;
|
|
}
|
|
return mInner->Unregister(aRv);
|
|
}
|
|
|
|
already_AddRefed<PushManager>
|
|
ServiceWorkerRegistration::GetPushManager(JSContext* aCx, ErrorResult& aRv)
|
|
{
|
|
if (!mInner) {
|
|
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
|
|
return nullptr;
|
|
}
|
|
if (!mPushManager) {
|
|
mPushManager = mInner->GetPushManager(aCx, aRv);
|
|
if (aRv.Failed()) {
|
|
return nullptr;
|
|
}
|
|
}
|
|
RefPtr<PushManager> ret = mPushManager;
|
|
return ret.forget();
|
|
}
|
|
|
|
already_AddRefed<Promise>
|
|
ServiceWorkerRegistration::ShowNotification(JSContext* aCx,
|
|
const nsAString& aTitle,
|
|
const NotificationOptions& aOptions,
|
|
ErrorResult& aRv)
|
|
{
|
|
if (!mInner) {
|
|
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
|
|
return nullptr;
|
|
}
|
|
return mInner->ShowNotification(aCx, aTitle, aOptions, aRv);
|
|
}
|
|
|
|
already_AddRefed<Promise>
|
|
ServiceWorkerRegistration::GetNotifications(const GetNotificationOptions& aOptions,
|
|
ErrorResult& aRv)
|
|
{
|
|
if (!mInner) {
|
|
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
|
|
return nullptr;
|
|
}
|
|
return mInner->GetNotifications(aOptions, aRv);
|
|
}
|
|
|
|
} // dom namespace
|
|
} // mozilla namespace
|