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;
|
RefPtr<PromiseWorkerProxy> mPromiseProxy;
|
||||||
nsCString mScope;
|
nsCString mScope;
|
||||||
|
bool mIncludeUncontrolled;
|
||||||
public:
|
public:
|
||||||
MatchAllRunnable(PromiseWorkerProxy* aPromiseProxy,
|
MatchAllRunnable(PromiseWorkerProxy* aPromiseProxy,
|
||||||
const nsCString& aScope)
|
const nsCString& aScope,
|
||||||
|
bool aIncludeUncontrolled)
|
||||||
: mPromiseProxy(aPromiseProxy),
|
: mPromiseProxy(aPromiseProxy),
|
||||||
mScope(aScope)
|
mScope(aScope),
|
||||||
|
mIncludeUncontrolled(aIncludeUncontrolled)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(mPromiseProxy);
|
MOZ_ASSERT(mPromiseProxy);
|
||||||
}
|
}
|
||||||
@ -203,7 +206,8 @@ public:
|
|||||||
RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
|
RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
|
||||||
nsTArray<ServiceWorkerClientInfo> result;
|
nsTArray<ServiceWorkerClientInfo> result;
|
||||||
|
|
||||||
swm->GetAllClients(mPromiseProxy->GetWorkerPrivate()->GetPrincipal(), mScope, result);
|
swm->GetAllClients(mPromiseProxy->GetWorkerPrivate()->GetPrincipal(), mScope,
|
||||||
|
mIncludeUncontrolled, result);
|
||||||
RefPtr<ResolvePromiseWorkerRunnable> r =
|
RefPtr<ResolvePromiseWorkerRunnable> r =
|
||||||
new ResolvePromiseWorkerRunnable(mPromiseProxy->GetWorkerPrivate(),
|
new ResolvePromiseWorkerRunnable(mPromiseProxy->GetWorkerPrivate(),
|
||||||
mPromiseProxy, result);
|
mPromiseProxy, result);
|
||||||
@ -689,7 +693,7 @@ ServiceWorkerClients::MatchAll(const ClientQueryOptions& aOptions,
|
|||||||
nsString scope;
|
nsString scope;
|
||||||
mWorkerScope->GetScope(scope);
|
mWorkerScope->GetScope(scope);
|
||||||
|
|
||||||
if (aOptions.mIncludeUncontrolled || aOptions.mType != ClientType::Window) {
|
if (aOptions.mType != ClientType::Window) {
|
||||||
aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
|
aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@ -708,7 +712,8 @@ ServiceWorkerClients::MatchAll(const ClientQueryOptions& aOptions,
|
|||||||
|
|
||||||
RefPtr<MatchAllRunnable> r =
|
RefPtr<MatchAllRunnable> r =
|
||||||
new MatchAllRunnable(promiseProxy,
|
new MatchAllRunnable(promiseProxy,
|
||||||
NS_ConvertUTF16toUTF8(scope));
|
NS_ConvertUTF16toUTF8(scope),
|
||||||
|
aOptions.mIncludeUncontrolled);
|
||||||
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(NS_DispatchToMainThread(r)));
|
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(NS_DispatchToMainThread(r)));
|
||||||
return promise.forget();
|
return promise.forget();
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
#include "nsINetworkInterceptController.h"
|
#include "nsINetworkInterceptController.h"
|
||||||
#include "nsIMutableArray.h"
|
#include "nsIMutableArray.h"
|
||||||
#include "nsIScriptError.h"
|
#include "nsIScriptError.h"
|
||||||
|
#include "nsISimpleEnumerator.h"
|
||||||
#include "nsIUploadChannel2.h"
|
#include "nsIUploadChannel2.h"
|
||||||
#include "nsPIDOMWindow.h"
|
#include "nsPIDOMWindow.h"
|
||||||
#include "nsScriptLoader.h"
|
#include "nsScriptLoader.h"
|
||||||
@ -3760,7 +3761,8 @@ ServiceWorkerManager::GetClient(nsIPrincipal* aPrincipal,
|
|||||||
void
|
void
|
||||||
ServiceWorkerManager::GetAllClients(nsIPrincipal* aPrincipal,
|
ServiceWorkerManager::GetAllClients(nsIPrincipal* aPrincipal,
|
||||||
const nsCString& aScope,
|
const nsCString& aScope,
|
||||||
nsTArray<ServiceWorkerClientInfo>& aControlledDocuments)
|
bool aIncludeUncontrolled,
|
||||||
|
nsTArray<ServiceWorkerClientInfo>& aDocuments)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(aPrincipal);
|
MOZ_ASSERT(aPrincipal);
|
||||||
|
|
||||||
@ -3772,21 +3774,65 @@ ServiceWorkerManager::GetAllClients(nsIPrincipal* aPrincipal,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto iter = mControlledDocuments.Iter(); !iter.Done(); iter.Next()) {
|
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
|
||||||
ServiceWorkerRegistrationInfo* thisRegistration = iter.UserData();
|
if (NS_WARN_IF(!obs)) {
|
||||||
MOZ_ASSERT(thisRegistration);
|
return;
|
||||||
if (!registration->mScope.Equals(thisRegistration->mScope)) {
|
}
|
||||||
continue;
|
|
||||||
|
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());
|
bool equals = false;
|
||||||
|
aPrincipal->Equals(aDoc->NodePrincipal(), &equals);
|
||||||
if (!document || !document->GetWindow()) {
|
if (!equals) {
|
||||||
continue;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ServiceWorkerClientInfo clientInfo(document);
|
if (!Preferences::GetBool("dom.serviceWorkers.testing.enabled") &&
|
||||||
aControlledDocuments.AppendElement(clientInfo);
|
!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
|
void
|
||||||
GetAllClients(nsIPrincipal* aPrincipal,
|
GetAllClients(nsIPrincipal* aPrincipal,
|
||||||
const nsCString& aScope,
|
const nsCString& aScope,
|
||||||
nsTArray<ServiceWorkerClientInfo>& aControlledDocuments);
|
bool aIncludeUncontrolled,
|
||||||
|
nsTArray<ServiceWorkerClientInfo>& aDocuments);
|
||||||
|
|
||||||
void
|
void
|
||||||
MaybeClaimClient(nsIDocument* aDocument,
|
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 = [
|
var expected_with_include_uncontrolled = [
|
||||||
/* visibilityState, focused, url, frameType */
|
/* visibilityState, focused, url, frameType */
|
||||||
|
['visible', true, location.href, 'top-level'],
|
||||||
['visible', false, new URL(scope + '#1', location).toString(), 'nested'],
|
['visible', false, new URL(scope + '#1', location).toString(), 'nested'],
|
||||||
['visible', true, new URL(scope + '#2', location).toString(), 'nested'],
|
['visible', true, new URL(scope + '#2', location).toString(), 'nested'],
|
||||||
['visible', false, new URL(base_url, location).toString(), 'nested'],
|
['visible', false, new URL(base_url, location).toString(), 'nested']
|
||||||
['visible', true, location.href, 'top-level']
|
|
||||||
];
|
];
|
||||||
|
|
||||||
function test_matchall(frame, expected, query_options) {
|
function test_matchall(frame, expected, query_options) {
|
||||||
@ -42,9 +42,13 @@ function test_matchall(frame, expected, query_options) {
|
|||||||
return new Promise(function(resolve, reject) {
|
return new Promise(function(resolve, reject) {
|
||||||
var channel = new MessageChannel();
|
var channel = new MessageChannel();
|
||||||
channel.port1.onmessage = function(e) {
|
channel.port1.onmessage = function(e) {
|
||||||
assert_equals(e.data.length, expected.length);
|
// Ignore hidden clients which may be coming from background tabs.
|
||||||
for (var i = 0; i < e.data.length; i++)
|
var data = e.data.filter(function(info) {
|
||||||
assert_array_equals(e.data[i], expected[i]);
|
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);
|
resolve(frame);
|
||||||
};
|
};
|
||||||
frame.contentWindow.navigator.serviceWorker.controller.postMessage(
|
frame.contentWindow.navigator.serviceWorker.controller.postMessage(
|
||||||
|
@ -5,10 +5,17 @@ self.onmessage = function(e) {
|
|||||||
self.clients.matchAll(options).then(function(clients) {
|
self.clients.matchAll(options).then(function(clients) {
|
||||||
var message = [];
|
var message = [];
|
||||||
clients.forEach(function(client) {
|
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,
|
message.push([client.visibilityState,
|
||||||
client.focused,
|
client.focused,
|
||||||
client.url,
|
client.url,
|
||||||
client.frameType]);
|
frame_type]);
|
||||||
});
|
});
|
||||||
// Sort by url
|
// Sort by url
|
||||||
message.sort(function(a, b) { return a[2] > b[2] ? 1 : -1; });
|
message.sort(function(a, b) { return a[2] > b[2] ? 1 : -1; });
|
||||||
|
Loading…
Reference in New Issue
Block a user