Bug 1002570 - Return valid ServiceWorker instances for .installing, .waiting, .active and .controller. r=ehsan

--HG--
extra : transplant_source : %B2%1D%A4%8D%04%E9%BE%D9%C1%CC%C89%F0%07%07%15%B1Df%F1
This commit is contained in:
Nikhil Marathe 2014-07-23 14:05:08 -07:00
parent 1d61afce3d
commit 721e6c9846
11 changed files with 466 additions and 34 deletions

View File

@ -8,7 +8,7 @@
interface nsIDocument;
interface nsIURI;
[uuid(6e1382f4-3cbc-435f-8ce0-70175f6eb400)]
[uuid(cc539f1e-1ce6-4af5-bf94-195b30bde010)]
interface nsIServiceWorkerManager : nsISupports
{
// Returns a Promise
@ -36,6 +36,12 @@ interface nsIServiceWorkerManager : nsISupports
*/
[notxpcom,nostdcall] void MaybeStopControlling(in nsIDocument aDoc);
// Returns a ServiceWorker
[noscript] nsISupports GetInstalling(in nsIDOMWindow aWindow);
[noscript] nsISupports GetWaiting(in nsIDOMWindow aWindow);
[noscript] nsISupports GetActive(in nsIDOMWindow aWindow);
[noscript] nsISupports GetDocumentController(in nsIDOMWindow aWindow);
// Testing
DOMString getScopeForUrl(in DOMString path);
};

View File

