Start exposing navigator.serviceWorker inside service workers
authorcdumez@apple.com <cdumez@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 28 Nov 2017 18:22:20 +0000 (18:22 +0000)
committercdumez@apple.com <cdumez@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 28 Nov 2017 18:22:20 +0000 (18:22 +0000)
https://bugs.webkit.org/show_bug.cgi?id=180087

Reviewed by Brady Eidson.

Source/WebCore:

Start exposing navigator.serviceWorker inside service workers as per:
- https://w3c.github.io/ServiceWorker/#navigator-serviceworker

Although the property is now exposed, the API on ServiceWorkerContainer is not
supported yet inside service workers and the promise will be rejected. This will
be implemented in a follow-up.

Test: http/tests/workers/service/WorkerNavigator_serviceWorker.html

* Sources.txt:
* WebCore.xcodeproj/project.pbxproj:
* bindings/js/JSWorkerNavigatorCustom.cpp: Added.
(WebCore::JSWorkerNavigator::visitAdditionalChildren):
* page/WorkerNavigator.idl:
* workers/service/ServiceWorker.idl:
* workers/service/ServiceWorkerContainer.cpp:
(WebCore::ServiceWorkerContainer::controller const):
(WebCore::ServiceWorkerContainer::addRegistration):
(WebCore::ServiceWorkerContainer::getRegistration):
(WebCore::ServiceWorkerContainer::getRegistrations):
* workers/service/ServiceWorkerContainer.idl:
* workers/service/ServiceWorkerRegistration.cpp:
(WebCore::ServiceWorkerRegistration::update):
(WebCore::ServiceWorkerRegistration::unregister):
* workers/service/ServiceWorkerRegistration.idl:

LayoutTests:

Add layout test coverage.

* http/tests/workers/service/WorkerNavigator_serviceWorker-expected.txt: Added.
* http/tests/workers/service/WorkerNavigator_serviceWorker.html: Added.
* http/tests/workers/service/resources/WorkerNavigator_serviceWorker-worker.js: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@225221 268f45cc-cd09-0410-ab3c-d52691b4dbfc

