mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 21:31:04 +00:00
Bug 1229056 - Implement ClientQueryOptions.includeUncontrolled; r=jdm
This commit is contained in:
parent
5ac100af7e
commit
6c4573cf9e
@ -181,11 +181,14 @@ class MatchAllRunnable final : public nsRunnable
|
||||
|
||||
RefPtr<PromiseWorkerProxy> mPromiseProxy;
|
||||
nsCString mScope;
|
||||
bool mIncludeUncontrolled;
|
||||
public:
|
||||
MatchAllRunnable(PromiseWorkerProxy* aPromiseProxy,
|
||||
const nsCString& aScope)
|
||||
const nsCString& aScope,
|
||||
bool aIncludeUncontrolled)
|
||||
: mPromiseProxy(aPromiseProxy),
|
||||
mScope(aScope)
|
||||
mScope(aScope),
|
||||
mIncludeUncontrolled(aIncludeUncontrolled)
|
||||
{
|
||||
MOZ_ASSERT(mPromiseProxy);
|
||||
}
|
||||
@ -203,7 +206,8 @@ public:
|
||||
RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
|
||||
nsTArray<ServiceWorkerClientInfo> result;
|
||||
|
||||
swm->GetAllClients(mPromiseProxy->GetWorkerPrivate()->GetPrincipal(), mScope, result);
|
||||
swm->GetAllClients(mPromiseProxy->GetWorkerPrivate()->GetPrincipal(), mScope,
|
||||
mIncludeUncontrolled, result);
|
||||
RefPtr<ResolvePromiseWorkerRunnable> r =
|
||||
new ResolvePromiseWorkerRunnable(mPromiseProxy->GetWorkerPrivate(),
|
||||
mPromiseProxy, result);
|
||||
@ -689,7 +693,7 @@ ServiceWorkerClients::MatchAll(const ClientQueryOptions& aOptions,
|
||||
nsString scope;
|
||||
mWorkerScope->GetScope(scope);
|
||||
|
||||
if (aOptions.mIncludeUncontrolled || aOptions.mType != ClientType::Window) {
|
||||
if (aOptions.mType != ClientType::Window) {
|
||||
aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
@ -708,7 +712,8 @@ ServiceWorkerClients::MatchAll(const ClientQueryOptions& aOptions,
|
||||
|
||||
RefPtr<MatchAllRunnable> r =
|
||||
new MatchAllRunnable(promiseProxy,
|
||||
NS_ConvertUTF16toUTF8(scope));
|
||||
NS_ConvertUTF16toUTF8(scope),
|
||||
aOptions.mIncludeUncontrolled);
|
||||
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(NS_DispatchToMainThread(r)));
|
||||
return promise.forget();
|
||||
}
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "nsINetworkInterceptController.h"
|
||||
#include "nsIMutableArray.h"
|
||||
#include "nsIScriptError.h"
|
||||
#include "nsISimpleEnumerator.h"
|
||||
#include "nsIUploadChannel2.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
#include "nsScriptLoader.h"
|
||||
@ -3760,7 +3761,8 @@ ServiceWorkerManager::GetClient(nsIPrincipal* aPrincipal,
|
||||
void
|
||||
ServiceWorkerManager::GetAllClients(nsIPrincipal* aPrincipal,
|
||||
const nsCString& aScope,
|
||||
nsTArray<ServiceWorkerClientInfo>& aControlledDocuments)
|
||||
bool aIncludeUncontrolled,
|
||||
nsTArray<ServiceWorkerClientInfo>& aDocuments)
|
||||
{
|
||||
MOZ_ASSERT(aPrincipal);
|
||||
|
||||
@ -3772,21 +3774,65 @@ ServiceWorkerManager::GetAllClients(nsIPrincipal* aPrincipal,
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto iter = mControlledDocuments.Iter(); !iter.Done(); iter.Next()) {
|
||||
ServiceWorkerRegistrationInfo* thisRegistration = iter.UserData();
|
||||
MOZ_ASSERT(thisRegistration);
|
||||
if (!registration->mScope.Equals(thisRegistration->mScope)) {
|
||||
continue;
|
||||
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
|
||||
if (NS_WARN_IF(!obs)) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsISimpleEnumerator> enumerator;
|
||||
nsresult rv = obs->EnumerateObservers("service-worker-get-client",
|
||||
getter_AddRefs(enumerator));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto ProcessDocument = [&aDocuments](nsIPrincipal* aPrincipal, nsIDocument* aDoc) {
|
||||
if (!aDoc || !aDoc->GetWindow()) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDocument> document = do_QueryInterface(iter.Key());
|
||||
|
||||
if (!document || !document->GetWindow()) {
|
||||
continue;
|
||||
bool equals = false;
|
||||
aPrincipal->Equals(aDoc->NodePrincipal(), &equals);
|
||||
if (!equals) {
|
||||
return;
|
||||
}
|
||||
|
||||
ServiceWorkerClientInfo clientInfo(document);
|
||||
aControlledDocuments.AppendElement(clientInfo);
|
||||
if (!Preferences::GetBool("dom.serviceWorkers.testing.enabled") &&
|
||||
!IsFromAuthenticatedOrigin(aDoc)) {
|
||||
return;
|
||||
}
|
||||
|
||||
ServiceWorkerClientInfo clientInfo(aDoc);
|
||||
aDocuments.AppendElement(aDoc);
|
||||
};
|
||||
|
||||
// Since it's not simple to check whether a document is in
|
||||
// mControlledDocuments, we take different code paths depending on whether we
|
||||
// need to look at all documents. The common parts of the two loops are
|
||||
// factored out into the ProcessDocument lambda.
|
||||
if (aIncludeUncontrolled) {
|
||||
bool loop = true;
|
||||
while (NS_SUCCEEDED(enumerator->HasMoreElements(&loop)) && loop) {
|
||||
nsCOMPtr<nsISupports> ptr;
|
||||
rv = enumerator->GetNext(getter_AddRefs(ptr));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDocument> doc = do_QueryInterface(ptr);
|
||||
ProcessDocument(aPrincipal, doc);
|
||||
}
|
||||
} else {
|
||||
for (auto iter = mControlledDocuments.Iter(); !iter.Done(); iter.Next()) {
|
||||
ServiceWorkerRegistrationInfo* thisRegistration = iter.UserData();
|
||||
MOZ_ASSERT(thisRegistration);
|
||||
if (!registration->mScope.Equals(thisRegistration->mScope)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDocument> doc = do_QueryInterface(iter.Key());
|
||||
ProcessDocument(aPrincipal, doc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -444,7 +444,8 @@ public:
|
||||
void
|
||||
GetAllClients(nsIPrincipal* aPrincipal,
|
||||
const nsCString& aScope,
|
||||
nsTArray<ServiceWorkerClientInfo>& aControlledDocuments);
|
||||
bool aIncludeUncontrolled,
|
||||
nsTArray<ServiceWorkerClientInfo>& aDocuments);
|
||||
|
||||
void
|
||||
MaybeClaimClient(nsIDocument* aDocument,
|
||||
|
@ -1,6 +0,0 @@
|
||||
[clients-matchall-include-uncontrolled.https.html]
|
||||
type: testharness
|
||||
expected: TIMEOUT
|
||||
[Verify matchAll() respect includeUncontrolled]
|
||||
expected: TIMEOUT
|
||||
|
@ -28,10 +28,10 @@ var expected_without_include_uncontrolled = [
|
||||
|
||||
var expected_with_include_uncontrolled = [
|
||||
/* visibilityState, focused, url, frameType */
|
||||
['visible', true, location.href, 'top-level'],
|
||||
['visible', false, new URL(scope + '#1', location).toString(), 'nested'],
|
||||
['visible', true, new URL(scope + '#2', location).toString(), 'nested'],
|
||||
['visible', false, new URL(base_url, location).toString(), 'nested'],
|
||||
['visible', true, location.href, 'top-level']
|
||||
['visible', false, new URL(base_url, location).toString(), 'nested']
|
||||
];
|
||||
|
||||
function test_matchall(frame, expected, query_options) {
|
||||
@ -42,9 +42,13 @@ function test_matchall(frame, expected, query_options) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
var channel = new MessageChannel();
|
||||
channel.port1.onmessage = function(e) {
|
||||
assert_equals(e.data.length, expected.length);
|
||||
for (var i = 0; i < e.data.length; i++)
|
||||
assert_array_equals(e.data[i], expected[i]);
|
||||
// Ignore hidden clients which may be coming from background tabs.
|
||||
var data = e.data.filter(function(info) {
|
||||
return info[0] == 'visible';
|
||||
});
|
||||
assert_equals(data.length, expected.length);
|
||||
for (var i = 0; i < data.length; i++)
|
||||
assert_array_equals(data[i], expected[i]);
|
||||
resolve(frame);
|
||||
};
|
||||
frame.contentWindow.navigator.serviceWorker.controller.postMessage(
|
||||
|
@ -5,10 +5,17 @@ self.onmessage = function(e) {
|
||||
self.clients.matchAll(options).then(function(clients) {
|
||||
var message = [];
|
||||
clients.forEach(function(client) {
|
||||
var frame_type = client.frameType;
|
||||
if (client.url.indexOf('clients-matchall-include-uncontrolled.https.html') > -1 &&
|
||||
client.frameType == 'auxiliary') {
|
||||
// The test tab might be opened using window.open() by the test framework.
|
||||
// In that case, just pretend it's top-level!
|
||||
frame_type = 'top-level';
|
||||
}
|
||||
message.push([client.visibilityState,
|
||||
client.focused,
|
||||
client.url,
|
||||
client.frameType]);
|
||||
frame_type]);
|
||||
});
|
||||
// Sort by url
|
||||
message.sort(function(a, b) { return a[2] > b[2] ? 1 : -1; });
|
||||
|
Loading…
Reference in New Issue
Block a user