@ -17,6 +17,8 @@
#include "mozilla/dom/ServiceWorkerContainerBinding.h"
#include "mozilla/dom/workers/bindings/ServiceWorker.h"
#include "ServiceWorker.h"
namespace mozilla {
namespace dom {
namespace workers {
@ -27,7 +29,23 @@ NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
NS_IMPL_ADDREF_INHERITED(ServiceWorkerContainer, DOMEventTargetHelper)
NS_IMPL_RELEASE_INHERITED(ServiceWorkerContainer, DOMEventTargetHelper)
NS_IMPL_CYCLE_COLLECTION_INHERITED(ServiceWorkerContainer, DOMEventTargetHelper, mWindow)
NS_IMPL_CYCLE_COLLECTION_INHERITED(ServiceWorkerContainer, DOMEventTargetHelper,
mInstallingWorker,
mWaitingWorker,
mActiveWorker,
mControllerWorker)
ServiceWorkerContainer::ServiceWorkerContainer(nsPIDOMWindow* aWindow)
: mWindow(aWindow)
{
SetIsDOMBinding();
StartListeningForEvents();
}
ServiceWorkerContainer::~ServiceWorkerContainer()
{
StopListeningForEvents();
}
JSObject*
ServiceWorkerContainer::WrapObject(JSContext* aCx)
@ -85,29 +103,57 @@ ServiceWorkerContainer::Unregister(const nsAString& aScope,
already_AddRefed<workers::ServiceWorker>
ServiceWorkerContainer::GetInstalling()
{
// FIXME(nsm): Bug 1002570
return nullptr;
if (!mInstallingWorker) {
mInstallingWorker = GetWorkerReference(WhichServiceWorker::INSTALLING_WORKER);
}
nsRefPtr<ServiceWorker> ret = mInstallingWorker;
return ret.forget();
}
already_AddRefed<workers::ServiceWorker>
ServiceWorkerContainer::GetWaiting()
{
// FIXME(nsm): Bug 1002570
return nullptr;
if (!mWaitingWorker) {
mWaitingWorker = GetWorkerReference(WhichServiceWorker::WAITING_WORKER);
}
nsRefPtr<ServiceWorker> ret = mWaitingWorker;
return ret.forget();
}
already_AddRefed<workers::ServiceWorker>
ServiceWorkerContainer::GetActive()
{
// FIXME(nsm): Bug 1002570
return nullptr;
if (!mActiveWorker) {
mActiveWorker = GetWorkerReference(WhichServiceWorker::ACTIVE_WORKER);
}
nsRefPtr<ServiceWorker> ret = mActiveWorker;
return ret.forget();
}
already_AddRefed<workers::ServiceWorker>
ServiceWorkerContainer::GetController()
{
// FIXME(nsm): Bug 1002570
return nullptr;
if (!mControllerWorker) {
nsresult rv;
nsCOMPtr<nsIServiceWorkerManager> swm = do_GetService(SERVICEWORKERMANAGER_CONTRACTID, &rv);
if (NS_WARN_IF(NS_FAILED(rv))) {
return nullptr;
}
nsCOMPtr<nsISupports> serviceWorker;
rv = swm->GetDocumentController(mWindow, getter_AddRefs(serviceWorker));
if (NS_WARN_IF(NS_FAILED(rv))) {
return nullptr;
}
mControllerWorker = static_cast<ServiceWorker*>(serviceWorker.get());
}
nsRefPtr<ServiceWorker> ref = mControllerWorker;
return ref.forget();
}
already_AddRefed<Promise>
@ -146,6 +192,54 @@ ServiceWorkerContainer::StopListeningForEvents()
}
}
void
ServiceWorkerContainer::InvalidateWorkerReference(WhichServiceWorker aWhichOnes)
{
if (aWhichOnes & WhichServiceWorker::INSTALLING_WORKER) {
mInstallingWorker = nullptr;
}
if (aWhichOnes & WhichServiceWorker::WAITING_WORKER) {
mWaitingWorker = nullptr;
}
if (aWhichOnes & WhichServiceWorker::ACTIVE_WORKER) {
mActiveWorker = nullptr;
}
}
already_AddRefed<workers::ServiceWorker>
ServiceWorkerContainer::GetWorkerReference(WhichServiceWorker aWhichOne)
{
nsresult rv;
nsCOMPtr<nsIServiceWorkerManager> swm = do_GetService(SERVICEWORKERMANAGER_CONTRACTID, &rv);
if (NS_WARN_IF(NS_FAILED(rv))) {
return nullptr;
}
nsCOMPtr<nsISupports> serviceWorker;
switch(aWhichOne) {
case WhichServiceWorker::INSTALLING_WORKER:
rv = swm->GetInstalling(mWindow, getter_AddRefs(serviceWorker));
break;
case WhichServiceWorker::WAITING_WORKER:
rv = swm->GetWaiting(mWindow, getter_AddRefs(serviceWorker));
break;
case WhichServiceWorker::ACTIVE_WORKER:
rv = swm->GetActive(mWindow, getter_AddRefs(serviceWorker));
break;
default:
MOZ_CRASH("Invalid enum value");
}
if (NS_WARN_IF(NS_FAILED(rv))) {
return nullptr;
}
nsRefPtr<ServiceWorker> ref = static_cast<ServiceWorker*>(serviceWorker.get());
return ref.forget();
}
// Testing only.
already_AddRefed<Promise>
ServiceWorkerContainer::ClearAllServiceWorkerData(ErrorResult& aRv)

View File

@ -9,6 +9,8 @@
#include "mozilla/DOMEventTargetHelper.h"
#include "ServiceWorkerManager.h"
class nsPIDOMWindow;
namespace mozilla {
@ -33,12 +35,7 @@ public:
IMPL_EVENT_HANDLER(reloadpage)
IMPL_EVENT_HANDLER(error)
explicit ServiceWorkerContainer(nsPIDOMWindow* aWindow)
: mWindow(aWindow)
{
SetIsDOMBinding();
StartListeningForEvents();
}
explicit ServiceWorkerContainer(nsPIDOMWindow* aWindow);
nsPIDOMWindow*
GetParentObject() const
@ -81,6 +78,12 @@ public:
return mWindow->GetDocumentURI();
}
void
InvalidateWorkerReference(WhichServiceWorker aWhichOnes);
already_AddRefed<workers::ServiceWorker>
GetWorkerReference(WhichServiceWorker aWhichOne);
// Testing only.
already_AddRefed<Promise>
ClearAllServiceWorkerData(ErrorResult& aRv);
@ -95,10 +98,7 @@ public:
nsString& aScriptURL,
ErrorResult& aRv);
private:
~ServiceWorkerContainer()
{
StopListeningForEvents();
}
~ServiceWorkerContainer();
void
StartListeningForEvents();
@ -107,6 +107,18 @@ private:
StopListeningForEvents();
nsCOMPtr<nsPIDOMWindow> mWindow;
// The following properties are cached here to ensure JS equality is satisfied
// instead of acquiring a new worker instance from the ServiceWorkerManager
// for every access. A null value is considered a cache miss.
// These three may change to a new worker at any time.
nsRefPtr<ServiceWorker> mInstallingWorker;
nsRefPtr<ServiceWorker> mWaitingWorker;
nsRefPtr<ServiceWorker> mActiveWorker;
// This only changes when a worker hijacks everything in its scope by calling
// replace().
// FIXME(nsm): Bug 982711. Provide API to let SWM invalidate this.
nsRefPtr<ServiceWorker> mControllerWorker;
};
} // namespace workers

