mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-11 01:57:00 +00:00
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:
parent
1d61afce3d
commit
721e6c9846
@ -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);
|
||||
};
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
||||
|
51
dom/workers/test/serviceworkers/controller/index.html
Normal file
51
dom/workers/test/serviceworkers/controller/index.html
Normal 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>
|
||||
|
||||
|
@ -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]
|
||||
|
11
dom/workers/test/serviceworkers/simpleregister/index.html
Normal file
11
dom/workers/test/serviceworkers/simpleregister/index.html
Normal 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>
|
61
dom/workers/test/serviceworkers/test_controller.html
Normal file
61
dom/workers/test/serviceworkers/test_controller.html
Normal 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>
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
Loading…
x
Reference in New Issue
Block a user