14 files changed:
LayoutTests/ChangeLog
LayoutTests/http/tests/workers/service/WorkerNavigator_serviceWorker-expected.txt [new file with mode: 0644]
LayoutTests/http/tests/workers/service/WorkerNavigator_serviceWorker.html [new file with mode: 0644]
LayoutTests/http/tests/workers/service/resources/WorkerNavigator_serviceWorker-worker.js [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/Sources.txt
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/bindings/js/JSWorkerNavigatorCustom.cpp [new file with mode: 0644]
Source/WebCore/page/WorkerNavigator.idl
Source/WebCore/workers/service/ServiceWorker.idl
Source/WebCore/workers/service/ServiceWorkerContainer.cpp
Source/WebCore/workers/service/ServiceWorkerContainer.idl
Source/WebCore/workers/service/ServiceWorkerRegistration.cpp
Source/WebCore/workers/service/ServiceWorkerRegistration.idl

index f18d4ea..6326af8 100644 (file)
@@ -1,3 +1,16 @@
+2017-11-28  Chris Dumez  <cdumez@apple.com>
+
+        Start exposing navigator.serviceWorker inside service workers
+        https://bugs.webkit.org/show_bug.cgi?id=180087
+
+        Reviewed by Brady Eidson.
+
+        Add layout test coverage.
+
+        * http/tests/workers/service/WorkerNavigator_serviceWorker-expected.txt: Added.
+        * http/tests/workers/service/WorkerNavigator_serviceWorker.html: Added.
+        * http/tests/workers/service/resources/WorkerNavigator_serviceWorker-worker.js: Added.
+
 2017-11-28  Michael Catanzaro  <mcatanzaro@igalia.com>
 
         REGRESSION(r225098): [WPE] Some features have changed of value (70 new failures)
diff --git a/LayoutTests/http/tests/workers/service/WorkerNavigator_serviceWorker-expected.txt b/LayoutTests/http/tests/workers/service/WorkerNavigator_serviceWorker-expected.txt
new file mode 100644 (file)
index 0000000..ac98f23
--- /dev/null
@@ -0,0 +1,13 @@
+* Tests that workerNavigator.serviceWorker exists
+
+Object.getOwnPropertyDescriptor(self.navigator.__proto__, 'serviceWorker') returned {"enumerable":true,"configurable":true}
+navigator.serviceWorker.__proto__ === self.ServiceWorkerContainer.prototype returned true
+navigator.serviceWorker.controller === null returned true
+Object.getOwnPropertyDescriptor(self, 'ServiceWorkerContainer') returned {"writable":true,"enumerable":false,"configurable":true}
+Object.getOwnPropertyDescriptor(self, 'ServiceWorker') returned {"writable":true,"enumerable":false,"configurable":true}
+Object.getOwnPropertyDescriptor(self, 'ServiceWorkerRegistration') returned {"writable":true,"enumerable":false,"configurable":true}
+Object.getOwnPropertyDescriptor(self.navigator.serviceWorker.__proto__, 'controller') returned {"enumerable":true,"configurable":true}
+Object.getOwnPropertyDescriptor(self.navigator.serviceWorker.__proto__, 'register') returned {"writable":true,"enumerable":true,"configurable":true}
+Object.getOwnPropertyDescriptor(self.navigator.serviceWorker.__proto__, 'getRegistration') returned {"writable":true,"enumerable":true,"configurable":true}
+Object.getOwnPropertyDescriptor(self.navigator.serviceWorker.__proto__, 'getRegistrations') returned {"writable":true,"enumerable":true,"configurable":true}
+
diff --git a/LayoutTests/http/tests/workers/service/WorkerNavigator_serviceWorker.html b/LayoutTests/http/tests/workers/service/WorkerNavigator_serviceWorker.html
new file mode 100644 (file)
index 0000000..24b29d4
--- /dev/null
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html>
+<body>
+<script src="resources/sw-test-pre.js"></script>
+<script>
+log("* Tests that workerNavigator.serviceWorker exists");
+log("");
+
+navigator.serviceWorker.addEventListener("message", function(event) {
+    if (event.data === "DONE") {
+        finishSWTest();
+        return;
+    }
+    log(event.data);
+});
+
+navigator.serviceWorker.register("resources/WorkerNavigator_serviceWorker-worker.js", { }).then(function(registration) {
+    registration.installing.postMessage("Object.getOwnPropertyDescriptor(self.navigator.__proto__, 'serviceWorker')");
+    registration.installing.postMessage("navigator.serviceWorker.__proto__ === self.ServiceWorkerContainer.prototype");
+    registration.installing.postMessage("navigator.serviceWorker.controller === null");
+    registration.installing.postMessage("Object.getOwnPropertyDescriptor(self, 'ServiceWorkerContainer')");
+    registration.installing.postMessage("Object.getOwnPropertyDescriptor(self, 'ServiceWorker')");
+    registration.installing.postMessage("Object.getOwnPropertyDescriptor(self, 'ServiceWorkerRegistration')");
+    registration.installing.postMessage("Object.getOwnPropertyDescriptor(self.navigator.serviceWorker.__proto__, 'controller')");
+    registration.installing.postMessage("Object.getOwnPropertyDescriptor(self.navigator.serviceWorker.__proto__, 'register')");
+    registration.installing.postMessage("Object.getOwnPropertyDescriptor(self.navigator.serviceWorker.__proto__, 'getRegistration')");
+    registration.installing.postMessage("Object.getOwnPropertyDescriptor(self.navigator.serviceWorker.__proto__, 'getRegistrations')");
+    registration.installing.postMessage("DONE");
+});
+</script>
+</body>
+</html>
diff --git a/LayoutTests/http/tests/workers/service/resources/WorkerNavigator_serviceWorker-worker.js b/LayoutTests/http/tests/workers/service/resources/WorkerNavigator_serviceWorker-worker.js
new file mode 100644 (file)
index 0000000..90e64ee
--- /dev/null
@@ -0,0 +1,8 @@
+self.addEventListener("message", (event) => {
+    if (event.data === "DONE") {
+        event.source.postMessage(event.data);
+        return;
+    }
+    let result = eval(event.data);
+    event.source.postMessage(event.data + " returned " + JSON.stringify(result));
+});
index acda6f4..a025b6e 100644 (file)
@@ -1,3 +1,36 @@
+2017-11-28  Chris Dumez  <cdumez@apple.com>
+
+        Start exposing navigator.serviceWorker inside service workers
+        https://bugs.webkit.org/show_bug.cgi?id=180087
+
+        Reviewed by Brady Eidson.
+
+        Start exposing navigator.serviceWorker inside service workers as per:
+        - https://w3c.github.io/ServiceWorker/#navigator-serviceworker
+
+        Although the property is now exposed, the API on ServiceWorkerContainer is not
+        supported yet inside service workers and the promise will be rejected. This will
+        be implemented in a follow-up.
+
+        Test: http/tests/workers/service/WorkerNavigator_serviceWorker.html
+
+        * Sources.txt:
+        * WebCore.xcodeproj/project.pbxproj:
+        * bindings/js/JSWorkerNavigatorCustom.cpp: Added.
+        (WebCore::JSWorkerNavigator::visitAdditionalChildren):
+        * page/WorkerNavigator.idl:
+        * workers/service/ServiceWorker.idl:
+        * workers/service/ServiceWorkerContainer.cpp:
+        (WebCore::ServiceWorkerContainer::controller const):
+        (WebCore::ServiceWorkerContainer::addRegistration):
+        (WebCore::ServiceWorkerContainer::getRegistration):
+        (WebCore::ServiceWorkerContainer::getRegistrations):
+        * workers/service/ServiceWorkerContainer.idl:
+        * workers/service/ServiceWorkerRegistration.cpp:
+        (WebCore::ServiceWorkerRegistration::update):
+        (WebCore::ServiceWorkerRegistration::unregister):
+        * workers/service/ServiceWorkerRegistration.idl:
+
 2017-11-28  Simon Fraser  <simon.fraser@apple.com>
 
         Modernize GraphicsLayer dumping
index 8d0e0ba..1bdd782 100644 (file)
@@ -418,6 +418,7 @@ bindings/js/JSWebGPURenderPassAttachmentDescriptorCustom.cpp
 bindings/js/JSWebGPURenderingContextCustom.cpp
 bindings/js/JSWorkerGlobalScopeBase.cpp
 bindings/js/JSWorkerGlobalScopeCustom.cpp
+bindings/js/JSWorkerNavigatorCustom.cpp
 bindings/js/JSXMLDocumentCustom.cpp
 bindings/js/JSXMLHttpRequestCustom.cpp
 bindings/js/JSXPathNSResolverCustom.cpp
index 7ae3423..2d338fc 100644 (file)
                46EFAF0D1E5FB9C200E7F34B /* LowPowerModeNotifierIOS.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = LowPowerModeNotifierIOS.mm; sourceTree = "<group>"; };
                46EFAF0F1E5FB9E100E7F34B /* LowPowerModeNotifier.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LowPowerModeNotifier.cpp; sourceTree = "<group>"; };
                46EFAF101E5FB9E100E7F34B /* LowPowerModeNotifier.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LowPowerModeNotifier.h; sourceTree = "<group>"; };
+               46F91BC91FCDD0FE001599C3 /* JSWorkerNavigatorCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSWorkerNavigatorCustom.cpp; sourceTree = "<group>"; };
                490707E41219C04300D90E51 /* ANGLEWebKitBridge.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ANGLEWebKitBridge.cpp; sourceTree = "<group>"; };
                490707E51219C04300D90E51 /* ANGLEWebKitBridge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ANGLEWebKitBridge.h; sourceTree = "<group>"; };
                49291E4A134172C800E753DE /* ImageRenderingMode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImageRenderingMode.h; sourceTree = "<group>"; };
                                31A088C41E737B2C003B6609 /* JSWebGPURenderingContextCustom.cpp */,
                                31A088C51E737B2C003B6609 /* JSWebGPURenderPassAttachmentDescriptorCustom.cpp */,
                                E18258AB0EF3CD7000933242 /* JSWorkerGlobalScopeCustom.cpp */,
+                               46F91BC91FCDD0FE001599C3 /* JSWorkerNavigatorCustom.cpp */,
                                83A4A9F81CE7FD7E00709B00 /* JSXMLDocumentCustom.cpp */,
                                836C14421CDEAFCA0073493F /* JSXPathNSResolverCustom.cpp */,
                                A1C7FAA1133A5D3500D6732D /* JSXPathResultCustom.cpp */,
diff --git a/Source/WebCore/bindings/js/JSWorkerNavigatorCustom.cpp b/Source/WebCore/bindings/js/JSWorkerNavigatorCustom.cpp
new file mode 100644 (file)
index 0000000..9829cdd
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "JSWorkerNavigator.h"
+
+namespace WebCore {
+
+void JSWorkerNavigator::visitAdditionalChildren(SlotVisitor& visitor)
+{
+#if ENABLE(SERVICE_WORKER)
+    visitor.addOpaqueRoot(&wrapped().serviceWorker());
+#else
+    UNUSED_PARAM(visitor);
+#endif
+}
+
+}
index c472243..e4c2555 100644 (file)
 [
     Exposed=Worker,
     GenerateIsReachable=Impl,
+    JSCustomMarkFunction,
 ] interface WorkerNavigator {
 };
 
 WorkerNavigator implements NavigatorID;
 WorkerNavigator implements NavigatorLanguage;
 WorkerNavigator implements NavigatorOnLine;
+WorkerNavigator implements NavigatorServiceWorker;
index 741b8e2..2f3c447 100644 (file)
@@ -29,7 +29,7 @@
 [
     ActiveDOMObject,
     SecureContext,
-    Exposed=(Window),
+    Exposed=(Window,ServiceWorker),
     Conditional=SERVICE_WORKER,
     EnabledAtRuntime=ServiceWorker
 ] interface ServiceWorker : EventTarget {
index e77b8b9..f679309 100644 (file)
@@ -78,6 +78,7 @@ void ServiceWorkerContainer::derefEventTarget()
 ServiceWorker* ServiceWorkerContainer::controller() const
 {
     auto* context = scriptExecutionContext();
+    ASSERT_WITH_MESSAGE(!context || is<Document>(*context) || !context->activeServiceWorker(), "Only documents can have a controller at the moment.");
     return context ? context->activeServiceWorker() : nullptr;
 }
 
@@ -90,6 +91,12 @@ void ServiceWorkerContainer::addRegistration(const String& relativeScriptURL, co
         return;
     }
 
+    // FIXME: Add support in workers.
+    if (!is<Document>(*context)) {
+        promise->reject(Exception { NotSupportedError, ASCIILiteral("serviceWorker.register() is not yet supported in workers") });
+        return;
+    }
+
     if (relativeScriptURL.isEmpty()) {
         promise->reject(Exception { TypeError, ASCIILiteral("serviceWorker.register() cannot be called with an empty script URL") });
         return;
@@ -212,6 +219,12 @@ void ServiceWorkerContainer::getRegistration(const String& clientURL, Ref<Deferr
         return;
     }
 
+    // FIXME: Add support in workers.
+    if (!is<Document>(*context)) {
+        promise->reject(Exception { NotSupportedError, ASCIILiteral("serviceWorker.getRegistration() is not yet supported in workers") });
+        return;
+    }
+
     URL parsedURL = context->completeURL(clientURL);
     if (!protocolHostAndPortAreEqual(parsedURL, context->url())) {
         promise->reject(Exception { SecurityError, ASCIILiteral("Origin of clientURL is not client's origin") });
@@ -259,6 +272,12 @@ void ServiceWorkerContainer::getRegistrations(RegistrationsPromise&& promise)
         return;
     }
 
+    // FIXME: Add support in workers.
+    if (!is<Document>(*context)) {
+        promise.reject(Exception { NotSupportedError, ASCIILiteral("serviceWorker.getRegistrations() is not yet supported in workers") });
+        return;
+    }
+
     if (!m_swConnection)
         m_swConnection = &ServiceWorkerProvider::singleton().serviceWorkerConnectionForSession(context->sessionID());
 
index dc38ca5..7f6c546 100644 (file)
@@ -28,7 +28,7 @@
 
 [
     SecureContext,
-    Exposed=(Window),
+    Exposed=(Window,ServiceWorker),
     Conditional=SERVICE_WORKER,
     EnabledAtRuntime=ServiceWorker,
     GenerateIsReachable=Impl,
index e452238..d292591 100644 (file)
@@ -121,6 +121,12 @@ void ServiceWorkerRegistration::update(Ref<DeferredPromise>&& promise)
         return;
     }
 
+    // FIXME: Add support in workers.
+    if (!is<Document>(*context)) {
+        promise->reject(Exception { NotSupportedError, ASCIILiteral("serviceWorkerRegistration.update() is not yet supported in workers") });
+        return;
+    }
+
     auto* container = context->serviceWorkerContainer();
     if (!container) {
         promise->reject(Exception(InvalidStateError));
@@ -146,6 +152,12 @@ void ServiceWorkerRegistration::unregister(Ref<DeferredPromise>&& promise)
         return;
     }
 
+    // FIXME: Add support in workers.
+    if (!is<Document>(*context)) {
+        promise->reject(Exception { NotSupportedError, ASCIILiteral("serviceWorkerRegistration.unregister() is not yet supported in workers") });
+        return;
+    }
+
     auto* container = context->serviceWorkerContainer();
     if (!container) {
         promise->reject(Exception(InvalidStateError));
index 9eaa241..a9beab6 100644 (file)
@@ -29,7 +29,7 @@
 [
     ActiveDOMObject,
     SecureContext,
-    Exposed=(Window),
+    Exposed=(Window,ServiceWorker),
     Conditional=SERVICE_WORKER,
     EnabledAtRuntime=ServiceWorker
 ] interface ServiceWorkerRegistration : EventTarget {