зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1131352 - Part 2: Add ServiceWorkerGlobalScope skipWaiting(). r=nsm, r=baku
This commit is contained in:
Родитель
1fde4d00db
Коммит
2d3a0be044
|
@ -16,6 +16,9 @@ interface ServiceWorkerGlobalScope : WorkerGlobalScope {
|
||||||
readonly attribute Clients clients;
|
readonly attribute Clients clients;
|
||||||
readonly attribute ServiceWorkerRegistration registration;
|
readonly attribute ServiceWorkerRegistration registration;
|
||||||
|
|
||||||
|
[Throws]
|
||||||
|
Promise<boolean> skipWaiting();
|
||||||
|
|
||||||
attribute EventHandler oninstall;
|
attribute EventHandler oninstall;
|
||||||
attribute EventHandler onactivate;
|
attribute EventHandler onactivate;
|
||||||
attribute EventHandler onfetch;
|
attribute EventHandler onfetch;
|
||||||
|
|
|
@ -1135,8 +1135,11 @@ private:
|
||||||
swm->InvalidateServiceWorkerRegistrationWorker(mRegistration,
|
swm->InvalidateServiceWorkerRegistrationWorker(mRegistration,
|
||||||
WhichServiceWorker::INSTALLING_WORKER | WhichServiceWorker::WAITING_WORKER);
|
WhichServiceWorker::INSTALLING_WORKER | WhichServiceWorker::WAITING_WORKER);
|
||||||
|
|
||||||
// FIXME(nsm): Bug 982711 Deal with activateImmediately.
|
// "If registration's waiting worker's skip waiting flag is set"
|
||||||
NS_WARN_IF_FALSE(!aActivateImmediately, "Immediate activation using replace() is not supported yet");
|
if (mRegistration->mWaitingWorker->SkipWaitingFlag()) {
|
||||||
|
mRegistration->PurgeActiveWorker();
|
||||||
|
}
|
||||||
|
|
||||||
Done(NS_OK);
|
Done(NS_OK);
|
||||||
// Activate() is invoked out of band of atomic.
|
// Activate() is invoked out of band of atomic.
|
||||||
mRegistration->TryToActivate();
|
mRegistration->TryToActivate();
|
||||||
|
@ -1466,7 +1469,7 @@ LifecycleEventWorkerRunnable::DispatchLifecycleEvent(JSContext* aCx, WorkerPriva
|
||||||
void
|
void
|
||||||
ServiceWorkerRegistrationInfo::TryToActivate()
|
ServiceWorkerRegistrationInfo::TryToActivate()
|
||||||
{
|
{
|
||||||
if (!IsControllingDocuments()) {
|
if (!IsControllingDocuments() || mWaitingWorker->SkipWaitingFlag()) {
|
||||||
Activate();
|
Activate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1477,28 +1480,36 @@ ContinueActivateTask::ContinueAfterWorkerEvent(bool aSuccess, bool aActivateImme
|
||||||
mRegistration->FinishActivate(aSuccess);
|
mRegistration->FinishActivate(aSuccess);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ServiceWorkerRegistrationInfo::PurgeActiveWorker()
|
||||||
|
{
|
||||||
|
nsRefPtr<ServiceWorkerInfo> exitingWorker = mActiveWorker.forget();
|
||||||
|
if (!exitingWorker)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// FIXME(jaoo): Bug 1170543 - Wait for exitingWorker to finish and terminate it.
|
||||||
|
exitingWorker->UpdateState(ServiceWorkerState::Redundant);
|
||||||
|
nsresult rv = serviceWorkerScriptCache::PurgeCache(mPrincipal,
|
||||||
|
exitingWorker->CacheName());
|
||||||
|
if (NS_FAILED(rv)) {
|
||||||
|
NS_WARNING("Failed to purge the activating cache.");
|
||||||
|
}
|
||||||
|
nsRefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
|
||||||
|
swm->InvalidateServiceWorkerRegistrationWorker(this, WhichServiceWorker::ACTIVE_WORKER);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ServiceWorkerRegistrationInfo::Activate()
|
ServiceWorkerRegistrationInfo::Activate()
|
||||||
{
|
{
|
||||||
nsRefPtr<ServiceWorkerInfo> activatingWorker = mWaitingWorker;
|
nsRefPtr<ServiceWorkerInfo> activatingWorker = mWaitingWorker;
|
||||||
nsRefPtr<ServiceWorkerInfo> exitingWorker = mActiveWorker;
|
|
||||||
|
|
||||||
nsRefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
|
|
||||||
swm->InvalidateServiceWorkerRegistrationWorker(this, WhichServiceWorker::WAITING_WORKER | WhichServiceWorker::ACTIVE_WORKER);
|
|
||||||
if (!activatingWorker) {
|
if (!activatingWorker) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (exitingWorker) {
|
PurgeActiveWorker();
|
||||||
// FIXME(nsm): Wait for worker.
|
|
||||||
// Terminate worker
|
nsRefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
|
||||||
exitingWorker->UpdateState(ServiceWorkerState::Redundant);
|
swm->InvalidateServiceWorkerRegistrationWorker(this, WhichServiceWorker::WAITING_WORKER);
|
||||||
nsresult rv = serviceWorkerScriptCache::PurgeCache(mPrincipal,
|
|
||||||
exitingWorker->CacheName());
|
|
||||||
if (NS_FAILED(rv)) {
|
|
||||||
NS_WARNING("Failed to purge the activating cache.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mActiveWorker = activatingWorker.forget();
|
mActiveWorker = activatingWorker.forget();
|
||||||
mWaitingWorker = nullptr;
|
mWaitingWorker = nullptr;
|
||||||
|
@ -3678,6 +3689,31 @@ ServiceWorkerManager::ClaimClients(nsIPrincipal* aPrincipal,
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
ServiceWorkerManager::SetSkipWaitingFlag(const nsCString& aScope,
|
||||||
|
uint64_t aServiceWorkerID)
|
||||||
|
{
|
||||||
|
nsRefPtr<ServiceWorkerRegistrationInfo> registration = GetRegistration(aScope);
|
||||||
|
if (!registration) {
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (registration->mInstallingWorker &&
|
||||||
|
(registration->mInstallingWorker->ID() == aServiceWorkerID)) {
|
||||||
|
registration->mInstallingWorker->SetSkipWaitingFlag();
|
||||||
|
} else if (registration->mWaitingWorker &&
|
||||||
|
(registration->mWaitingWorker->ID() == aServiceWorkerID)) {
|
||||||
|
registration->mWaitingWorker->SetSkipWaitingFlag();
|
||||||
|
if (registration->mWaitingWorker->State() == ServiceWorkerState::Installed) {
|
||||||
|
registration->TryToActivate();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ServiceWorkerManager::FireControllerChange(ServiceWorkerRegistrationInfo* aRegistration)
|
ServiceWorkerManager::FireControllerChange(ServiceWorkerRegistrationInfo* aRegistration)
|
||||||
{
|
{
|
||||||
|
|
|
@ -117,6 +117,9 @@ public:
|
||||||
void
|
void
|
||||||
Clear();
|
Clear();
|
||||||
|
|
||||||
|
void
|
||||||
|
PurgeActiveWorker();
|
||||||
|
|
||||||
void
|
void
|
||||||
TryToActivate();
|
TryToActivate();
|
||||||
|
|
||||||
|
@ -151,6 +154,7 @@ private:
|
||||||
// There is a high chance of there being at least one ServiceWorker
|
// There is a high chance of there being at least one ServiceWorker
|
||||||
// associated with this all the time.
|
// associated with this all the time.
|
||||||
nsAutoTArray<ServiceWorker*, 1> mInstances;
|
nsAutoTArray<ServiceWorker*, 1> mInstances;
|
||||||
|
bool mSkipWaitingFlag;
|
||||||
|
|
||||||
~ServiceWorkerInfo()
|
~ServiceWorkerInfo()
|
||||||
{ }
|
{ }
|
||||||
|
@ -181,14 +185,27 @@ public:
|
||||||
mScriptSpec = aSpec;
|
mScriptSpec = aSpec;
|
||||||
}
|
}
|
||||||
|
|
||||||
explicit ServiceWorkerInfo(ServiceWorkerRegistrationInfo* aReg,
|
bool SkipWaitingFlag() const
|
||||||
const nsACString& aScriptSpec,
|
{
|
||||||
const nsAString& aCacheName)
|
AssertIsOnMainThread();
|
||||||
|
return mSkipWaitingFlag;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetSkipWaitingFlag()
|
||||||
|
{
|
||||||
|
AssertIsOnMainThread();
|
||||||
|
mSkipWaitingFlag = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
ServiceWorkerInfo(ServiceWorkerRegistrationInfo* aReg,
|
||||||
|
const nsACString& aScriptSpec,
|
||||||
|
const nsAString& aCacheName)
|
||||||
: mRegistration(aReg)
|
: mRegistration(aReg)
|
||||||
, mScriptSpec(aScriptSpec)
|
, mScriptSpec(aScriptSpec)
|
||||||
, mCacheName(aCacheName)
|
, mCacheName(aCacheName)
|
||||||
, mState(ServiceWorkerState::EndGuard_)
|
, mState(ServiceWorkerState::EndGuard_)
|
||||||
, mServiceWorkerID(GetNextID())
|
, mServiceWorkerID(GetNextID())
|
||||||
|
, mSkipWaitingFlag(false)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(mRegistration);
|
MOZ_ASSERT(mRegistration);
|
||||||
MOZ_ASSERT(!aCacheName.IsEmpty());
|
MOZ_ASSERT(!aCacheName.IsEmpty());
|
||||||
|
@ -338,11 +355,14 @@ public:
|
||||||
nsresult
|
nsresult
|
||||||
ClaimClients(nsIPrincipal* aPrincipal, const nsCString& aScope, uint64_t aId);
|
ClaimClients(nsIPrincipal* aPrincipal, const nsCString& aScope, uint64_t aId);
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
SetSkipWaitingFlag(const nsCString& aScope, uint64_t aServiceWorkerID);
|
||||||
|
|
||||||
static already_AddRefed<ServiceWorkerManager>
|
static already_AddRefed<ServiceWorkerManager>
|
||||||
GetInstance();
|
GetInstance();
|
||||||
|
|
||||||
void LoadRegistrations(
|
void
|
||||||
const nsTArray<ServiceWorkerRegistrationData>& aRegistrations);
|
LoadRegistrations(const nsTArray<ServiceWorkerRegistrationData>& aRegistrations);
|
||||||
|
|
||||||
// Used by remove() and removeAll() when clearing history.
|
// Used by remove() and removeAll() when clearing history.
|
||||||
// MUST ONLY BE CALLED FROM UnregisterIfMatchesHost!
|
// MUST ONLY BE CALLED FROM UnregisterIfMatchesHost!
|
||||||
|
|
|
@ -487,6 +487,125 @@ ServiceWorkerGlobalScope::Registration()
|
||||||
return mRegistration;
|
return mRegistration;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
class SkipWaitingResultRunnable final : public WorkerRunnable
|
||||||
|
{
|
||||||
|
nsRefPtr<PromiseWorkerProxy> mPromiseProxy;
|
||||||
|
|
||||||
|
public:
|
||||||
|
SkipWaitingResultRunnable(WorkerPrivate* aWorkerPrivate,
|
||||||
|
PromiseWorkerProxy* aPromiseProxy)
|
||||||
|
: WorkerRunnable(aWorkerPrivate, WorkerThreadModifyBusyCount)
|
||||||
|
, mPromiseProxy(aPromiseProxy)
|
||||||
|
{
|
||||||
|
AssertIsOnMainThread();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool
|
||||||
|
WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate) override
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(aWorkerPrivate);
|
||||||
|
aWorkerPrivate->AssertIsOnWorkerThread();
|
||||||
|
|
||||||
|
Promise* promise = mPromiseProxy->GetWorkerPromise();
|
||||||
|
MOZ_ASSERT(promise);
|
||||||
|
|
||||||
|
promise->MaybeResolve(JS::UndefinedHandleValue);
|
||||||
|
|
||||||
|
// Release the reference on the worker thread.
|
||||||
|
mPromiseProxy->CleanUp(aCx);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class WorkerScopeSkipWaitingRunnable final : public nsRunnable
|
||||||
|
{
|
||||||
|
nsRefPtr<PromiseWorkerProxy> mPromiseProxy;
|
||||||
|
nsCString mScope;
|
||||||
|
|
||||||
|
public:
|
||||||
|
WorkerScopeSkipWaitingRunnable(PromiseWorkerProxy* aPromiseProxy,
|
||||||
|
const nsCString& aScope)
|
||||||
|
: mPromiseProxy(aPromiseProxy)
|
||||||
|
, mScope(aScope)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(aPromiseProxy);
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
Run() override
|
||||||
|
{
|
||||||
|
AssertIsOnMainThread();
|
||||||
|
nsRefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
|
||||||
|
MOZ_ASSERT(swm);
|
||||||
|
|
||||||
|
MutexAutoLock lock(mPromiseProxy->GetCleanUpLock());
|
||||||
|
if (mPromiseProxy->IsClean()) {
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
WorkerPrivate* workerPrivate = mPromiseProxy->GetWorkerPrivate();
|
||||||
|
MOZ_ASSERT(workerPrivate);
|
||||||
|
|
||||||
|
swm->SetSkipWaitingFlag(mScope, workerPrivate->ServiceWorkerID());
|
||||||
|
|
||||||
|
nsRefPtr<SkipWaitingResultRunnable> runnable =
|
||||||
|
new SkipWaitingResultRunnable(workerPrivate, mPromiseProxy);
|
||||||
|
|
||||||
|
AutoJSAPI jsapi;
|
||||||
|
jsapi.Init();
|
||||||
|
JSContext* cx = jsapi.cx();
|
||||||
|
if (runnable->Dispatch(cx)) {
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dispatch to worker thread failed because the worker is shutting down.
|
||||||
|
// Use a control runnable to release the runnable on the worker thread.
|
||||||
|
nsRefPtr<PromiseWorkerProxyControlRunnable> releaseRunnable =
|
||||||
|
new PromiseWorkerProxyControlRunnable(workerPrivate, mPromiseProxy);
|
||||||
|
|
||||||
|
if (!releaseRunnable->Dispatch(cx)) {
|
||||||
|
NS_RUNTIMEABORT("Failed to dispatch Claim control runnable.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
already_AddRefed<Promise>
|
||||||
|
ServiceWorkerGlobalScope::SkipWaiting(ErrorResult& aRv)
|
||||||
|
{
|
||||||
|
mWorkerPrivate->AssertIsOnWorkerThread();
|
||||||
|
MOZ_ASSERT(mWorkerPrivate->IsServiceWorker());
|
||||||
|
|
||||||
|
nsRefPtr<Promise> promise = Promise::Create(this, aRv);
|
||||||
|
if (NS_WARN_IF(aRv.Failed())) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsRefPtr<PromiseWorkerProxy> promiseProxy =
|
||||||
|
PromiseWorkerProxy::Create(mWorkerPrivate, promise);
|
||||||
|
if (!promiseProxy->GetWorkerPromise()) {
|
||||||
|
// Don't dispatch if adding the worker feature failed.
|
||||||
|
promise->MaybeResolve(JS::UndefinedHandleValue);
|
||||||
|
return promise.forget();
|
||||||
|
}
|
||||||
|
|
||||||
|
nsRefPtr<WorkerScopeSkipWaitingRunnable> runnable =
|
||||||
|
new WorkerScopeSkipWaitingRunnable(promiseProxy,
|
||||||
|
NS_ConvertUTF16toUTF8(mScope));
|
||||||
|
|
||||||
|
aRv = NS_DispatchToMainThread(runnable);
|
||||||
|
if (NS_WARN_IF(aRv.Failed())) {
|
||||||
|
promise->MaybeReject(NS_ERROR_DOM_ABORT_ERR);
|
||||||
|
}
|
||||||
|
|
||||||
|
return promise.forget();
|
||||||
|
}
|
||||||
|
|
||||||
WorkerDebuggerGlobalScope::WorkerDebuggerGlobalScope(
|
WorkerDebuggerGlobalScope::WorkerDebuggerGlobalScope(
|
||||||
WorkerPrivate* aWorkerPrivate)
|
WorkerPrivate* aWorkerPrivate)
|
||||||
: mWorkerPrivate(aWorkerPrivate)
|
: mWorkerPrivate(aWorkerPrivate)
|
||||||
|
|
|
@ -227,6 +227,9 @@ public:
|
||||||
ServiceWorkerRegistrationWorkerThread*
|
ServiceWorkerRegistrationWorkerThread*
|
||||||
Registration();
|
Registration();
|
||||||
|
|
||||||
|
already_AddRefed<Promise>
|
||||||
|
SkipWaiting(ErrorResult& aRv);
|
||||||
|
|
||||||
IMPL_EVENT_HANDLER(activate)
|
IMPL_EVENT_HANDLER(activate)
|
||||||
IMPL_EVENT_HANDLER(beforeevicted)
|
IMPL_EVENT_HANDLER(beforeevicted)
|
||||||
IMPL_EVENT_HANDLER(evicted)
|
IMPL_EVENT_HANDLER(evicted)
|
||||||
|
|
|
@ -107,6 +107,8 @@ support-files =
|
||||||
sw_clients/refresher_cached_compressed.html
|
sw_clients/refresher_cached_compressed.html
|
||||||
sw_clients/refresher_cached_compressed.html^headers^
|
sw_clients/refresher_cached_compressed.html^headers^
|
||||||
strict_mode_error.js
|
strict_mode_error.js
|
||||||
|
skip_waiting_installed_worker.js
|
||||||
|
skip_waiting_scope/index.html
|
||||||
|
|
||||||
[test_unregister.html]
|
[test_unregister.html]
|
||||||
[test_installation_simple.html]
|
[test_installation_simple.html]
|
||||||
|
@ -147,4 +149,5 @@ support-files =
|
||||||
[test_app_protocol.html]
|
[test_app_protocol.html]
|
||||||
[test_claim_fetch.html]
|
[test_claim_fetch.html]
|
||||||
[test_force_refresh.html]
|
[test_force_refresh.html]
|
||||||
|
[test_skip_waiting.html]
|
||||||
[test_strict_mode_error.html]
|
[test_strict_mode_error.html]
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
|
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
|
self.addEventListener('install', evt => {
|
||||||
|
evt.waitUntil(self.skipWaiting());
|
||||||
|
});
|
|
@ -0,0 +1,37 @@
|
||||||
|
<!--
|
||||||
|
Any copyright is dedicated to the Public Domain.
|
||||||
|
http://creativecommons.org/publicdomain/zero/1.0/
|
||||||
|
-->
|
||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Bug 1131352 - Add ServiceWorkerGlobalScope skipWaiting()</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">
|
||||||
|
|
||||||
|
if (!parent) {
|
||||||
|
info("skip_waiting_scope/index.html shouldn't be launched directly!");
|
||||||
|
}
|
||||||
|
|
||||||
|
navigator.serviceWorker.ready.then(function() {
|
||||||
|
parent.postMessage("READY", "*");
|
||||||
|
});
|
||||||
|
|
||||||
|
navigator.serviceWorker.oncontrollerchange = function() {
|
||||||
|
parent.postMessage({
|
||||||
|
event: "controllerchange",
|
||||||
|
controllerScriptURL: navigator.serviceWorker.controller &&
|
||||||
|
navigator.serviceWorker.controller.scriptURL
|
||||||
|
}, "*");
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
</pre>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,95 @@
|
||||||
|
<!--
|
||||||
|
Any copyright is dedicated to the Public Domain.
|
||||||
|
http://creativecommons.org/publicdomain/zero/1.0/
|
||||||
|
-->
|
||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Bug 1131352 - Add ServiceWorkerGlobalScope skipWaiting()</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, iframe, content;
|
||||||
|
|
||||||
|
function start() {
|
||||||
|
return navigator.serviceWorker.register("worker.js",
|
||||||
|
{scope: "./skip_waiting_scope/"});
|
||||||
|
}
|
||||||
|
|
||||||
|
function waitForActivated(swr) {
|
||||||
|
registration = swr;
|
||||||
|
var promise = new Promise(function(resolve, reject) {
|
||||||
|
window.onmessage = function(e) {
|
||||||
|
if (e.data === "READY") {
|
||||||
|
ok(true, "Active worker is activated now");
|
||||||
|
resolve();
|
||||||
|
} else {
|
||||||
|
ok(false, "Wrong value. Somenting went wrong");
|
||||||
|
resolve();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
iframe = document.createElement("iframe");
|
||||||
|
iframe.setAttribute("src", "skip_waiting_scope/index.html");
|
||||||
|
|
||||||
|
content = document.getElementById("content");
|
||||||
|
content.appendChild(iframe);
|
||||||
|
|
||||||
|
return promise;
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkWhetherItSkippedWaiting() {
|
||||||
|
var promise = new Promise(function(resolve, reject) {
|
||||||
|
window.onmessage = function (evt) {
|
||||||
|
if (evt.data.event === "controllerchange") {
|
||||||
|
ok(evt.data.controllerScriptURL.match("skip_waiting_installed_worker"),
|
||||||
|
"The controller changed after skiping the waiting step");
|
||||||
|
resolve();
|
||||||
|
} else {
|
||||||
|
ok(false, "Wrong value. Somenting went wrong");
|
||||||
|
resolve();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
navigator.serviceWorker.register("skip_waiting_installed_worker.js",
|
||||||
|
{scope: "./skip_waiting_scope/"})
|
||||||
|
.then(swr => {
|
||||||
|
registration = swr;
|
||||||
|
});
|
||||||
|
|
||||||
|
return promise;
|
||||||
|
}
|
||||||
|
|
||||||
|
function clean() {
|
||||||
|
content.removeChild(iframe);
|
||||||
|
|
||||||
|
return registration.unregister();
|
||||||
|
}
|
||||||
|
|
||||||
|
function runTest() {
|
||||||
|
start()
|
||||||
|
.then(waitForActivated)
|
||||||
|
.then(checkWhetherItSkippedWaiting)
|
||||||
|
.then(clean)
|
||||||
|
.catch(function(e) {
|
||||||
|
ok(false, "Some test failed with error " + e);
|
||||||
|
}).then(SimpleTest.finish);
|
||||||
|
}
|
||||||
|
|
||||||
|
SimpleTest.waitForExplicitFinish();
|
||||||
|
SpecialPowers.pushPrefEnv({"set": [
|
||||||
|
["dom.serviceWorkers.exemptFromPerDomainMax", true],
|
||||||
|
["dom.serviceWorkers.enabled", true],
|
||||||
|
["dom.serviceWorkers.testing.enabled", true]
|
||||||
|
]}, runTest);
|
||||||
|
</script>
|
||||||
|
</pre>
|
||||||
|
</body>
|
||||||
|
</html>
|
Загрузка…
Ссылка в новой задаче