Bug 1217909 P2 Track registering documents as weak reference so SWM can report errors to them. r=catalinb

This commit is contained in:
Ben Kelly 2015-11-16 08:04:11 -08:00
parent 0ed576ed62
commit b21fcda909
2 changed files with 83 additions and 1 deletions

View File

@ -1577,6 +1577,8 @@ ServiceWorkerManager::Register(nsIDOMWindow* aWindow,
return rv;
}
AddRegisteringDocument(cleanedScope, doc);
ServiceWorkerJobQueue* queue = GetOrCreateJobQueue(originSuffix, cleanedScope);
MOZ_ASSERT(queue);
@ -2414,7 +2416,9 @@ ServiceWorkerManager::ReportToAllClients(const nsCString& aScope,
return;
}
// Report errors to the consoles of every controlled document
nsAutoTArray<uint64_t, 16> windows;
// Report errors to every controlled document.
for (auto iter = mControlledDocuments.Iter(); !iter.Done(); iter.Next()) {
ServiceWorkerRegistrationInfo* reg = iter.UserData();
MOZ_ASSERT(reg);
@ -2427,6 +2431,8 @@ ServiceWorkerManager::ReportToAllClients(const nsCString& aScope,
continue;
}
windows.AppendElement(doc->InnerWindowID());
nsContentUtils::ReportToConsoleNonLocalized(aMessage,
aFlags,
NS_LITERAL_CSTRING("Service Workers"),
@ -2436,6 +2442,49 @@ ServiceWorkerManager::ReportToAllClients(const nsCString& aScope,
aLineNumber,
aColumnNumber);
}
// Report to any documents that have called .register() for this scope. They
// may not be controlled, but will still want to see error reports.
WeakDocumentList* list = mRegisteringDocuments.Get(aScope);
if (list) {
for (int32_t i = list->Length() - 1; i >= 0; --i) {
nsCOMPtr<nsIDocument> doc = do_QueryReferent(list->ElementAt(i));
if (!doc) {
list->RemoveElementAt(i);
continue;
}
uint64_t innerWindowId = doc->InnerWindowID();
if (windows.Contains(innerWindowId)) {
continue;
}
windows.AppendElement(innerWindowId);
nsContentUtils::ReportToConsoleNonLocalized(aMessage,
aFlags,
NS_LITERAL_CSTRING("Service Workers"),
doc,
uri,
aLine,
aLineNumber,
aColumnNumber);
}
}
// If there are no documents to report to, at least report something to the
// browser console.
if (windows.IsEmpty()) {
nsContentUtils::ReportToConsoleNonLocalized(aMessage,
aFlags,
NS_LITERAL_CSTRING("Service Workers"),
nullptr, // document
uri,
aLine,
aLineNumber,
aColumnNumber);
return;
}
}
void
@ -4129,6 +4178,31 @@ ServiceWorkerManager::NotifyListenersOnUnregister(
}
}
void
ServiceWorkerManager::AddRegisteringDocument(const nsACString& aScope,
nsIDocument* aDoc)
{
AssertIsOnMainThread();
MOZ_ASSERT(!aScope.IsEmpty());
MOZ_ASSERT(aDoc);
WeakDocumentList* list = mRegisteringDocuments.LookupOrAdd(aScope);
MOZ_ASSERT(list);
for (int32_t i = list->Length() - 1; i >= 0; --i) {
nsCOMPtr<nsIDocument> existing = do_QueryReferent(list->ElementAt(i));
if (!existing) {
list->RemoveElementAt(i);
continue;
}
if (existing == aDoc) {
return;
}
}
list->AppendElement(do_GetWeakReference(aDoc));
}
NS_IMPL_ISUPPORTS(ServiceWorkerInfo, nsIServiceWorkerInfo)
NS_IMETHODIMP

View File

@ -329,6 +329,11 @@ public:
// Set of all documents that may be controlled by a service worker.
nsTHashtable<nsISupportsHashKey> mAllDocuments;
// Track all documents that have attempted to register a service worker for a
// given scope.
typedef nsTArray<nsCOMPtr<nsIWeakReference>> WeakDocumentList;
nsClassHashtable<nsCStringHashKey, WeakDocumentList> mRegisteringDocuments;
bool
IsAvailable(const OriginAttributes& aOriginAttributes, nsIURI* aURI);
@ -620,6 +625,9 @@ private:
void
NotifyListenersOnUnregister(nsIServiceWorkerRegistrationInfo* aRegistration);
void
AddRegisteringDocument(const nsACString& aScope, nsIDocument* aDoc);
};
} // namespace workers