зеркало из 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();
|
||||
}
|
||||
|
||||
RefPtr<ServiceWorker::Inner> inner = new ServiceWorkerImpl(info);
|
||||
RefPtr<ServiceWorker::Inner> inner = new ServiceWorkerImpl(info, reg);
|
||||
ref = new ServiceWorker(aOwner, aDescriptor, inner);
|
||||
return ref.forget();
|
||||
}
|
||||
|
@ -86,6 +86,31 @@ ServiceWorker::ServiceWorker(nsIGlobalObject* aGlobal,
|
|||
|
||||
// This will update our state too.
|
||||
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()
|
||||
|
@ -94,6 +119,10 @@ ServiceWorker::~ServiceWorker()
|
|||
mInner->RemoveServiceWorker(this);
|
||||
}
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_INHERITED(ServiceWorker,
|
||||
DOMEventTargetHelper,
|
||||
mRegistration);
|
||||
|
||||
NS_IMPL_ADDREF_INHERITED(ServiceWorker, DOMEventTargetHelper)
|
||||
NS_IMPL_RELEASE_INHERITED(ServiceWorker, DOMEventTargetHelper)
|
||||
|
||||
|
@ -201,5 +230,14 @@ ServiceWorker::DisconnectFromOwner()
|
|||
DOMEventTargetHelper::DisconnectFromOwner();
|
||||
}
|
||||
|
||||
void
|
||||
ServiceWorker::MaybeAttachToRegistration(ServiceWorkerRegistration* aRegistration)
|
||||
{
|
||||
MOZ_DIAGNOSTIC_ASSERT(aRegistration);
|
||||
MOZ_DIAGNOSTIC_ASSERT(!mRegistration);
|
||||
|
||||
mRegistration = aRegistration;
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "mozilla/DOMEventTargetHelper.h"
|
||||
#include "mozilla/dom/BindingDeclarations.h"
|
||||
#include "mozilla/dom/ServiceWorkerDescriptor.h"
|
||||
#include "mozilla/dom/ServiceWorkerUtils.h"
|
||||
|
||||
#ifdef XP_WIN
|
||||
#undef PostMessage
|
||||
|
@ -55,6 +56,12 @@ public:
|
|||
virtual void
|
||||
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
|
||||
PostMessage(RefPtr<ServiceWorkerCloneData>&& aData,
|
||||
const ClientInfo& aClientInfo,
|
||||
|
@ -65,6 +72,7 @@ public:
|
|||
|
||||
NS_DECLARE_STATIC_IID_ACCESSOR(NS_DOM_SERVICEWORKER_IID)
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(ServiceWorker, DOMEventTargetHelper)
|
||||
|
||||
IMPL_EVENT_HANDLER(statechange)
|
||||
IMPL_EVENT_HANDLER(error)
|
||||
|
@ -102,9 +110,13 @@ private:
|
|||
// This class is reference-counted and will be destroyed from Release().
|
||||
~ServiceWorker();
|
||||
|
||||
void
|
||||
MaybeAttachToRegistration(ServiceWorkerRegistration* aRegistration);
|
||||
|
||||
ServiceWorkerDescriptor mDescriptor;
|
||||
|
||||
RefPtr<Inner> mInner;
|
||||
RefPtr<ServiceWorkerRegistration> mRegistration;
|
||||
};
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(ServiceWorker, NS_DOM_SERVICEWORKER_IID)
|
||||
|
|
|
@ -36,6 +36,42 @@ ServiceWorkerImpl::RemoveServiceWorker(ServiceWorker* aWorker)
|
|||
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
|
||||
ServiceWorkerImpl::PostMessage(RefPtr<ServiceWorkerCloneData>&& aData,
|
||||
const ClientInfo& aClientInfo,
|
||||
|
@ -54,11 +90,14 @@ ServiceWorkerImpl::SetState(ServiceWorkerState aState)
|
|||
}
|
||||
|
||||
|
||||
ServiceWorkerImpl::ServiceWorkerImpl(ServiceWorkerInfo* aInfo)
|
||||
ServiceWorkerImpl::ServiceWorkerImpl(ServiceWorkerInfo* aInfo,
|
||||
ServiceWorkerRegistrationInfo* aReg)
|
||||
: mInfo(aInfo)
|
||||
, mReg(aReg)
|
||||
, mOuter(nullptr)
|
||||
{
|
||||
MOZ_DIAGNOSTIC_ASSERT(mInfo);
|
||||
MOZ_DIAGNOSTIC_ASSERT(mReg);
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
|
|
|
@ -14,11 +14,13 @@ namespace mozilla {
|
|||
namespace dom {
|
||||
|
||||
class ServiceWorkerInfo;
|
||||
class ServiceWorkerRegistrationInfo;
|
||||
|
||||
class ServiceWorkerImpl final : public ServiceWorker::Inner
|
||||
, public ServiceWorkerInfo::Listener
|
||||
{
|
||||
RefPtr<ServiceWorkerInfo> mInfo;
|
||||
RefPtr<ServiceWorkerRegistrationInfo> mReg;
|
||||
ServiceWorker* mOuter;
|
||||
|
||||
~ServiceWorkerImpl();
|
||||
|
@ -30,6 +32,10 @@ class ServiceWorkerImpl final : public ServiceWorker::Inner
|
|||
void
|
||||
RemoveServiceWorker(ServiceWorker* aWorker) override;
|
||||
|
||||
void
|
||||
GetRegistration(ServiceWorkerRegistrationCallback&& aSuccessCB,
|
||||
ServiceWorkerFailureCallback&& aFailureCB) override;
|
||||
|
||||
void
|
||||
PostMessage(RefPtr<ServiceWorkerCloneData>&& aData,
|
||||
const ClientInfo& aClientInfo,
|
||||
|
@ -40,7 +46,8 @@ class ServiceWorkerImpl final : public ServiceWorker::Inner
|
|||
SetState(ServiceWorkerState aState) override;
|
||||
|
||||
public:
|
||||
explicit ServiceWorkerImpl(ServiceWorkerInfo* aInfo);
|
||||
ServiceWorkerImpl(ServiceWorkerInfo* aInfo,
|
||||
ServiceWorkerRegistrationInfo* aReg);
|
||||
|
||||
NS_INLINE_DECL_REFCOUNTING(ServiceWorkerImpl, override);
|
||||
};
|
||||
|
|
Загрузка…
Ссылка в новой задаче