зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1462772 P3 Make ServiceWorker binding objects get or create a handle to their associated registration. r=mrbkap
This commit is contained in:
Родитель
4866ecedf2
Коммит
f3b6e1d527
|
@ -63,7 +63,7 @@ ServiceWorker::Create(nsIGlobalObject* aOwner,
|
||||||
return ref.forget();
|
return ref.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
RefPtr<ServiceWorker::Inner> inner = new ServiceWorkerImpl(info);
|
RefPtr<ServiceWorker::Inner> inner = new ServiceWorkerImpl(info, reg);
|
||||||
ref = new ServiceWorker(aOwner, aDescriptor, inner);
|
ref = new ServiceWorker(aOwner, aDescriptor, inner);
|
||||||
return ref.forget();
|
return ref.forget();
|
||||||
}
|
}
|
||||||
|
@ -86,6 +86,31 @@ ServiceWorker::ServiceWorker(nsIGlobalObject* aGlobal,
|
||||||
|
|
||||||
// This will update our state too.
|
// This will update our state too.
|
||||||
mInner->AddServiceWorker(this);
|
mInner->AddServiceWorker(this);
|
||||||
|
|
||||||
|
// Attempt to get an existing binding object for the registration
|
||||||
|
// associated with this ServiceWorker.
|
||||||
|
RefPtr<ServiceWorkerRegistration> reg = aGlobal->GetServiceWorkerRegistration(
|
||||||
|
ServiceWorkerRegistrationDescriptor(mDescriptor.RegistrationId(),
|
||||||
|
mDescriptor.PrincipalInfo(),
|
||||||
|
mDescriptor.Scope(),
|
||||||
|
ServiceWorkerUpdateViaCache::Imports));
|
||||||
|
if (reg) {
|
||||||
|
MaybeAttachToRegistration(reg);
|
||||||
|
} else {
|
||||||
|
RefPtr<ServiceWorker> self = this;
|
||||||
|
|
||||||
|
mInner->GetRegistration(
|
||||||
|
[self = std::move(self)] (const ServiceWorkerRegistrationDescriptor& aDescriptor) {
|
||||||
|
nsIGlobalObject* global = self->GetParentObject();
|
||||||
|
NS_ENSURE_TRUE_VOID(global);
|
||||||
|
RefPtr<ServiceWorkerRegistration> reg =
|
||||||
|
global->GetOrCreateServiceWorkerRegistration(aDescriptor);
|
||||||
|
self->MaybeAttachToRegistration(reg);
|
||||||
|
}, [] (ErrorResult& aRv) {
|
||||||
|
// do nothing
|
||||||
|
aRv.SuppressException();
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ServiceWorker::~ServiceWorker()
|
ServiceWorker::~ServiceWorker()
|
||||||
|
@ -94,6 +119,10 @@ ServiceWorker::~ServiceWorker()
|
||||||
mInner->RemoveServiceWorker(this);
|
mInner->RemoveServiceWorker(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NS_IMPL_CYCLE_COLLECTION_INHERITED(ServiceWorker,
|
||||||
|
DOMEventTargetHelper,
|
||||||
|
mRegistration);
|
||||||
|
|
||||||
NS_IMPL_ADDREF_INHERITED(ServiceWorker, DOMEventTargetHelper)
|
NS_IMPL_ADDREF_INHERITED(ServiceWorker, DOMEventTargetHelper)
|
||||||
NS_IMPL_RELEASE_INHERITED(ServiceWorker, DOMEventTargetHelper)
|
NS_IMPL_RELEASE_INHERITED(ServiceWorker, DOMEventTargetHelper)
|
||||||
|
|
||||||
|
@ -201,5 +230,14 @@ ServiceWorker::DisconnectFromOwner()
|
||||||
DOMEventTargetHelper::DisconnectFromOwner();
|
DOMEventTargetHelper::DisconnectFromOwner();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ServiceWorker::MaybeAttachToRegistration(ServiceWorkerRegistration* aRegistration)
|
||||||
|
{
|
||||||
|
MOZ_DIAGNOSTIC_ASSERT(aRegistration);
|
||||||
|
MOZ_DIAGNOSTIC_ASSERT(!mRegistration);
|
||||||
|
|
||||||
|
mRegistration = aRegistration;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace dom
|
} // namespace dom
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include "mozilla/DOMEventTargetHelper.h"
|
#include "mozilla/DOMEventTargetHelper.h"
|
||||||
#include "mozilla/dom/BindingDeclarations.h"
|
#include "mozilla/dom/BindingDeclarations.h"
|
||||||
#include "mozilla/dom/ServiceWorkerDescriptor.h"
|
#include "mozilla/dom/ServiceWorkerDescriptor.h"
|
||||||
|
#include "mozilla/dom/ServiceWorkerUtils.h"
|
||||||
|
|
||||||
#ifdef XP_WIN
|
#ifdef XP_WIN
|
||||||
#undef PostMessage
|
#undef PostMessage
|
||||||
|
@ -55,6 +56,12 @@ public:
|
||||||
virtual void
|
virtual void
|
||||||
RemoveServiceWorker(ServiceWorker* aWorker) = 0;
|
RemoveServiceWorker(ServiceWorker* aWorker) = 0;
|
||||||
|
|
||||||
|
// Get the associated registration for this ServiceWorker. The success
|
||||||
|
// callback should always be called asynchronously.
|
||||||
|
virtual void
|
||||||
|
GetRegistration(ServiceWorkerRegistrationCallback&& aSuccessCB,
|
||||||
|
ServiceWorkerFailureCallback&& aFailureCB) = 0;
|
||||||
|
|
||||||
virtual void
|
virtual void
|
||||||
PostMessage(RefPtr<ServiceWorkerCloneData>&& aData,
|
PostMessage(RefPtr<ServiceWorkerCloneData>&& aData,
|
||||||
const ClientInfo& aClientInfo,
|
const ClientInfo& aClientInfo,
|
||||||
|
@ -65,6 +72,7 @@ public:
|
||||||
|
|
||||||
NS_DECLARE_STATIC_IID_ACCESSOR(NS_DOM_SERVICEWORKER_IID)
|
NS_DECLARE_STATIC_IID_ACCESSOR(NS_DOM_SERVICEWORKER_IID)
|
||||||
NS_DECL_ISUPPORTS_INHERITED
|
NS_DECL_ISUPPORTS_INHERITED
|
||||||
|
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(ServiceWorker, DOMEventTargetHelper)
|
||||||
|
|
||||||
IMPL_EVENT_HANDLER(statechange)
|
IMPL_EVENT_HANDLER(statechange)
|
||||||
IMPL_EVENT_HANDLER(error)
|
IMPL_EVENT_HANDLER(error)
|
||||||
|
@ -102,9 +110,13 @@ private:
|
||||||
// This class is reference-counted and will be destroyed from Release().
|
// This class is reference-counted and will be destroyed from Release().
|
||||||
~ServiceWorker();
|
~ServiceWorker();
|
||||||
|
|
||||||
|
void
|
||||||
|
MaybeAttachToRegistration(ServiceWorkerRegistration* aRegistration);
|
||||||
|
|
||||||
ServiceWorkerDescriptor mDescriptor;
|
ServiceWorkerDescriptor mDescriptor;
|
||||||
|
|
||||||
RefPtr<Inner> mInner;
|
RefPtr<Inner> mInner;
|
||||||
|
RefPtr<ServiceWorkerRegistration> mRegistration;
|
||||||
};
|
};
|
||||||
|
|
||||||
NS_DEFINE_STATIC_IID_ACCESSOR(ServiceWorker, NS_DOM_SERVICEWORKER_IID)
|
NS_DEFINE_STATIC_IID_ACCESSOR(ServiceWorker, NS_DOM_SERVICEWORKER_IID)
|
||||||
|
|
|
@ -36,6 +36,42 @@ ServiceWorkerImpl::RemoveServiceWorker(ServiceWorker* aWorker)
|
||||||
mOuter = nullptr;
|
mOuter = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ServiceWorkerImpl::GetRegistration(ServiceWorkerRegistrationCallback&& aSuccessCB,
|
||||||
|
ServiceWorkerFailureCallback&& aFailureCB)
|
||||||
|
{
|
||||||
|
// While we could immediate call success with our registration descriptor
|
||||||
|
// we instead queue a runnable to do this. This ensures that GetRegistration()
|
||||||
|
// is always async to match how the IPC implementation will work. It also
|
||||||
|
// ensure that if any events are triggered from providing the registration
|
||||||
|
// that they are fired from a runnable on the correct global's event target.
|
||||||
|
|
||||||
|
if (!mOuter) {
|
||||||
|
aFailureCB(CopyableErrorResult(NS_ERROR_DOM_INVALID_STATE_ERR));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsIGlobalObject* global = mOuter->GetParentObject();
|
||||||
|
if (!global) {
|
||||||
|
aFailureCB(CopyableErrorResult(NS_ERROR_DOM_INVALID_STATE_ERR));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction(
|
||||||
|
"ServiceWorkerImpl::GetRegistration",
|
||||||
|
[reg = mReg, successCB = std::move(aSuccessCB)] () mutable {
|
||||||
|
successCB(reg->Descriptor());
|
||||||
|
});
|
||||||
|
|
||||||
|
nsresult rv =
|
||||||
|
global->EventTargetFor(TaskCategory::Other)->Dispatch(r.forget(),
|
||||||
|
NS_DISPATCH_NORMAL);
|
||||||
|
if (NS_FAILED(rv)) {
|
||||||
|
aFailureCB(CopyableErrorResult(rv));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ServiceWorkerImpl::PostMessage(RefPtr<ServiceWorkerCloneData>&& aData,
|
ServiceWorkerImpl::PostMessage(RefPtr<ServiceWorkerCloneData>&& aData,
|
||||||
const ClientInfo& aClientInfo,
|
const ClientInfo& aClientInfo,
|
||||||
|
@ -54,11 +90,14 @@ ServiceWorkerImpl::SetState(ServiceWorkerState aState)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ServiceWorkerImpl::ServiceWorkerImpl(ServiceWorkerInfo* aInfo)
|
ServiceWorkerImpl::ServiceWorkerImpl(ServiceWorkerInfo* aInfo,
|
||||||
|
ServiceWorkerRegistrationInfo* aReg)
|
||||||
: mInfo(aInfo)
|
: mInfo(aInfo)
|
||||||
|
, mReg(aReg)
|
||||||
, mOuter(nullptr)
|
, mOuter(nullptr)
|
||||||
{
|
{
|
||||||
MOZ_DIAGNOSTIC_ASSERT(mInfo);
|
MOZ_DIAGNOSTIC_ASSERT(mInfo);
|
||||||
|
MOZ_DIAGNOSTIC_ASSERT(mReg);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace dom
|
} // namespace dom
|
||||||
|
|
|
@ -14,11 +14,13 @@ namespace mozilla {
|
||||||
namespace dom {
|
namespace dom {
|
||||||
|
|
||||||
class ServiceWorkerInfo;
|
class ServiceWorkerInfo;
|
||||||
|
class ServiceWorkerRegistrationInfo;
|
||||||
|
|
||||||
class ServiceWorkerImpl final : public ServiceWorker::Inner
|
class ServiceWorkerImpl final : public ServiceWorker::Inner
|
||||||
, public ServiceWorkerInfo::Listener
|
, public ServiceWorkerInfo::Listener
|
||||||
{
|
{
|
||||||
RefPtr<ServiceWorkerInfo> mInfo;
|
RefPtr<ServiceWorkerInfo> mInfo;
|
||||||
|
RefPtr<ServiceWorkerRegistrationInfo> mReg;
|
||||||
ServiceWorker* mOuter;
|
ServiceWorker* mOuter;
|
||||||
|
|
||||||
~ServiceWorkerImpl();
|
~ServiceWorkerImpl();
|
||||||
|
@ -30,6 +32,10 @@ class ServiceWorkerImpl final : public ServiceWorker::Inner
|
||||||
void
|
void
|
||||||
RemoveServiceWorker(ServiceWorker* aWorker) override;
|
RemoveServiceWorker(ServiceWorker* aWorker) override;
|
||||||
|
|
||||||
|
void
|
||||||
|
GetRegistration(ServiceWorkerRegistrationCallback&& aSuccessCB,
|
||||||
|
ServiceWorkerFailureCallback&& aFailureCB) override;
|
||||||
|
|
||||||
void
|
void
|
||||||
PostMessage(RefPtr<ServiceWorkerCloneData>&& aData,
|
PostMessage(RefPtr<ServiceWorkerCloneData>&& aData,
|
||||||
const ClientInfo& aClientInfo,
|
const ClientInfo& aClientInfo,
|
||||||
|
@ -40,7 +46,8 @@ class ServiceWorkerImpl final : public ServiceWorker::Inner
|
||||||
SetState(ServiceWorkerState aState) override;
|
SetState(ServiceWorkerState aState) override;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit ServiceWorkerImpl(ServiceWorkerInfo* aInfo);
|
ServiceWorkerImpl(ServiceWorkerInfo* aInfo,
|
||||||
|
ServiceWorkerRegistrationInfo* aReg);
|
||||||
|
|
||||||
NS_INLINE_DECL_REFCOUNTING(ServiceWorkerImpl, override);
|
NS_INLINE_DECL_REFCOUNTING(ServiceWorkerImpl, override);
|
||||||
};
|
};
|
||||||
|
|
Загрузка…
Ссылка в новой задаче