Bug 1058311 - Update client interface. Implement matchAll WindowClient. r=baku

This commit is contained in:
Catalin Badea 2015-03-06 15:04:49 +02:00
parent d61b6923ca
commit c230b69ed6
20 changed files with 472 additions and 54 deletions

View File

@ -670,6 +670,26 @@ public:
mCleanedUp);
}
bool
HadOriginalOpener() const
{
MOZ_ASSERT(IsOuterWindow());
return mHadOriginalOpener;
}
bool
IsTopLevelWindow()
{
MOZ_ASSERT(IsOuterWindow());
nsCOMPtr<nsIDOMWindow> parentWindow;
nsresult rv = GetScriptableTop(getter_AddRefs(parentWindow));
if (NS_WARN_IF(NS_FAILED(rv))) {
return false;
}
return parentWindow == static_cast<nsIDOMWindow*>(this);
}
virtual void
FirePopupBlockedEvent(nsIDocument* aDoc,
nsIURI* aPopupURI,

View File

@ -1270,6 +1270,11 @@ DOMInterfaces = {
'nativeType': 'mozilla::dom::TextTrackRegion',
},
'WindowClient': {
'nativeType': 'mozilla::dom::workers::ServiceWorkerWindowClient',
'headerFile': 'mozilla/dom/workers/bindings/ServiceWorkerWindowClient.h',
},
'WebGLActiveInfo': {
'nativeType': 'mozilla::WebGLActiveInfo',
'headerFile': 'WebGLActiveInfo.h'

View File

@ -10,8 +10,23 @@
[Exposed=ServiceWorker]
interface Client {
readonly attribute unsigned long id;
readonly attribute USVString url;
[Throws]
void postMessage(any message, optional sequence<Transferable> transfer);
};
[Exposed=ServiceWorker]
interface WindowClient : Client {
readonly attribute VisibilityState visibilityState;
readonly attribute boolean focused;
readonly attribute FrameType frameType;
Promise<WindowClient> focus();
};
enum FrameType {
"auxiliary",
"top-level",
"nested",
"none"
};

View File

@ -10,10 +10,11 @@
[Exposed=ServiceWorker]
interface Clients {
// A list of client objects, identifiable by ID, that correspond to windows
// (or workers) that are "controlled" by this SW
// The objects returned will be new instances every time
[Throws]
Promise<sequence<Client>?> matchAll(optional ClientQueryOptions options);
Promise<WindowClient> openWindow(USVString url);
Promise<void> claim();
};
dictionary ClientQueryOptions {

View File

@ -12,7 +12,9 @@
Exposed=(ServiceWorker)]
interface FetchEvent : Event {
readonly attribute Request request;
readonly attribute Client client; // The window issuing the request.
// https://github.com/slightlyoff/ServiceWorker/issues/631
readonly attribute Client? client; // The window issuing the request.
readonly attribute boolean isReload;
[Throws] void respondWith(Promise<Response> r);

View File

@ -9,10 +9,9 @@
#include "mozilla/dom/MessageEvent.h"
#include "nsGlobalWindow.h"
#include "nsIDocument.h"
#include "WorkerPrivate.h"
#include "mozilla/dom/ClientBinding.h"
using namespace mozilla;
using namespace mozilla::dom;
using namespace mozilla::dom::workers;
@ -27,6 +26,31 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ServiceWorkerClient)
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END
ServiceWorkerClientInfo::ServiceWorkerClientInfo(nsIDocument* aDoc)
{
MOZ_ASSERT(aDoc);
MOZ_ASSERT(aDoc->GetWindow());
nsRefPtr<nsGlobalWindow> outerWindow = static_cast<nsGlobalWindow*>(aDoc->GetWindow());
mClientId = outerWindow->WindowID();
aDoc->GetURL(mUrl);
mVisibilityState = aDoc->VisibilityState();
ErrorResult result;
mFocused = aDoc->HasFocus(result);
if (result.Failed()) {
NS_WARNING("Failed to get focus information.");
}
if (!outerWindow->IsTopLevelWindow()) {
mFrameType = FrameType::Nested;
} else if (outerWindow->HadOriginalOpener()) {
mFrameType = FrameType::Auxiliary;
} else {
mFrameType = FrameType::Top_level;
}
}
JSObject*
ServiceWorkerClient::WrapObject(JSContext* aCx)
{
@ -55,7 +79,7 @@ public:
Run()
{
AssertIsOnMainThread();
nsGlobalWindow* window = nsGlobalWindow::GetInnerWindowWithId(mId);
nsGlobalWindow* window = nsGlobalWindow::GetOuterWindowWithId(mId);
if (!window) {
return NS_ERROR_FAILURE;
}

View File

@ -11,47 +11,78 @@
#include "nsWrapperCache.h"
#include "mozilla/ErrorResult.h"
#include "mozilla/dom/BindingDeclarations.h"
#include "mozilla/dom/ClientBinding.h"
namespace mozilla {
namespace dom {
namespace workers {
class ServiceWorkerClient MOZ_FINAL : public nsISupports,
public nsWrapperCache
class ServiceWorkerClient;
class ServiceWorkerWindowClient;
// Used as a container object for information needed to create
// client objects.
class ServiceWorkerClientInfo MOZ_FINAL
{
friend class ServiceWorkerClient;
friend class ServiceWorkerWindowClient;
public:
explicit ServiceWorkerClientInfo(nsIDocument* aDoc);
private:
uint64_t mClientId;
nsString mUrl;
// Window Clients
VisibilityState mVisibilityState;
bool mFocused;
FrameType mFrameType;
};
class ServiceWorkerClient : public nsISupports,
public nsWrapperCache
{
public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(ServiceWorkerClient)
ServiceWorkerClient(nsISupports* aOwner, uint64_t aId)
ServiceWorkerClient(nsISupports* aOwner,
const ServiceWorkerClientInfo& aClientInfo)
: mOwner(aOwner),
mId(aId)
mId(aClientInfo.mClientId),
mUrl(aClientInfo.mUrl)
{
MOZ_ASSERT(aOwner);
}
uint32_t Id() const
{
return mId;
}
nsISupports* GetParentObject() const
nsISupports*
GetParentObject() const
{
return mOwner;
}
void PostMessage(JSContext* aCx, JS::Handle<JS::Value> aMessage,
const Optional<Sequence<JS::Value>>& aTransferable,
ErrorResult& aRv);
void
GetUrl(nsAString& aUrl) const
{
aUrl.Assign(mUrl);
}
void
PostMessage(JSContext* aCx, JS::Handle<JS::Value> aMessage,
const Optional<Sequence<JS::Value>>& aTransferable,
ErrorResult& aRv);
JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
private:
~ServiceWorkerClient()
{
}
protected:
virtual ~ServiceWorkerClient()
{ }
private:
nsCOMPtr<nsISupports> mOwner;
uint64_t mId;
nsString mUrl;
};
} // namespace workers

View File

@ -8,6 +8,7 @@
#include "ServiceWorkerClient.h"
#include "ServiceWorkerClients.h"
#include "ServiceWorkerManager.h"
#include "ServiceWorkerWindowClient.h"
#include "WorkerPrivate.h"
#include "WorkerRunnable.h"
@ -122,17 +123,17 @@ private:
class ResolvePromiseWorkerRunnable MOZ_FINAL : public WorkerRunnable
{
nsRefPtr<PromiseHolder> mPromiseHolder;
nsAutoPtr<nsTArray<uint64_t>> mValue;
nsTArray<ServiceWorkerClientInfo> mValue;
public:
ResolvePromiseWorkerRunnable(WorkerPrivate* aWorkerPrivate,
PromiseHolder* aPromiseHolder,
nsAutoPtr<nsTArray<uint64_t>>& aValue)
nsTArray<ServiceWorkerClientInfo>& aValue)
: WorkerRunnable(aWorkerPrivate, WorkerThreadModifyBusyCount),
mPromiseHolder(aPromiseHolder),
mValue(aValue)
mPromiseHolder(aPromiseHolder)
{
AssertIsOnMainThread();
mValue.SwapElements(aValue);
}
bool
@ -145,10 +146,10 @@ public:
MOZ_ASSERT(promise);
nsTArray<nsRefPtr<ServiceWorkerClient>> ret;
for (size_t i = 0; i < mValue->Length(); i++) {
for (size_t i = 0; i < mValue.Length(); i++) {
ret.AppendElement(nsRefPtr<ServiceWorkerClient>(
new ServiceWorkerClient(promise->GetParentObject(),
mValue->ElementAt(i))));
new ServiceWorkerWindowClient(promise->GetParentObject(),
mValue.ElementAt(i))));
}
promise->MaybeResolve(ret);
@ -216,7 +217,7 @@ public:
}
nsRefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
nsAutoPtr<nsTArray<uint64_t>> result(new nsTArray<uint64_t>());
nsTArray<ServiceWorkerClientInfo> result;
swm->GetAllClients(mScope, result);
nsRefPtr<ResolvePromiseWorkerRunnable> r =
@ -282,3 +283,29 @@ ServiceWorkerClients::MatchAll(const ClientQueryOptions& aOptions,
return promise.forget();
}
already_AddRefed<Promise>
ServiceWorkerClients::OpenWindow(const nsAString& aUrl)
{
ErrorResult result;
nsRefPtr<Promise> promise = Promise::Create(mWorkerScope, result);
if (NS_WARN_IF(result.Failed())) {
return nullptr;
}
promise->MaybeReject(NS_ERROR_NOT_AVAILABLE);
return promise.forget();
}
already_AddRefed<Promise>
ServiceWorkerClients::Claim()
{
ErrorResult result;
nsRefPtr<Promise> promise = Promise::Create(mWorkerScope, result);
if (NS_WARN_IF(result.Failed())) {
return nullptr;
}
promise->MaybeReject(NS_ERROR_NOT_AVAILABLE);
return promise.forget();
}

View File

@ -31,6 +31,12 @@ public:
already_AddRefed<Promise>
MatchAll(const ClientQueryOptions& aOptions, ErrorResult& aRv);
already_AddRefed<Promise>
OpenWindow(const nsAString& aUrl);
already_AddRefed<Promise>
Claim();
JSObject*
WrapObject(JSContext* aCx) MOZ_OVERRIDE;

View File

@ -28,7 +28,6 @@ BEGIN_WORKERS_NAMESPACE
FetchEvent::FetchEvent(EventTarget* aOwner)
: Event(aOwner, nullptr, nullptr)
, mWindowId(0)
, mIsReload(false)
, mWaitToRespond(false)
{
@ -41,11 +40,11 @@ FetchEvent::~FetchEvent()
void
FetchEvent::PostInit(nsMainThreadPtrHandle<nsIInterceptedChannel>& aChannel,
nsMainThreadPtrHandle<ServiceWorker>& aServiceWorker,
uint64_t aWindowId)
nsAutoPtr<ServiceWorkerClientInfo>& aClientInfo)
{
mChannel = aChannel;
mServiceWorker = aServiceWorker;
mWindowId = aWindowId;
mClientInfo = aClientInfo;
}
/*static*/ already_AddRefed<FetchEvent>
@ -244,10 +243,14 @@ FetchEvent::RespondWith(Promise& aPromise, ErrorResult& aRv)
}
already_AddRefed<ServiceWorkerClient>
FetchEvent::Client()
FetchEvent::GetClient()
{
if (!mClient) {
mClient = new ServiceWorkerClient(GetParentObject(), mWindowId);
if (!mClientInfo) {
return nullptr;
}
mClient = new ServiceWorkerClient(GetParentObject(), *mClientInfo);
}
nsRefPtr<ServiceWorkerClient> client = mClient;
return client.forget();

View File

@ -32,7 +32,7 @@ class FetchEvent MOZ_FINAL : public Event
nsMainThreadPtrHandle<ServiceWorker> mServiceWorker;
nsRefPtr<ServiceWorkerClient> mClient;
nsRefPtr<Request> mRequest;
uint64_t mWindowId;
nsAutoPtr<ServiceWorkerClientInfo> mClientInfo;
bool mIsReload;
bool mWaitToRespond;
protected:
@ -51,7 +51,7 @@ public:
void PostInit(nsMainThreadPtrHandle<nsIInterceptedChannel>& aChannel,
nsMainThreadPtrHandle<ServiceWorker>& aServiceWorker,
uint64_t aWindowId);
nsAutoPtr<ServiceWorkerClientInfo>& aClientInfo);
static already_AddRefed<FetchEvent>
Constructor(const GlobalObject& aGlobal,
@ -72,7 +72,7 @@ public:
}
already_AddRefed<ServiceWorkerClient>
Client();
GetClient();
bool
IsReload() const

View File

@ -2088,7 +2088,7 @@ class FetchEventRunnable : public WorkerRunnable
nsMainThreadPtrHandle<ServiceWorker> mServiceWorker;
nsTArray<nsCString> mHeaderNames;
nsTArray<nsCString> mHeaderValues;
uint64_t mWindowId;
nsAutoPtr<ServiceWorkerClientInfo> mClientInfo;
nsCString mSpec;
nsCString mMethod;
bool mIsReload;
@ -2096,11 +2096,11 @@ public:
FetchEventRunnable(WorkerPrivate* aWorkerPrivate,
nsMainThreadPtrHandle<nsIInterceptedChannel>& aChannel,
nsMainThreadPtrHandle<ServiceWorker>& aServiceWorker,
uint64_t aWindowId)
nsAutoPtr<ServiceWorkerClientInfo>& aClientInfo)
: WorkerRunnable(aWorkerPrivate, WorkerThreadModifyBusyCount)
, mInterceptedChannel(aChannel)
, mServiceWorker(aServiceWorker)
, mWindowId(aWindowId)
, mClientInfo(aClientInfo)
{
MOZ_ASSERT(aWorkerPrivate);
}
@ -2225,7 +2225,7 @@ private:
return false;
}
event->PostInit(mInterceptedChannel, mServiceWorker, mWindowId);
event->PostInit(mInterceptedChannel, mServiceWorker, mClientInfo);
event->SetTrusted(true);
nsRefPtr<EventTarget> target = do_QueryObject(aWorkerPrivate->GlobalScope());
@ -2250,9 +2250,12 @@ ServiceWorkerManager::DispatchFetchEvent(nsIDocument* aDoc, nsIInterceptedChanne
nsresult rv = aChannel->GetIsNavigation(&isNavigation);
NS_ENSURE_SUCCESS(rv, rv);
nsAutoPtr<ServiceWorkerClientInfo> clientInfo;
if (!isNavigation) {
MOZ_ASSERT(aDoc);
rv = GetDocumentController(aDoc->GetInnerWindow(), getter_AddRefs(serviceWorker));
clientInfo = new ServiceWorkerClientInfo(aDoc);
} else {
nsCOMPtr<nsIChannel> internalChannel;
rv = aChannel->GetChannel(getter_AddRefs(internalChannel));
@ -2282,14 +2285,13 @@ ServiceWorkerManager::DispatchFetchEvent(nsIDocument* aDoc, nsIInterceptedChanne
nsMainThreadPtrHandle<nsIInterceptedChannel> handle(
new nsMainThreadPtrHolder<nsIInterceptedChannel>(aChannel, false));
uint64_t windowId = aDoc ? aDoc->GetInnerWindow()->WindowID() : 0;
nsRefPtr<ServiceWorker> sw = static_cast<ServiceWorker*>(serviceWorker.get());
nsMainThreadPtrHandle<ServiceWorker> serviceWorkerHandle(
new nsMainThreadPtrHolder<ServiceWorker>(sw));
// clientInfo is null if we don't have a controlled document
nsRefPtr<FetchEventRunnable> event =
new FetchEventRunnable(sw->GetWorkerPrivate(), handle, serviceWorkerHandle, windowId);
new FetchEventRunnable(sw->GetWorkerPrivate(), handle, serviceWorkerHandle, clientInfo);
rv = event->Init();
NS_ENSURE_SUCCESS(rv, rv);
@ -2519,14 +2521,14 @@ namespace {
class MOZ_STACK_CLASS FilterRegistrationData
{
public:
FilterRegistrationData(nsTArray<uint64_t>* aDocuments,
ServiceWorkerRegistrationInfo* aRegistration)
FilterRegistrationData(nsTArray<ServiceWorkerClientInfo>& aDocuments,
ServiceWorkerRegistrationInfo* aRegistration)
: mDocuments(aDocuments),
mRegistration(aRegistration)
{
}
nsTArray<uint64_t>* mDocuments;
nsTArray<ServiceWorkerClientInfo>& mDocuments;
nsRefPtr<ServiceWorkerRegistrationInfo> mRegistration;
};
@ -2539,12 +2541,16 @@ EnumControlledDocuments(nsISupports* aKey,
if (data->mRegistration != aRegistration) {
return PL_DHASH_NEXT;
}
nsCOMPtr<nsIDocument> document = do_QueryInterface(aKey);
if (!document || !document->GetInnerWindow()) {
if (!document || !document->GetWindow()) {
return PL_DHASH_NEXT;
}
data->mDocuments->AppendElement(document->GetInnerWindow()->WindowID());
ServiceWorkerClientInfo clientInfo(document);
data->mDocuments.AppendElement(clientInfo);
return PL_DHASH_NEXT;
}
@ -2591,7 +2597,7 @@ FireControllerChangeOnMatchingDocument(nsISupports* aKey,
void
ServiceWorkerManager::GetAllClients(const nsCString& aScope,
nsTArray<uint64_t>* aControlledDocuments)
nsTArray<ServiceWorkerClientInfo>& aControlledDocuments)
{
nsRefPtr<ServiceWorkerRegistrationInfo> registration = GetRegistration(aScope);

View File

@ -43,6 +43,7 @@ class ServiceWorkerRegistration;
namespace workers {
class ServiceWorker;
class ServiceWorkerClientInfo;
class ServiceWorkerInfo;
class ServiceWorkerJobQueue;
@ -379,7 +380,7 @@ public:
void
GetAllClients(const nsCString& aScope,
nsTArray<uint64_t>* aControlledDocuments);
nsTArray<ServiceWorkerClientInfo>& aControlledDocuments);
static already_AddRefed<ServiceWorkerManager>
GetInstance();

View File

@ -0,0 +1,34 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#include "ServiceWorkerWindowClient.h"
#include "mozilla/dom/ClientBinding.h"
using namespace mozilla::dom;
using namespace mozilla::dom::workers;
JSObject*
ServiceWorkerWindowClient::WrapObject(JSContext* aCx)
{
return WindowClientBinding::Wrap(aCx, this);
}
already_AddRefed<Promise>
ServiceWorkerWindowClient::Focus() const
{
ErrorResult result;
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(GetParentObject());
MOZ_ASSERT(global);
nsRefPtr<Promise> promise = Promise::Create(global, result);
if (NS_WARN_IF(result.Failed())) {
return nullptr;
}
promise->MaybeReject(NS_ERROR_NOT_AVAILABLE);
return promise.forget();
}

View File

@ -0,0 +1,65 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#ifndef mozilla_dom_workers_serviceworkerwindowclient_h
#define mozilla_dom_workers_serviceworkerwindowclient_h
#include "ServiceWorkerClient.h"
namespace mozilla {
namespace dom {
namespace workers {
class ServiceWorkerWindowClient MOZ_FINAL : public ServiceWorkerClient
{
public:
ServiceWorkerWindowClient(nsISupports* aOwner,
const ServiceWorkerClientInfo& aClientInfo)
: ServiceWorkerClient(aOwner, aClientInfo),
mVisibilityState(aClientInfo.mVisibilityState),
mFocused(aClientInfo.mFocused),
mFrameType(aClientInfo.mFrameType)
{
}
virtual JSObject*
WrapObject(JSContext* aCx) MOZ_OVERRIDE;
mozilla::dom::VisibilityState
VisibilityState() const
{
return mVisibilityState;
}
bool
Focused() const
{
return mFocused;
}
mozilla::dom::FrameType
FrameType() const
{
return mFrameType;
}
already_AddRefed<Promise>
Focus() const;
private:
~ServiceWorkerWindowClient()
{ }
mozilla::dom::VisibilityState mVisibilityState;
bool mFocused;
mozilla::dom::FrameType mFrameType;
};
} // namespace workers
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_workers_serviceworkerwindowclient_h

View File

@ -34,6 +34,7 @@ EXPORTS.mozilla.dom.workers.bindings += [
'ServiceWorker.h',
'ServiceWorkerClient.h',
'ServiceWorkerClients.h',
'ServiceWorkerWindowClient.h',
'SharedWorker.h',
'URL.h',
'WorkerFeature.h',
@ -69,6 +70,7 @@ UNIFIED_SOURCES += [
'ServiceWorkerManager.cpp',
'ServiceWorkerRegistrar.cpp',
'ServiceWorkerRegistration.cpp',
'ServiceWorkerWindowClient.cpp',
'SharedWorker.cpp',
'URL.cpp',
'WorkerDebuggerManager.cpp',

View File

@ -0,0 +1,61 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<!DOCTYPE HTML>
<html>
<head>
<title>Bug 1058311 - controlled page</title>
<script class="testbody" type="text/javascript">
var frameType = "none";
var testWindow = parent;
if (parent != window) {
frameType = "nested";
} else if (opener) {
frameType = "auxiliary";
testWindow = opener;
} else if (parent != window) {
frameType = "top-level";
} else {
postResult(false, "Unexpected frameType");
}
window.onload = function() {
navigator.serviceWorker.ready.then(function(swr) {
swr.active.postMessage("Start");
});
}
function postResult(result, msg) {
response = {
result: result,
message: msg
};
testWindow.postMessage(response, "*");
}
navigator.serviceWorker.onmessage = function(msg) {
// worker message;
result = msg.data.url == window.location;
postResult(result, "Client url test");
result = msg.data.visibilityState === document.visibilityState;
postResult(result, "Client visibility test. expected=" +document.visibilityState);
result = msg.data.focused === document.hasFocus();
postResult(result, "Client focus test. expected=" + document.hasFocus());
result = msg.data.frameType === frameType;
postResult(result, "Client frameType test. expected=" + frameType);
postResult(true, "DONE");
window.close();
};
</script>
</head>
<body>
</body>
</html>

View File

@ -0,0 +1,19 @@
onmessage = function(e) {
dump("MatchAllPropertiesWorker:" + e.data + "\n");
self.clients.matchAll().then(function(res) {
if (!res.length) {
dump("ERROR: no clients are currently controlled.\n");
}
for (i = 0; i < res.length; i++) {
client = res[i];
response = {
url: client.url,
visibilityState: client.visibilityState,
focused: client.focused,
frameType: client.frameType
};
client.postMessage(response);
}
});
}

View File

@ -24,6 +24,8 @@ support-files =
fetch/index.html
fetch/fetch_worker_script.js
fetch/fetch_tests.js
match_all_properties_worker.js
match_all_clients/match_all_controlled.html
[test_unregister.html]
skip-if = true # Bug 1133805
@ -40,3 +42,4 @@ skip-if = true # Bug 1133805
skip-if = true # Bug 1133805
[test_post_message.html]
[test_post_message_advanced.html]
[test_match_all_client_properties.html]

View File

@ -0,0 +1,93 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<!DOCTYPE HTML>
<html>
<head>
<title>Bug 1058311 - Test matchAll clients properties </title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test"></pre>
<script class="testbody" type="text/javascript">
var registration;
var clientURL = "match_all_clients/match_all_controlled.html";
function start() {
return navigator.serviceWorker.register("match_all_properties_worker.js",
{ scope: "./match_all_clients/" })
.then((swr) => registration = swr);
}
function unregister() {
return registration.unregister().then(function(result) {
ok(result, "Unregister should return true.");
});
}
function getMessageListener() {
return new Promise(function(res, rej) {
window.onmessage = function(e) {
if (e.data.message === undefined) {
info("rejecting promise");
rej();
return;
}
ok(e.data.result, e.data.message);
if (!e.data.result) {
rej();
}
if (e.data.message == "DONE") {
info("DONE from: " + e.source);
res();
}
}
});
}
function testNestedWindow() {
var p = getMessageListener();
var content = document.getElementById("content");
ok(content, "Parent exists.");
iframe = document.createElement("iframe");
content.appendChild(iframe);
iframe.setAttribute('src', clientURL);
return p.then(() => content.removeChild(iframe));
}
function testAuxiliaryWindow() {
var p = getMessageListener();
var w = window.open(clientURL);
return p.then(() => w.close());
}
function runTest() {
info("catalin");
info(window.opener == undefined);
start()
.then(testAuxiliaryWindow)
.then(testNestedWindow)
.catch(function(e) {
ok(false, "Some test failed with error " + e);
}).then(SimpleTest.finish);
}
SimpleTest.waitForExplicitFinish();
SpecialPowers.pushPrefEnv({"set": [
["dom.serviceWorkers.enabled", true],
["dom.serviceWorkers.testing.enabled", true]
]}, runTest);
</script>
</pre>
</body>
</html>