From a2d3be8aebf292e16d092d70ee1e19796bf4a9a5 Mon Sep 17 00:00:00 2001 From: Catalin Badea Date: Wed, 27 Aug 2014 10:24:09 -0700 Subject: [PATCH] Bug 982726 - Patch 1 - Service Worker: ServiceWorkerClients and Client interfaces with getServiced(). r=baku --HG-- extra : transplant_source : %06f%1C%BE%29%D4F%BAeN%0CI_%93y%8A%8FE%E5%BB --- dom/bindings/Bindings.conf | 10 + dom/webidl/ServiceWorkerClient.webidl | 14 ++ dom/webidl/ServiceWorkerClients.webidl | 19 ++ dom/webidl/ServiceWorkerGlobalScope.webidl | 5 +- dom/webidl/moz.build | 2 + dom/workers/ServiceWorkerClient.cpp | 29 +++ dom/workers/ServiceWorkerClient.h | 59 +++++ dom/workers/ServiceWorkerClients.cpp | 229 ++++++++++++++++++ dom/workers/ServiceWorkerClients.h | 56 +++++ dom/workers/ServiceWorkerManager.cpp | 51 ++++ dom/workers/ServiceWorkerManager.h | 4 + dom/workers/WorkerScope.cpp | 8 + dom/workers/WorkerScope.h | 16 ++ dom/workers/moz.build | 4 + .../serviceworkers/get_serviced_worker.js | 16 ++ dom/workers/test/serviceworkers/mochitest.ini | 3 + .../serviceworkers/sw_clients/simple.html | 25 ++ .../serviceworkers/test_get_serviced.html | 57 +++++ 18 files changed, 603 insertions(+), 4 deletions(-) create mode 100644 dom/webidl/ServiceWorkerClient.webidl create mode 100644 dom/webidl/ServiceWorkerClients.webidl create mode 100644 dom/workers/ServiceWorkerClient.cpp create mode 100644 dom/workers/ServiceWorkerClient.h create mode 100644 dom/workers/ServiceWorkerClients.cpp create mode 100644 dom/workers/ServiceWorkerClients.h create mode 100644 dom/workers/test/serviceworkers/get_serviced_worker.js create mode 100644 dom/workers/test/serviceworkers/sw_clients/simple.html create mode 100644 dom/workers/test/serviceworkers/test_get_serviced.html diff --git a/dom/bindings/Bindings.conf b/dom/bindings/Bindings.conf index 969b3e7809d3..0bb7f8dbb8bf 100644 --- a/dom/bindings/Bindings.conf +++ b/dom/bindings/Bindings.conf @@ -1058,6 +1058,16 @@ DOMInterfaces = { 'headerFile': 'mozilla/dom/workers/bindings/ServiceWorker.h', }, +'ServiceWorkerClient': { + 'nativeType': 'mozilla::dom::workers::ServiceWorkerClient', + 'headerFile': 'mozilla/dom/workers/bindings/ServiceWorkerClient.h', +}, + +'ServiceWorkerClients': { + 'nativeType': 'mozilla::dom::workers::ServiceWorkerClients', + 'headerFile': 'mozilla/dom/workers/bindings/ServiceWorkerClients.h', +}, + 'ServiceWorkerGlobalScope': { 'headerFile': 'mozilla/dom/WorkerScope.h', 'workers': True, diff --git a/dom/webidl/ServiceWorkerClient.webidl b/dom/webidl/ServiceWorkerClient.webidl new file mode 100644 index 000000000000..2473fb572fe9 --- /dev/null +++ b/dom/webidl/ServiceWorkerClient.webidl @@ -0,0 +1,14 @@ +/* -*- 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/. + * + * The origin of this IDL file is + * http://slightlyoff.github.io/ServiceWorker/spec/service_worker/index.html + * + */ + +[Exposed=ServiceWorker] +interface ServiceWorkerClient { + readonly attribute unsigned long id; +}; diff --git a/dom/webidl/ServiceWorkerClients.webidl b/dom/webidl/ServiceWorkerClients.webidl new file mode 100644 index 000000000000..8d88181ddc01 --- /dev/null +++ b/dom/webidl/ServiceWorkerClients.webidl @@ -0,0 +1,19 @@ +/* -*- 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/. + * + * The origin of this IDL file is + * http://slightlyoff.github.io/ServiceWorker/spec/service_worker/index.html + * + */ + +[Exposed=ServiceWorker] +interface ServiceWorkerClients { + // A list of client objects, identifiable by ID, that correspond to windows + // (or workers) that are "controlled" by this SW + [Throws] + Promise?> getServiced(); + [Throws] + Promise reloadAll(); +}; diff --git a/dom/webidl/ServiceWorkerGlobalScope.webidl b/dom/webidl/ServiceWorkerGlobalScope.webidl index 5f2518a4f704..6fa74e66f623 100644 --- a/dom/webidl/ServiceWorkerGlobalScope.webidl +++ b/dom/webidl/ServiceWorkerGlobalScope.webidl @@ -16,10 +16,7 @@ interface ServiceWorkerGlobalScope : WorkerGlobalScope { // FIXME(nsm): Bug 982725 // readonly attribute CacheList caches; - // FIXME(nsm): Bug 982726 - // A container for a list of window objects, identifiable by ID, that - // correspond to windows (or workers) that are "controlled" by this SW - // readonly attribute ServiceWorkerClients clients; + readonly attribute ServiceWorkerClients clients; [Unforgeable] readonly attribute DOMString scope; diff --git a/dom/webidl/moz.build b/dom/webidl/moz.build index 9a45de07c42b..db2eef8fd6b2 100644 --- a/dom/webidl/moz.build +++ b/dom/webidl/moz.build @@ -325,6 +325,8 @@ WEBIDL_FILES = [ 'ScrollAreaEvent.webidl', 'Selection.webidl', 'ServiceWorker.webidl', + 'ServiceWorkerClient.webidl', + 'ServiceWorkerClients.webidl', 'ServiceWorkerContainer.webidl', 'ServiceWorkerGlobalScope.webidl', 'ServiceWorkerRegistration.webidl', diff --git a/dom/workers/ServiceWorkerClient.cpp b/dom/workers/ServiceWorkerClient.cpp new file mode 100644 index 000000000000..2a2e1c28b3e0 --- /dev/null +++ b/dom/workers/ServiceWorkerClient.cpp @@ -0,0 +1,29 @@ +/* -*- 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 "ServiceWorkerClient.h" + +#include "mozilla/dom/ServiceWorkerClientBinding.h" + +using namespace mozilla::dom; +using namespace mozilla::dom::workers; + +NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(ServiceWorkerClient, mOwner) + +NS_IMPL_CYCLE_COLLECTING_ADDREF(ServiceWorkerClient) +NS_IMPL_CYCLE_COLLECTING_RELEASE(ServiceWorkerClient) + +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ServiceWorkerClient) + NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY + NS_INTERFACE_MAP_ENTRY(nsISupports) +NS_INTERFACE_MAP_END + +JSObject* +ServiceWorkerClient::WrapObject(JSContext* aCx) +{ + return ServiceWorkerClientBinding::Wrap(aCx, this); +} + diff --git a/dom/workers/ServiceWorkerClient.h b/dom/workers/ServiceWorkerClient.h new file mode 100644 index 000000000000..7ad4c4aff80e --- /dev/null +++ b/dom/workers/ServiceWorkerClient.h @@ -0,0 +1,59 @@ +/* -*- 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_serviceworkerclient_h +#define mozilla_dom_workers_serviceworkerclient_h + +#include "nsCOMPtr.h" +#include "nsWrapperCache.h" + +namespace mozilla { +namespace dom { + +class Promise; + +namespace workers { + +class ServiceWorkerClient MOZ_FINAL : public nsISupports, + public nsWrapperCache +{ +public: + NS_DECL_CYCLE_COLLECTING_ISUPPORTS + NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(ServiceWorkerClient) + + ServiceWorkerClient(nsISupports* aOwner, uint64_t aId) + : mOwner(aOwner), + mId(aId) + { + SetIsDOMBinding(); + } + + uint32_t Id() const + { + return mId; + } + + nsISupports* GetParentObject() const + { + return mOwner; + } + + JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE; + +private: + ~ServiceWorkerClient() + { + } + + nsCOMPtr mOwner; + uint64_t mId; +}; + +} // namespace workers +} // namespace dom +} // namespace mozilla + +#endif // mozilla_dom_workers_serviceworkerclient_h diff --git a/dom/workers/ServiceWorkerClients.cpp b/dom/workers/ServiceWorkerClients.cpp new file mode 100644 index 000000000000..cc2129cf8753 --- /dev/null +++ b/dom/workers/ServiceWorkerClients.cpp @@ -0,0 +1,229 @@ +/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */ +/* 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 "ServiceWorkerClient.h" +#include "ServiceWorkerClients.h" +#include "ServiceWorkerManager.h" + +#include "WorkerPrivate.h" +#include "WorkerRunnable.h" +#include "WorkerScope.h" + +#include "mozilla/dom/Promise.h" +#include "mozilla/dom/ServiceWorkerClientsBinding.h" + +using namespace mozilla; +using namespace mozilla::dom; +using namespace mozilla::dom::workers; + +NS_IMPL_CYCLE_COLLECTING_ADDREF(ServiceWorkerClients) +NS_IMPL_CYCLE_COLLECTING_RELEASE(ServiceWorkerClients) +NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(ServiceWorkerClients, mWorkerScope) + +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ServiceWorkerClients) + NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY + NS_INTERFACE_MAP_ENTRY(nsISupports) +NS_INTERFACE_MAP_END + +ServiceWorkerClients::ServiceWorkerClients(ServiceWorkerGlobalScope* aWorkerScope) + : mWorkerScope(aWorkerScope) +{ + MOZ_ASSERT(mWorkerScope); + SetIsDOMBinding(); +} + +JSObject* +ServiceWorkerClients::WrapObject(JSContext* aCx) +{ + return ServiceWorkerClientsBinding::Wrap(aCx, this); +} + +namespace { + +// Helper class used for passing the promise between threads while +// keeping the worker alive. +class PromiseHolder MOZ_FINAL : public WorkerFeature +{ + NS_INLINE_DECL_THREADSAFE_REFCOUNTING(PromiseHolder) + +public: + PromiseHolder(WorkerPrivate* aWorkerPrivate, + Promise* aPromise) + : mWorkerPrivate(aWorkerPrivate), + mPromise(aPromise), + mClean(false) + { + MOZ_ASSERT(mWorkerPrivate); + mWorkerPrivate->AssertIsOnWorkerThread(); + MOZ_ASSERT(mPromise); + + if (NS_WARN_IF(!mWorkerPrivate->AddFeature(mWorkerPrivate->GetJSContext(), this))) { + // Worker has been canceled and will go away. + // The ResolvePromiseWorkerRunnable won't run, so we can set mPromise to + // nullptr. + mPromise = nullptr; + mClean = true; + } + } + + Promise* + Get() const + { + return mPromise; + } + + void + Clean() + { + mWorkerPrivate->AssertIsOnWorkerThread(); + + if (mClean) { + return; + } + + mPromise = nullptr; + mWorkerPrivate->RemoveFeature(mWorkerPrivate->GetJSContext(), this); + mClean = true; + } + + bool + Notify(JSContext* aCx, Status aStatus) + { + mWorkerPrivate->AssertIsOnWorkerThread(); + + if (aStatus > Running) { + Clean(); + } + + return true; + } + +private: + ~PromiseHolder() + { + MOZ_ASSERT(mClean); + } + + WorkerPrivate* mWorkerPrivate; + nsRefPtr mPromise; + + bool mClean; +}; + +class ResolvePromiseWorkerRunnable MOZ_FINAL : public WorkerRunnable +{ + nsRefPtr mPromiseHolder; + nsAutoPtr> mValue; + +public: + ResolvePromiseWorkerRunnable(WorkerPrivate* aWorkerPrivate, + PromiseHolder* aPromiseHolder, + nsAutoPtr>& aValue) + : WorkerRunnable(aWorkerPrivate, WorkerThreadModifyBusyCount), + mPromiseHolder(aPromiseHolder), + mValue(aValue) + { + AssertIsOnMainThread(); + } + + bool + WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate) + { + MOZ_ASSERT(aWorkerPrivate); + aWorkerPrivate->AssertIsOnWorkerThread(); + + Promise* promise = mPromiseHolder->Get(); + MOZ_ASSERT(promise); + + nsTArray> ret; + for (size_t i = 0; i < mValue->Length(); i++) { + ret.AppendElement(nsRefPtr( + new ServiceWorkerClient(promise->GetParentObject(), + mValue->ElementAt(i)))); + } + promise->MaybeResolve(ret); + + // release the reference on the worker thread. + mPromiseHolder->Clean(); + + return true; + } +}; + +class GetServicedRunnable MOZ_FINAL : public nsRunnable +{ + WorkerPrivate* mWorkerPrivate; + nsCString mScope; + nsRefPtr mPromiseHolder; +public: + GetServicedRunnable(WorkerPrivate* aWorkerPrivate, + Promise* aPromise, + const nsCString& aScope) + : mWorkerPrivate(aWorkerPrivate), + mScope(aScope) + { + MOZ_ASSERT(aWorkerPrivate); + aWorkerPrivate->AssertIsOnWorkerThread(); + mPromiseHolder = new PromiseHolder(aWorkerPrivate, aPromise); + } + + NS_IMETHOD + Run() MOZ_OVERRIDE + { + AssertIsOnMainThread(); + + nsRefPtr swm = ServiceWorkerManager::GetInstance(); + nsAutoPtr> result(new nsTArray()); + + swm->GetServicedClients(mScope, result); + nsRefPtr r = + new ResolvePromiseWorkerRunnable(mWorkerPrivate, mPromiseHolder, result); + + AutoSafeJSContext cx; + r->Dispatch(cx); + return NS_OK; + } +}; + +} // anonymous namespace + +already_AddRefed +ServiceWorkerClients::GetServiced(ErrorResult& aRv) +{ + WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate(); + MOZ_ASSERT(workerPrivate); + workerPrivate->AssertIsOnWorkerThread(); + + DOMString scope; + mWorkerScope->GetScope(scope); + + nsRefPtr promise = Promise::Create(mWorkerScope, aRv); + if (NS_WARN_IF(aRv.Failed())) { + return nullptr; + } + + nsRefPtr r = + new GetServicedRunnable(workerPrivate, promise, NS_ConvertUTF16toUTF8(scope)); + nsresult rv = NS_DispatchToMainThread(r); + + if (NS_WARN_IF(NS_FAILED(rv))) { + promise->MaybeReject(NS_ERROR_NOT_AVAILABLE); + } + + return promise.forget(); +} + +// FIXME(catalinb): Bug 1045257 - Implement ReloadAll +already_AddRefed +ServiceWorkerClients::ReloadAll(ErrorResult& aRv) +{ + nsRefPtr promise = Promise::Create(mWorkerScope, aRv); + if (NS_WARN_IF(aRv.Failed())) { + return nullptr; + } + promise->MaybeReject(NS_ERROR_NOT_AVAILABLE); + return promise.forget(); +} + diff --git a/dom/workers/ServiceWorkerClients.h b/dom/workers/ServiceWorkerClients.h new file mode 100644 index 000000000000..39cf03a6dab6 --- /dev/null +++ b/dom/workers/ServiceWorkerClients.h @@ -0,0 +1,56 @@ +/* -*- 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_serviceworkerclients_h +#define mozilla_dom_workers_serviceworkerclients_h + +#include "nsAutoPtr.h" +#include "nsWrapperCache.h" + +namespace mozilla { + +class ErrorResult; + +namespace dom { + +class Promise; + +namespace workers { + +class ServiceWorkerGlobalScope; + +class ServiceWorkerClients MOZ_FINAL : public nsISupports, + public nsWrapperCache +{ +public: + NS_DECL_CYCLE_COLLECTING_ISUPPORTS + NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(ServiceWorkerClients) + + ServiceWorkerClients(ServiceWorkerGlobalScope* aWorkerScope); + + already_AddRefed GetServiced(ErrorResult& aRv); + already_AddRefed ReloadAll(ErrorResult& aRv); + + JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE; + + ServiceWorkerGlobalScope* GetParentObject() const + { + return mWorkerScope; + } + +private: + ~ServiceWorkerClients() + { + } + + nsRefPtr mWorkerScope; +}; + +} // namespace workers +} // namespace dom +} // namespace mozilla + +#endif // mozilla_dom_workers_serviceworkerclients_h diff --git a/dom/workers/ServiceWorkerManager.cpp b/dom/workers/ServiceWorkerManager.cpp index 32aa670c4f4c..15b40cedc5f2 100644 --- a/dom/workers/ServiceWorkerManager.cpp +++ b/dom/workers/ServiceWorkerManager.cpp @@ -24,6 +24,7 @@ #include "RuntimeService.h" #include "ServiceWorker.h" +#include "ServiceWorkerClient.h" #include "ServiceWorkerRegistration.h" #include "ServiceWorkerEvents.h" #include "WorkerInlines.h" @@ -2173,4 +2174,54 @@ ServiceWorkerManager::InvalidateServiceWorkerRegistrationWorker(ServiceWorkerReg } } +namespace { + +class MOZ_STACK_CLASS FilterRegistrationData +{ +public: + FilterRegistrationData(nsTArray* aDocuments, + ServiceWorkerRegistrationInfo* aRegistration) + : mDocuments(aDocuments), + mRegistration(aRegistration) + { + } + + nsTArray* mDocuments; + nsRefPtr mRegistration; +}; + +static PLDHashOperator +EnumControlledDocuments(nsISupports* aKey, + ServiceWorkerRegistrationInfo* aRegistration, + void* aData) +{ + FilterRegistrationData* data = static_cast(aData); + if (data->mRegistration != aRegistration) { + return PL_DHASH_NEXT; + } + nsCOMPtr document = do_QueryInterface(aKey); + if (!document || !document->GetInnerWindow()) { + return PL_DHASH_NEXT; + } + + data->mDocuments->AppendElement(document->GetInnerWindow()->WindowID()); + return PL_DHASH_NEXT; +} + +} // anonymous namespace + +void +ServiceWorkerManager::GetServicedClients(const nsCString& aScope, + nsTArray* aControlledDocuments) +{ + nsRefPtr domainInfo = GetDomainInfo(aScope); + nsRefPtr registration = + domainInfo->GetRegistration(aScope); + MOZ_ASSERT(registration); + FilterRegistrationData data(aControlledDocuments, registration); + + domainInfo->mControlledDocuments.EnumerateRead(EnumControlledDocuments, + &data); +} + END_WORKERS_NAMESPACE diff --git a/dom/workers/ServiceWorkerManager.h b/dom/workers/ServiceWorkerManager.h index 68f80165479d..2fb58bb63ca6 100644 --- a/dom/workers/ServiceWorkerManager.h +++ b/dom/workers/ServiceWorkerManager.h @@ -318,6 +318,10 @@ public: uint32_t aColumnNumber, uint32_t aFlags); + void + GetServicedClients(const nsCString& aScope, + nsTArray* aControlledDocuments); + static already_AddRefed GetInstance(); diff --git a/dom/workers/WorkerScope.cpp b/dom/workers/WorkerScope.cpp index ef2475ad3e53..d353cbf55a24 100644 --- a/dom/workers/WorkerScope.cpp +++ b/dom/workers/WorkerScope.cpp @@ -346,6 +346,14 @@ SharedWorkerGlobalScope::WrapGlobalObject(JSContext* aCx) true); } +NS_IMPL_CYCLE_COLLECTION_INHERITED(ServiceWorkerGlobalScope, WorkerGlobalScope, + mClients) +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(ServiceWorkerGlobalScope) +NS_INTERFACE_MAP_END_INHERITING(WorkerGlobalScope) + +NS_IMPL_ADDREF_INHERITED(ServiceWorkerGlobalScope, WorkerGlobalScope) +NS_IMPL_RELEASE_INHERITED(ServiceWorkerGlobalScope, WorkerGlobalScope) + ServiceWorkerGlobalScope::ServiceWorkerGlobalScope(WorkerPrivate* aWorkerPrivate, const nsACString& aScope) : WorkerGlobalScope(aWorkerPrivate), diff --git a/dom/workers/WorkerScope.h b/dom/workers/WorkerScope.h index ea4918d5805b..eed5fb4592e2 100644 --- a/dom/workers/WorkerScope.h +++ b/dom/workers/WorkerScope.h @@ -8,6 +8,7 @@ #include "Workers.h" #include "mozilla/DOMEventTargetHelper.h" +#include "ServiceWorkerClients.h" namespace mozilla { namespace dom { @@ -163,9 +164,15 @@ public: class ServiceWorkerGlobalScope MOZ_FINAL : public WorkerGlobalScope { const nsString mScope; + nsRefPtr mClients; + ~ServiceWorkerGlobalScope() { } public: + NS_DECL_ISUPPORTS_INHERITED + NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(ServiceWorkerGlobalScope, + WorkerGlobalScope) + ServiceWorkerGlobalScope(WorkerPrivate* aWorkerPrivate, const nsACString& aScope); virtual JSObject* @@ -195,6 +202,15 @@ public: // FIXME(nsm): Bug 982728 } + ServiceWorkerClients* + Clients() { + if (!mClients) { + mClients = new ServiceWorkerClients(this); + } + + return mClients; + } + IMPL_EVENT_HANDLER(activate) IMPL_EVENT_HANDLER(beforeevicted) IMPL_EVENT_HANDLER(evicted) diff --git a/dom/workers/moz.build b/dom/workers/moz.build index 1502dc5a6051..305cfc3b9139 100644 --- a/dom/workers/moz.build +++ b/dom/workers/moz.build @@ -29,6 +29,8 @@ EXPORTS.mozilla.dom.workers.bindings += [ 'Navigator.h', 'Performance.h', 'ServiceWorker.h', + 'ServiceWorkerClient.h', + 'ServiceWorkerClients.h', 'SharedWorker.h', 'URL.h', 'WorkerFeature.h', @@ -51,6 +53,8 @@ SOURCES += [ 'RuntimeService.cpp', 'ScriptLoader.cpp', 'ServiceWorker.cpp', + 'ServiceWorkerClient.cpp', + 'ServiceWorkerClients.cpp', 'ServiceWorkerContainer.cpp', 'ServiceWorkerEvents.cpp', 'ServiceWorkerManager.cpp', diff --git a/dom/workers/test/serviceworkers/get_serviced_worker.js b/dom/workers/test/serviceworkers/get_serviced_worker.js new file mode 100644 index 000000000000..b97e4145034c --- /dev/null +++ b/dom/workers/test/serviceworkers/get_serviced_worker.js @@ -0,0 +1,16 @@ +function loop() { + self.clients.getServiced().then(function(result) { + setTimeout(loop, 0); + }); +} + +onactivate = function(e) { + // spam getServiced until the worker is closed. + loop(); +} + +onclose = function(e) { + for (var i = 0; i < 100; ++i) { + self.clients.getServiced(); + } +} diff --git a/dom/workers/test/serviceworkers/mochitest.ini b/dom/workers/test/serviceworkers/mochitest.ini index 20da13ab8a92..c8e7660cc5b1 100644 --- a/dom/workers/test/serviceworkers/mochitest.ini +++ b/dom/workers/test/serviceworkers/mochitest.ini @@ -10,7 +10,10 @@ support-files = simpleregister/ready.html controller/index.html unregister/index.html + sw_clients/simple.html + get_serviced_worker.js +[test_get_serviced.html] [test_installation_simple.html] [test_install_event.html] [test_navigator.html] diff --git a/dom/workers/test/serviceworkers/sw_clients/simple.html b/dom/workers/test/serviceworkers/sw_clients/simple.html new file mode 100644 index 000000000000..6b1551928d35 --- /dev/null +++ b/dom/workers/test/serviceworkers/sw_clients/simple.html @@ -0,0 +1,25 @@ + + + + + Bug 982726 - test get_serviced not crashing + + + + +

+ +

+
+
+
+
+
diff --git a/dom/workers/test/serviceworkers/test_get_serviced.html b/dom/workers/test/serviceworkers/test_get_serviced.html
new file mode 100644
index 000000000000..8c47401a079d
--- /dev/null
+++ b/dom/workers/test/serviceworkers/test_get_serviced.html
@@ -0,0 +1,57 @@
+
+
+
+
+  Bug 982726 - test get_serviced not crashing
+  
+  
+
+
+

+ +

+
+
+
+
+