Bug 1041340 - Implement [[HandleDocumentUnload]]. r=baku

--HG--
extra : rebase_source : 05bee71b7e26a52783462b9803fe161077af9a7b
This commit is contained in:
Nikhil Marathe 2014-10-24 15:11:26 -07:00
parent 601a3a5216
commit e8c60ffc59
3 changed files with 39 additions and 12 deletions

View File

@ -1933,10 +1933,6 @@ void
ServiceWorkerManager::MaybeStartControlling(nsIDocument* aDoc)
{
AssertIsOnMainThread();
if (!Preferences::GetBool("dom.serviceWorkers.enabled")) {
return;
}
nsRefPtr<ServiceWorkerRegistrationInfo> registration =
GetServiceWorkerRegistrationInfo(aDoc);
if (registration) {
@ -1948,14 +1944,35 @@ ServiceWorkerManager::MaybeStartControlling(nsIDocument* aDoc)
}
}
class ServiceWorkerActivateAfterUnloadingJob MOZ_FINAL : public ServiceWorkerJob
{
nsRefPtr<ServiceWorkerRegistrationInfo> mRegistration;
public:
ServiceWorkerActivateAfterUnloadingJob(ServiceWorkerJobQueue* aQueue,
ServiceWorkerRegistrationInfo* aReg)
: ServiceWorkerJob(aQueue)
, mRegistration(aReg)
{ }
void
Start()
{
if (mRegistration->mPendingUninstall) {
mRegistration->Clear();
nsRefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
swm->RemoveRegistration(mRegistration);
} else {
mRegistration->TryToActivate();
}
Done(NS_OK);
}
};
void
ServiceWorkerManager::MaybeStopControlling(nsIDocument* aDoc)
{
MOZ_ASSERT(aDoc);
if (!Preferences::GetBool("dom.serviceWorkers.enabled")) {
return;
}
nsRefPtr<ServiceWorkerRegistrationInfo> registration;
mControlledDocuments.Remove(aDoc, getter_AddRefs(registration));
// A document which was uncontrolled does not maintain that state itself, so
@ -1963,6 +1980,14 @@ ServiceWorkerManager::MaybeStopControlling(nsIDocument* aDoc)
// associated registration. So this check is required.
if (registration) {
registration->StopControllingADocument();
if (!registration->IsControllingDocuments()) {
ServiceWorkerJobQueue* queue = GetOrCreateJobQueue(registration->mScope);
// The remaining tasks touch registration->mPendingUninstall, so queue
// them up in a job.
nsRefPtr<ServiceWorkerActivateAfterUnloadingJob> job =
new ServiceWorkerActivateAfterUnloadingJob(queue, registration);
queue->Append(job);
}
}
}

View File

@ -290,12 +290,13 @@ class ServiceWorkerManager MOZ_FINAL
, public nsIIPCBackgroundChildCreateCallback
{
friend class ActivationRunnable;
friend class ServiceWorkerRegistrationInfo;
friend class ServiceWorkerRegisterJob;
friend class GetReadyPromiseRunnable;
friend class GetRegistrationsRunnable;
friend class GetRegistrationRunnable;
friend class QueueFireUpdateFoundRunnable;
friend class ServiceWorkerActivateAfterUnloadingJob;
friend class ServiceWorkerRegisterJob;
friend class ServiceWorkerRegistrationInfo;
friend class ServiceWorkerUnregisterJob;
public:
@ -349,6 +350,8 @@ public:
void
RemoveRegistration(ServiceWorkerRegistrationInfo* aRegistration)
{
MOZ_ASSERT(aRegistration);
MOZ_ASSERT(!aRegistration->IsControllingDocuments());
MOZ_ASSERT(mServiceWorkerRegistrationInfos.Contains(aRegistration->mScope));
ServiceWorkerManager::RemoveScope(mOrderedScopes, aRegistration->mScope);
mServiceWorkerRegistrationInfos.Remove(aRegistration->mScope);

View File

@ -140,8 +140,7 @@
window.onmessage = null;
// We have to make frame navigate away, otherwise it will call
// MaybeStopControlling() when this document is unloaded. At that point
// the pref has been disabled, and so MaybeStopControlling() will just
// return since it is currently gated.
// the pref has been disabled, so the ServiceWorkerManager is not available.
frame.setAttribute("src", new URL("about:blank").href);
resolve();
} else if (e.data.type == "check") {