diff --git a/LayoutTests/http/tests/serviceworker/interfaces.html b/LayoutTests/http/tests/serviceworker/interfaces.html
index 4967ad7c0c8..2d133588f60 100644
--- a/LayoutTests/http/tests/serviceworker/interfaces.html
+++ b/LayoutTests/http/tests/serviceworker/interfaces.html
@@ -42,6 +42,7 @@
{
scriptURL: 'string',
state: 'string',
+ terminate: 'function',
onstatechange: EVENT_HANDLER
});
return registration.unregister();
diff --git a/LayoutTests/http/tests/serviceworker/resources/fetch-body-stream-worker.js b/LayoutTests/http/tests/serviceworker/resources/fetch-body-stream-worker.js
index 88e35b7c292..f3f47f9cf30 100644
--- a/LayoutTests/http/tests/serviceworker/resources/fetch-body-stream-worker.js
+++ b/LayoutTests/http/tests/serviceworker/resources/fetch-body-stream-worker.js
@@ -8,7 +8,6 @@ self.onmessage = function(e) {
function quit(port) {
port.postMessage('quit');
- self.close();
}
function doFetchTwiceTest(port) {
@@ -92,4 +91,4 @@ function doTextTest(port) {
doJSONTest(port);
});
});
-}
\ No newline at end of file
+}
diff --git a/LayoutTests/http/tests/serviceworker/resources/fetch-worker.js b/LayoutTests/http/tests/serviceworker/resources/fetch-worker.js
index 7f5d401c3f0..b086a961b7b 100644
--- a/LayoutTests/http/tests/serviceworker/resources/fetch-worker.js
+++ b/LayoutTests/http/tests/serviceworker/resources/fetch-worker.js
@@ -15,12 +15,19 @@ var testTargets = [
];
function doNextFetchTest(port) {
+
+ function runInfiniteFetchLoop() {
+ fetch('dummy.html')
+ .then(function() { runInfiniteFetchLoop(); });
+ }
+
if (testTargets.length == 0) {
- port.postMessage('quit');
- // Destroying the execution context while fetch is happening should not cause a crash.
- fetch('dummy.html').then(function() {}).catch(function() {});
- self.close();
- return;
+ // Destroying the execution context while fetch is happening
+ // should not cause a crash.
+ runInfiniteFetchLoop();
+
+ port.postMessage('quit');
+ return;
}
var target = testTargets.shift();
fetch(target)
diff --git a/LayoutTests/http/tests/serviceworker/resources/interfaces-worker.js b/LayoutTests/http/tests/serviceworker/resources/interfaces-worker.js
index f5b7fcfccf5..dc55410e4c2 100644
--- a/LayoutTests/http/tests/serviceworker/resources/interfaces-worker.js
+++ b/LayoutTests/http/tests/serviceworker/resources/interfaces-worker.js
@@ -9,6 +9,7 @@ test(function() {
{
scope: 'string',
clients: 'object',
+ close: 'function',
onactivate: EVENT_HANDLER,
onfetch: EVENT_HANDLER,
diff --git a/LayoutTests/http/tests/serviceworker/resources/serviceworkerglobalscope-close-worker.js b/LayoutTests/http/tests/serviceworker/resources/serviceworkerglobalscope-close-worker.js
new file mode 100644
index 00000000000..092e41d5420
--- /dev/null
+++ b/LayoutTests/http/tests/serviceworker/resources/serviceworkerglobalscope-close-worker.js
@@ -0,0 +1,8 @@
+importScripts('interfaces.js');
+importScripts('worker-test-harness.js');
+
+test(function() {
+ assert_throws({name: 'InvalidAccessError'}, function() {
+ self.close();
+ });
+}, 'ServiceWorkerGlobalScope close operation');
diff --git a/LayoutTests/http/tests/serviceworker/serviceworkerglobalscope-close.html b/LayoutTests/http/tests/serviceworker/serviceworkerglobalscope-close.html
new file mode 100644
index 00000000000..5665b99bd40
--- /dev/null
+++ b/LayoutTests/http/tests/serviceworker/serviceworkerglobalscope-close.html
@@ -0,0 +1,12 @@
+
+
ServiceWorkerGlobalScope: close operation
+
+
+
+
diff --git a/LayoutTests/http/tests/serviceworker/serviceworkerobject-terminate.html b/LayoutTests/http/tests/serviceworker/serviceworkerobject-terminate.html
new file mode 100644
index 00000000000..f1348147012
--- /dev/null
+++ b/LayoutTests/http/tests/serviceworker/serviceworkerobject-terminate.html
@@ -0,0 +1,24 @@
+
+ServiceWorker object: terminate operation
+
+
+
+
diff --git a/Source/modules/serviceworkers/ServiceWorker.cpp b/Source/modules/serviceworkers/ServiceWorker.cpp
index 2a22ed229f6..53f8e0c6965 100644
--- a/Source/modules/serviceworkers/ServiceWorker.cpp
+++ b/Source/modules/serviceworkers/ServiceWorker.cpp
@@ -85,6 +85,11 @@ void ServiceWorker::postMessage(ExecutionContext*, PassRefPtrpostMessage(messageString, webChannels.leakPtr());
}
+void ServiceWorker::terminate(ExceptionState& exceptionState)
+{
+ exceptionState.throwDOMException(InvalidAccessError, "Not supported.");
+}
+
bool ServiceWorker::isReady()
{
return m_proxyState == Ready;
diff --git a/Source/modules/serviceworkers/ServiceWorker.h b/Source/modules/serviceworkers/ServiceWorker.h
index ee36f9870da..dd77288e50a 100644
--- a/Source/modules/serviceworkers/ServiceWorker.h
+++ b/Source/modules/serviceworkers/ServiceWorker.h
@@ -56,6 +56,7 @@ class ServiceWorker FINAL : public AbstractWorker, public WebServiceWorkerProxy
static void dispose(WebType*);
void postMessage(ExecutionContext*, PassRefPtr message, const MessagePortArray*, ExceptionState&);
+ void terminate(ExceptionState&);
String scriptURL() const;
const AtomicString& state() const;
diff --git a/Source/modules/serviceworkers/ServiceWorker.idl b/Source/modules/serviceworkers/ServiceWorker.idl
index 69171dfaceb..ec8d558f06b 100644
--- a/Source/modules/serviceworkers/ServiceWorker.idl
+++ b/Source/modules/serviceworkers/ServiceWorker.idl
@@ -47,6 +47,8 @@ enum ServiceWorkerState {
// FIXME: Should inherit this from Worker.
[Custom, RaisesException] void postMessage(SerializedScriptValue message, optional sequence transfer);
+ [RaisesException] void terminate();
+
readonly attribute ScalarValueString scriptURL;
readonly attribute ServiceWorkerState state;
diff --git a/Source/modules/serviceworkers/ServiceWorkerGlobalScope.cpp b/Source/modules/serviceworkers/ServiceWorkerGlobalScope.cpp
index 4b8b024ffb1..ddcfd1f5c8b 100644
--- a/Source/modules/serviceworkers/ServiceWorkerGlobalScope.cpp
+++ b/Source/modules/serviceworkers/ServiceWorkerGlobalScope.cpp
@@ -161,6 +161,11 @@ PassRefPtrWillBeRawPtr ServiceWorkerGlobalScope::clients()
return m_clients;
}
+void ServiceWorkerGlobalScope::close(ExceptionState& exceptionState)
+{
+ exceptionState.throwDOMException(InvalidAccessError, "Not supported.");
+}
+
const AtomicString& ServiceWorkerGlobalScope::interfaceName() const
{
return EventTargetNames::ServiceWorkerGlobalScope;
diff --git a/Source/modules/serviceworkers/ServiceWorkerGlobalScope.h b/Source/modules/serviceworkers/ServiceWorkerGlobalScope.h
index 3fe316c52c8..06e5aa5087c 100644
--- a/Source/modules/serviceworkers/ServiceWorkerGlobalScope.h
+++ b/Source/modules/serviceworkers/ServiceWorkerGlobalScope.h
@@ -67,6 +67,8 @@ class ServiceWorkerGlobalScope FINAL : public WorkerGlobalScope {
ScriptPromise fetch(ScriptState*, const String&);
ScriptPromise fetch(ScriptState*, const String&, const Dictionary&);
+ void close(ExceptionState&);
+
// EventTarget
virtual const AtomicString& interfaceName() const OVERRIDE;
diff --git a/Source/modules/serviceworkers/ServiceWorkerGlobalScope.idl b/Source/modules/serviceworkers/ServiceWorkerGlobalScope.idl
index 73aa2df48f3..2b4ec9fe53d 100644
--- a/Source/modules/serviceworkers/ServiceWorkerGlobalScope.idl
+++ b/Source/modules/serviceworkers/ServiceWorkerGlobalScope.idl
@@ -43,6 +43,8 @@
[CallWith=ScriptState] Promise fetch(DOMString request, optional Dictionary requestInitDict);
[CallWith=ScriptState] Promise fetch(Request request, optional Dictionary requestInitDict);
+ [RaisesException] void close();
+
attribute EventHandler onactivate;
attribute EventHandler onfetch;
attribute EventHandler oninstall;