Bug 1223116 P1 Expose nsIServiceWorkerManager.shouldReportToWindow(). r=catalinb

This commit is contained in:
Ben Kelly 2015-11-16 08:04:11 -08:00
parent 97d4a51a9f
commit bc775ef754
2 changed files with 122 additions and 1 deletions

View File

@ -59,7 +59,7 @@ interface nsIServiceWorkerManagerListener : nsISupports
void onUnregister(in nsIServiceWorkerRegistrationInfo aInfo);
};
[scriptable, builtinclass, uuid(2f61820a-1e9a-4c16-bf1c-ce182c5f5d6d)]
[scriptable, builtinclass, uuid(c945e2e6-30c2-48e6-a282-e69de0c7ebb1)]
interface nsIServiceWorkerManager : nsISupports
{
/**
@ -174,6 +174,8 @@ interface nsIServiceWorkerManager : nsISupports
void addListener(in nsIServiceWorkerManagerListener aListener);
void removeListener(in nsIServiceWorkerManagerListener aListener);
bool shouldReportToWindow(in nsIDOMWindow aWindow, in ACString aScope);
};
%{ C++

View File

@ -4091,6 +4091,125 @@ ServiceWorkerManager::RemoveListener(nsIServiceWorkerManagerListener* aListener)
return NS_OK;
}
NS_IMETHODIMP
ServiceWorkerManager::ShouldReportToWindow(nsIDOMWindow* aWindow,
const nsACString& aScope,
bool* aResult)
{
AssertIsOnMainThread();
MOZ_ASSERT(aResult);
*aResult = false;
// Get the inner window ID to compare to our document windows below.
nsCOMPtr<nsPIDOMWindow> targetWin = do_QueryInterface(aWindow);
if (NS_WARN_IF(!targetWin)) {
return NS_OK;
}
targetWin = targetWin->GetScriptableTop();
uint64_t winId = targetWin->WindowID();
// Check our weak registering document references first. This way we clear
// out as many dead weak references as possible when this method is called.
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;
}
if (!doc->IsCurrentActiveDocument()) {
continue;
}
nsCOMPtr<nsPIDOMWindow> win = doc->GetWindow();
if (!win) {
continue;
}
win = win->GetScriptableTop();
// Match. We should report to this window.
if (win && winId == win->WindowID()) {
*aResult = true;
return NS_OK;
}
}
if (list->IsEmpty()) {
list = nullptr;
nsAutoPtr<WeakDocumentList> doomed;
mRegisteringDocuments.RemoveAndForget(aScope, doomed);
}
}
// Examine any windows performing a navigation that we are currently
// intercepting.
InterceptionList* intList = mNavigationInterceptions.Get(aScope);
if (intList) {
for (uint32_t i = 0; i < intList->Length(); ++i) {
nsCOMPtr<nsIInterceptedChannel> channel = intList->ElementAt(i);
nsCOMPtr<nsIChannel> inner;
nsresult rv = channel->GetChannel(getter_AddRefs(inner));
if (NS_WARN_IF(NS_FAILED(rv))) {
continue;
}
uint64_t id = nsContentUtils::GetInnerWindowID(inner);
if (id == 0) {
continue;
}
nsCOMPtr<nsPIDOMWindow> win = nsGlobalWindow::GetInnerWindowWithId(id);
if (!win) {
continue;
}
win = win->GetScriptableTop();
// Match. We should report to this window.
if (win && winId == win->WindowID()) {
*aResult = true;
return NS_OK;
}
}
}
// Next examine controlled documents to see if the windows match.
for (auto iter = mControlledDocuments.Iter(); !iter.Done(); iter.Next()) {
ServiceWorkerRegistrationInfo* reg = iter.UserData();
MOZ_ASSERT(reg);
if (!reg->mScope.Equals(aScope)) {
continue;
}
nsCOMPtr<nsIDocument> doc = do_QueryInterface(iter.Key());
if (!doc || !doc->IsCurrentActiveDocument()) {
continue;
}
nsCOMPtr<nsPIDOMWindow> win = doc->GetWindow();
if (!win) {
continue;
}
win = win->GetScriptableTop();
// Match. We should report to this window.
if (win && winId == win->WindowID()) {
*aResult = true;
return NS_OK;
}
}
// No match. We should not report to this window.
return NS_OK;
}
NS_IMETHODIMP
ServiceWorkerManager::Observe(nsISupports* aSubject,
const char* aTopic,