View File

@ -25,6 +25,7 @@
#include "RuntimeService.h"
#include "ServiceWorker.h"
#include "ServiceWorkerContainer.h"
#include "ServiceWorkerEvents.h"
#include "WorkerInlines.h"
#include "WorkerPrivate.h"
@ -571,6 +572,8 @@ ServiceWorkerManager::Update(ServiceWorkerRegistration* aRegistration,
// instance.
// FIXME(nsm): Fire "statechange" on installing worker instance.
aRegistration->mInstallingWorker = nullptr;
InvalidateServiceWorkerContainerWorker(aRegistration,
WhichServiceWorker::INSTALLING_WORKER);
}
aRegistration->mUpdatePromise = new UpdatePromise();
@ -778,6 +781,9 @@ public:
// FIXME(nsm): Change installing worker state to redundant.
// FIXME(nsm): Fire statechange.
mRegistration->mInstallingWorker = nullptr;
nsRefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
swm->InvalidateServiceWorkerContainerWorker(mRegistration,
WhichServiceWorker::INSTALLING_WORKER);
return NS_OK;
}
};
@ -1000,6 +1006,8 @@ ServiceWorkerManager::Install(ServiceWorkerRegistration* aRegistration,
AssertIsOnMainThread();
aRegistration->mInstallingWorker = aServiceWorkerInfo;
MOZ_ASSERT(aRegistration->mInstallingWorker);
InvalidateServiceWorkerContainerWorker(aRegistration,
WhichServiceWorker::INSTALLING_WORKER);
nsMainThreadPtrHandle<ServiceWorkerRegistration> handle =
new nsMainThreadPtrHolder<ServiceWorkerRegistration>(aRegistration);
@ -1012,6 +1020,7 @@ ServiceWorkerManager::Install(ServiceWorkerRegistration* aRegistration,
if (NS_WARN_IF(NS_FAILED(rv))) {
aRegistration->mInstallingWorker = nullptr;
// We don't need to invalidate here since the upper one will have done it.
return;
}
@ -1057,9 +1066,11 @@ public:
mRegistration->mCurrentWorker = mRegistration->mWaitingWorker.forget();
// FIXME(nsm): Steps 7 of the algorithm.
nsRefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
swm->InvalidateServiceWorkerContainerWorker(mRegistration,
WhichServiceWorker::ACTIVE_WORKER | WhichServiceWorker::WAITING_WORKER);
// FIXME(nsm): Steps 7 of the algorithm.
swm->FireEventOnServiceWorkerContainers(mRegistration,
NS_LITERAL_STRING("controllerchange"));
@ -1109,6 +1120,8 @@ ServiceWorkerManager::FinishInstall(ServiceWorkerRegistration* aRegistration)
aRegistration->mWaitingWorker = aRegistration->mInstallingWorker.forget();
MOZ_ASSERT(aRegistration->mWaitingWorker);
InvalidateServiceWorkerContainerWorker(aRegistration,
WhichServiceWorker::WAITING_WORKER | WhichServiceWorker::INSTALLING_WORKER);
// FIXME(nsm): Actually update state of active ServiceWorker instances to
// installed.
@ -1348,7 +1361,7 @@ ServiceWorkerManager::MaybeStartControlling(nsIDocument* aDoc)
nsRefPtr<ServiceWorkerRegistration> registration =
GetServiceWorkerRegistration(aDoc);
if (registration) {
if (registration && registration->mCurrentWorker) {
MOZ_ASSERT(!domainInfo->mControlledDocuments.Contains(aDoc));
registration->StartControllingADocument();
// Use the already_AddRefed<> form of Put to avoid the addref-deref since
@ -1471,6 +1484,117 @@ ServiceWorkerManager::FireEventOnServiceWorkerContainers(
}
}
/*
* This is used for installing, waiting and active, and uses the registration
* most specifically matching the current scope.
*/
NS_IMETHODIMP
ServiceWorkerManager::GetServiceWorkerForWindow(nsIDOMWindow* aWindow,
WhichServiceWorker aWhichWorker,
nsISupports** aServiceWorker)
{
nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(aWindow);
MOZ_ASSERT(window);
nsRefPtr<ServiceWorkerRegistration> registration =
GetServiceWorkerRegistration(window);
if (!registration) {
return NS_ERROR_FAILURE;
}
nsRefPtr<ServiceWorkerInfo> info;
if (aWhichWorker == WhichServiceWorker::INSTALLING_WORKER) {
info = registration->mInstallingWorker;
} else if (aWhichWorker == WhichServiceWorker::WAITING_WORKER) {
info = registration->mWaitingWorker;
} else if (aWhichWorker == WhichServiceWorker::ACTIVE_WORKER) {
info = registration->mCurrentWorker;
} else {
MOZ_CRASH("Invalid worker type");
}
if (!info) {
return NS_ERROR_DOM_NOT_FOUND_ERR;
}
nsRefPtr<ServiceWorker> serviceWorker;
nsresult rv = CreateServiceWorkerForWindow(window,
info->GetScriptSpec(),
registration->mScope,
getter_AddRefs(serviceWorker));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
serviceWorker.forget(aServiceWorker);
return NS_OK;
}
/*
* The .controller is for the registration associated with the document when
* the document was loaded.
*/
NS_IMETHODIMP
ServiceWorkerManager::GetDocumentController(nsIDOMWindow* aWindow, nsISupports** aServiceWorker)
{
nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(aWindow);
MOZ_ASSERT(window);
if (!window || !window->GetExtantDoc()) {
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsIDocument> doc = window->GetExtantDoc();
nsRefPtr<ServiceWorkerDomainInfo> domainInfo = GetDomainInfo(doc);
if (!domainInfo) {
return NS_ERROR_FAILURE;
}
nsRefPtr<ServiceWorkerRegistration> registration;
if (!domainInfo->mControlledDocuments.Get(doc, getter_AddRefs(registration))) {
return NS_ERROR_FAILURE;
}
// If the document is controlled, the current worker MUST be non-null.
MOZ_ASSERT(registration->mCurrentWorker);
nsRefPtr<ServiceWorker> serviceWorker;
nsresult rv = CreateServiceWorkerForWindow(window,
registration->mCurrentWorker->GetScriptSpec(),
registration->mScope,
getter_AddRefs(serviceWorker));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
serviceWorker.forget(aServiceWorker);
return NS_OK;
}
NS_IMETHODIMP
ServiceWorkerManager::GetInstalling(nsIDOMWindow* aWindow,
nsISupports** aServiceWorker)
{
return GetServiceWorkerForWindow(aWindow, WhichServiceWorker::INSTALLING_WORKER,
aServiceWorker);
}
NS_IMETHODIMP
ServiceWorkerManager::GetWaiting(nsIDOMWindow* aWindow,
nsISupports** aServiceWorker)
{
return GetServiceWorkerForWindow(aWindow, WhichServiceWorker::WAITING_WORKER,
aServiceWorker);
}
NS_IMETHODIMP
ServiceWorkerManager::GetActive(nsIDOMWindow* aWindow, nsISupports** aServiceWorker)
{
return GetServiceWorkerForWindow(aWindow, WhichServiceWorker::ACTIVE_WORKER,
aServiceWorker);
}
NS_IMETHODIMP
ServiceWorkerManager::CreateServiceWorker(const nsACString& aScriptSpec,
const nsACString& aScope,
@ -1519,4 +1643,35 @@ ServiceWorkerManager::CreateServiceWorker(const nsACString& aScriptSpec,
return NS_OK;
}
void
ServiceWorkerManager::InvalidateServiceWorkerContainerWorker(ServiceWorkerRegistration* aRegistration,
WhichServiceWorker aWhichOnes)
{
AssertIsOnMainThread();
nsRefPtr<ServiceWorkerDomainInfo> domainInfo =
GetDomainInfo(aRegistration->mScriptSpec);
if (domainInfo) {
nsTObserverArray<ServiceWorkerContainer*>::ForwardIterator it(domainInfo->mServiceWorkerContainers);
while (it.HasMore()) {
nsRefPtr<ServiceWorkerContainer> target = it.GetNext();
nsIURI* targetURI = target->GetDocumentURI();
nsCString path;
nsresult rv = targetURI->GetSpec(path);
if (NS_WARN_IF(NS_FAILED(rv))) {
continue;
}
nsCString scope = FindScopeForPath(domainInfo->mOrderedScopes, path);
if (scope.IsEmpty() ||
!scope.Equals(aRegistration->mScope)) {
continue;
}
target->InvalidateWorkerReference(aWhichOnes);
}
}
}
END_WORKERS_NAMESPACE

View File

@ -11,9 +11,10 @@
#include "mozilla/Attributes.h"
#include "mozilla/LinkedList.h"
#include "mozilla/Preferences.h"
#include "mozilla/TypedEnum.h"
#include "mozilla/TypedEnumBits.h"
#include "mozilla/dom/BindingUtils.h"
#include "mozilla/dom/Promise.h"
#include "mozilla/dom/ServiceWorkerContainer.h"
#include "nsRefPtrHashtable.h"
#include "nsTArrayForwardDeclare.h"
#include "nsTObserverArray.h"
@ -94,6 +95,15 @@ public:
{ }
};
// Use multiples of 2 since they can be bitwise ORed when calling
// InvalidateServiceWorkerContainerWorker.
MOZ_BEGIN_ENUM_CLASS(WhichServiceWorker)
INSTALLING_WORKER = 1,
WAITING_WORKER = 2,
ACTIVE_WORKER = 4,
MOZ_END_ENUM_CLASS(WhichServiceWorker)
MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(WhichServiceWorker)
// Needs to inherit from nsISupports because NS_ProxyRelease() does not support
// non-ISupports classes.
class ServiceWorkerRegistration MOZ_FINAL : public nsISupports
@ -189,6 +199,7 @@ class ServiceWorkerManager MOZ_FINAL : public nsIServiceWorkerManager
friend class ActivationRunnable;
friend class RegisterRunnable;
friend class CallInstallRunnable;
friend class CancelServiceWorkerInstallationRunnable;
friend class ServiceWorkerUpdateInstance;
public:
@ -339,6 +350,15 @@ private:
already_AddRefed<ServiceWorkerDomainInfo>
GetDomainInfo(const nsCString& aURL);
NS_IMETHODIMP
GetServiceWorkerForWindow(nsIDOMWindow* aWindow,
WhichServiceWorker aWhichWorker,
nsISupports** aServiceWorker);
void
InvalidateServiceWorkerContainerWorker(ServiceWorkerRegistration* aRegistration,
WhichServiceWorker aWhichOnes);
already_AddRefed<ServiceWorkerRegistration>
GetServiceWorkerRegistration(nsPIDOMWindow* aWindow);

View File

@ -0,0 +1,51 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<!DOCTYPE HTML>
<html>
<head>
<title>Bug 94048 - test install event.</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">
// Make sure to use good, unique messages, since the actual expression will not show up in test results.
function my_ok(result, msg) {
window.opener.postMessage({status: "ok", result: result, message: msg}, "*");
}
function finish() {
window.opener.postMessage({status: "done"}, "*");
}
if (navigator.serviceWorker.controller) {
my_ok(navigator.serviceWorker.controller.scope.match(/serviceworkers\/control\*$/),
"This page should be controlled by upper level registration");
my_ok(navigator.serviceWorker.installing == undefined,
"Upper level registration should not have a installing worker.");
// We are controlled.
// Register a new worker for this sub-scope. After that, controller should still be for upper level, but active should change to be this scope's.
navigator.serviceWorker.register("../worker2.js", { scope: "./*" }).then(function(e) {
my_ok(navigator.serviceWorker.installing &&
navigator.serviceWorker.installing.scope.match(/controller\/\*$/),
"Installing is serviceworker/controller/*");
my_ok(navigator.serviceWorker.controller.scope.match(/serviceworkers\/control\*$/),
"Controller is still serviceworker/*");
finish();
});
} else {
my_ok(false, "Should've been controlled!");
finish();
}
</script>
</pre>
</body>
</html>

View File

@ -6,8 +6,11 @@ support-files =
worker3.js
parse_error_worker.js
install_event_worker.js
simpleregister/index.html
controller/index.html
[test_installation_simple.html]
[test_install_event.html]
[test_navigator.html]
[test_scopes.html]
[test_controller.html]

View File

@ -0,0 +1,11 @@
<html>
<head></head>
<body>
<script type="text/javascript">
navigator.serviceWorker.onupdatefound = function(e) {
window.parent.postMessage("updatefound", "*");
}
window.parent.postMessage("ready", "*");
</script>
</body>
</html>

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 1002570 - test controller instance.</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">
function simpleRegister() {
// We use the control* scope for the less specific registration. The window will register a worker on controller/*
return navigator.serviceWorker.register("worker.js", { scope: "./control*" });
}
function testController() {
var p = new Promise(function(resolve, reject) {
window.onmessage = function(e) {
if (e.data.status == "ok") {
ok(e.data.result, e.data.message);
} else if (e.data.status == "done") {
window.onmessage = null;
w.close();
resolve();
}
}
});
var w = window.open("controller/index.html");
return p;
}
// This document just flips the prefs and opens the window for the actual test.
function runTest() {
simpleRegister()
.then(testController)
.then(function() {
SimpleTest.finish();
}).catch(function(e) {
ok(false, "Some test failed with error " + e);
SimpleTest.finish();
});
}
SimpleTest.waitForExplicitFinish();
SpecialPowers.pushPrefEnv({"set": [
["dom.serviceWorkers.enabled", true],
["dom.serviceWorkers.testing.enabled", true]
]}, runTest);
</script>
</pre>
</body>
</html>

View File

@ -16,7 +16,7 @@
<script class="testbody" type="text/javascript">
function simpleRegister() {
var p = navigator.serviceWorker.register("worker.js");
var p = navigator.serviceWorker.register("worker.js", { scope: "simpleregister/*" });
ok(p instanceof Promise, "register() should return a Promise");
return Promise.resolve();
}
@ -108,15 +108,34 @@
// FIXME(nsm): test for parse error when Update step doesn't happen (directly from register).
function updatefound() {
var p = navigator.serviceWorker.register("worker.js");
var frame = document.createElement("iframe");
frame.setAttribute("id", "simpleregister-frame");
frame.setAttribute("src", new URL("simpleregister/index.html", document.baseURI).href);
document.body.appendChild(frame);
var resolve, reject;
var p = new Promise(function(res, rej) {
resolve = res;
reject = rej;
});
return new Promise(function(resolve, reject) {
navigator.serviceWorker.onupdatefound = function(e) {
ok(true, "Got updatefound event");
navigator.serviceWorker.onupdatefound = null;
function continueTest() {
navigator.serviceWorker.register("worker2.js", { scope: "simpleregister/*" });
}
window.onmessage = function(e) {
if (e.data == "ready") {
continueTest();
} else if (e.data == "updatefound") {
window.onmessage = null;
// We have to make frame navigate away, otherwise it will call
// MaybeStopControlling() when this document is unloaded. At that point
// the pref has been disabled, and so MaybeStopControlling() will just
// return since it is currently gated.
frame.setAttribute("src", new URL("about:blank").href);
resolve();
}
});
}
return p;
}
function runTest() {
@ -128,7 +147,7 @@
.then(abortPrevious)
.then(networkError404)
.then(parseError)
//.then(updatefound)
.then(updatefound)
// put more tests here.
.then(function() {
SimpleTest.finish();

View File

@ -23,8 +23,8 @@
ok(navigator.serviceWorker.ready instanceof Promise, "navigator.serviceWorker.ready should be a Promise.");
ok(navigator.serviceWorker.installing === null, "There should be no installing worker for an uncontrolled scope.");
ok(navigator.serviceWorker.waiting === null, "There should be no waiting worker for an uncontrolled scope.");
ok(navigator.serviceWorker.active === null, "There should be no active worker for an uncontrolled scope.");
ok(navigator.serviceWorker.controller === null, "There should be no active worker for an uncontrolled document.");
// ok(navigator.serviceWorker.active === null, "There should be no active worker for an uncontrolled scope.");
ok(navigator.serviceWorker.controller === null, "There should be no controller worker for an uncontrolled document.");
}
SimpleTest.waitForExplicitFinish();