зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1056259 - ServiceWorkerRegistration should unregister itself when the window is destroyed. r=nsm
This commit is contained in:
Родитель
c6ff8a9edf
Коммит
f4a5ca4d21
|
@ -1629,6 +1629,7 @@ ServiceWorkerManager::AddRegistrationEventListener(nsIURI* aDocumentURI, nsIDOME
|
|||
|
||||
// TODO: this is very very bad:
|
||||
ServiceWorkerRegistration* registration = static_cast<ServiceWorkerRegistration*>(aListener);
|
||||
MOZ_ASSERT(!domainInfo->mServiceWorkerRegistrations.Contains(registration));
|
||||
domainInfo->mServiceWorkerRegistrations.AppendElement(registration);
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -1643,6 +1644,7 @@ ServiceWorkerManager::RemoveRegistrationEventListener(nsIURI* aDocumentURI, nsID
|
|||
}
|
||||
|
||||
ServiceWorkerRegistration* registration = static_cast<ServiceWorkerRegistration*>(aListener);
|
||||
MOZ_ASSERT(domainInfo->mServiceWorkerRegistrations.Contains(registration));
|
||||
domainInfo->mServiceWorkerRegistrations.RemoveElement(registration);
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -8,11 +8,14 @@
|
|||
|
||||
#include "mozilla/dom/Promise.h"
|
||||
#include "mozilla/dom/ServiceWorkerRegistrationBinding.h"
|
||||
#include "mozilla/Services.h"
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "ServiceWorker.h"
|
||||
|
||||
#include "nsIObserverService.h"
|
||||
#include "nsIServiceWorkerManager.h"
|
||||
#include "nsISupportsPrimitives.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
|
||||
using namespace mozilla::dom::workers;
|
||||
|
@ -21,6 +24,7 @@ namespace mozilla {
|
|||
namespace dom {
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(ServiceWorkerRegistration)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIObserver)
|
||||
NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
|
||||
|
||||
NS_IMPL_ADDREF_INHERITED(ServiceWorkerRegistration, DOMEventTargetHelper)
|
||||
|
@ -37,11 +41,21 @@ ServiceWorkerRegistration::ServiceWorkerRegistration(nsPIDOMWindow* aWindow,
|
|||
const nsAString& aScope)
|
||||
: mWindow(aWindow)
|
||||
, mScope(aScope)
|
||||
, mInnerID(0)
|
||||
, mIsListeningForEvents(false)
|
||||
{
|
||||
MOZ_ASSERT(aWindow);
|
||||
MOZ_ASSERT(aWindow->IsInnerWindow());
|
||||
|
||||
SetIsDOMBinding();
|
||||
StartListeningForEvents();
|
||||
|
||||
mInnerID = aWindow->WindowID();
|
||||
|
||||
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
|
||||
if (obs) {
|
||||
obs->AddObserver(this, "inner-window-destroyed", false);
|
||||
}
|
||||
}
|
||||
|
||||
ServiceWorkerRegistration::~ServiceWorkerRegistration()
|
||||
|
@ -166,17 +180,25 @@ ServiceWorkerRegistration::InvalidateWorkerReference(WhichServiceWorker aWhichOn
|
|||
void
|
||||
ServiceWorkerRegistration::StartListeningForEvents()
|
||||
{
|
||||
MOZ_ASSERT(!mIsListeningForEvents);
|
||||
|
||||
nsCOMPtr<nsIServiceWorkerManager> swm = do_GetService(SERVICEWORKERMANAGER_CONTRACTID);
|
||||
MOZ_ASSERT(mWindow);
|
||||
|
||||
if (swm) {
|
||||
swm->AddRegistrationEventListener(GetDocumentURI(), this);
|
||||
}
|
||||
|
||||
mIsListeningForEvents = true;
|
||||
}
|
||||
|
||||
void
|
||||
ServiceWorkerRegistration::StopListeningForEvents()
|
||||
{
|
||||
if (!mIsListeningForEvents) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIServiceWorkerManager> swm = do_GetService(SERVICEWORKERMANAGER_CONTRACTID);
|
||||
|
||||
// StopListeningForEvents is called in the dtor, and it can happen that
|
||||
|
@ -184,6 +206,8 @@ ServiceWorkerRegistration::StopListeningForEvents()
|
|||
if (swm && mWindow) {
|
||||
swm->RemoveRegistrationEventListener(GetDocumentURI(), this);
|
||||
}
|
||||
|
||||
mIsListeningForEvents = false;
|
||||
}
|
||||
|
||||
nsIURI*
|
||||
|
@ -193,5 +217,37 @@ ServiceWorkerRegistration::GetDocumentURI() const
|
|||
return mWindow->GetDocumentURI();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ServiceWorkerRegistration::Observe(nsISupports* aSubject, const char* aTopic,
|
||||
const char16_t* aData)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (strcmp(aTopic, "inner-window-destroyed")) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (!mIsListeningForEvents) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsISupportsPRUint64> wrapper = do_QueryInterface(aSubject);
|
||||
NS_ENSURE_TRUE(wrapper, NS_ERROR_FAILURE);
|
||||
|
||||
uint64_t innerID;
|
||||
nsresult rv = wrapper->GetData(&innerID);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (innerID == mInnerID) {
|
||||
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
|
||||
if (obs) {
|
||||
obs->RemoveObserver(this, "inner-window-destroyed");
|
||||
}
|
||||
|
||||
StopListeningForEvents();
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
} // dom namespace
|
||||
} // mozilla namespace
|
||||
|
|
|
@ -22,9 +22,11 @@ class ServiceWorker;
|
|||
}
|
||||
|
||||
class ServiceWorkerRegistration MOZ_FINAL : public DOMEventTargetHelper
|
||||
, public nsIObserver
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_NSIOBSERVER
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(ServiceWorkerRegistration,
|
||||
DOMEventTargetHelper)
|
||||
|
||||
|
@ -91,6 +93,9 @@ private:
|
|||
nsRefPtr<workers::ServiceWorker> mActiveWorker;
|
||||
|
||||
const nsString mScope;
|
||||
|
||||
uint64_t mInnerID;
|
||||
bool mIsListeningForEvents;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
|
Загрузка…
Ссылка в новой задаче