Title: [292456] trunk
Revision
292456
Author
you...@apple.com
Date
2022-04-06 03:05:05 -0700 (Wed, 06 Apr 2022)

Log Message

ServiceWorkerClients.openWindow should not need to get all clients asynchronously to resolve its promise
https://bugs.webkit.org/show_bug.cgi?id=238503

Reviewed by Chris Dumez.

Source/WebCore:

Move matching client in openWindow in network process as an optimization.
This also prevents some race conditions where the opened page could quickly navigate to another page.
Also have a code path that rejects the openWindow promise, and trigger that code path in case of internal error.

Covered by existing and API test.

* workers/WorkerGlobalScope.h:
* workers/service/ServiceWorkerClients.cpp:
* workers/service/context/SWContextManager.h:
* workers/service/server/SWServer.cpp:
* workers/service/server/SWServer.h:
* workers/service/server/SWServerToContextConnection.h:

Source/WebKit:

Add logic to get the client from its page ID.
In case of internal error case, trigger promise rejection instead of promise resolution with null.

* NetworkProcess/ServiceWorker/WebSWServerToContextConnection.cpp:
* NetworkProcess/ServiceWorker/WebSWServerToContextConnection.h:
* NetworkProcess/ServiceWorker/WebSWServerToContextConnection.messages.in:
* WebProcess/Storage/WebSWContextManagerConnection.cpp:
* WebProcess/Storage/WebSWContextManagerConnection.h:

Tools:

* TestWebKitAPI/Tests/WebKitCocoa/ServiceWorkerBasic.mm:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (292455 => 292456)


--- trunk/Source/WebCore/ChangeLog	2022-04-06 09:16:42 UTC (rev 292455)
+++ trunk/Source/WebCore/ChangeLog	2022-04-06 10:05:05 UTC (rev 292456)
@@ -1,3 +1,23 @@
+2022-04-06  Youenn Fablet  <you...@apple.com>
+
+        ServiceWorkerClients.openWindow should not need to get all clients asynchronously to resolve its promise
+        https://bugs.webkit.org/show_bug.cgi?id=238503
+
+        Reviewed by Chris Dumez.
+
+        Move matching client in openWindow in network process as an optimization.
+        This also prevents some race conditions where the opened page could quickly navigate to another page.
+        Also have a code path that rejects the openWindow promise, and trigger that code path in case of internal error.
+
+        Covered by existing and API test.
+
+        * workers/WorkerGlobalScope.h:
+        * workers/service/ServiceWorkerClients.cpp:
+        * workers/service/context/SWContextManager.h:
+        * workers/service/server/SWServer.cpp:
+        * workers/service/server/SWServer.h:
+        * workers/service/server/SWServerToContextConnection.h:
+
 2022-04-06  Antti Koivisto  <an...@apple.com>
 
         Remove some @apply leftover code

Modified: trunk/Source/WebCore/workers/WorkerGlobalScope.h (292455 => 292456)


--- trunk/Source/WebCore/workers/WorkerGlobalScope.h	2022-04-06 09:16:42 UTC (rev 292455)
+++ trunk/Source/WebCore/workers/WorkerGlobalScope.h	2022-04-06 10:05:05 UTC (rev 292456)
@@ -28,6 +28,7 @@
 
 #include "Base64Utilities.h"
 #include "CacheStorageConnection.h"
+#include "ClientOrigin.h"
 #include "ImageBitmap.h"
 #include "ScriptExecutionContext.h"
 #include "Supplementable.h"
@@ -156,6 +157,8 @@
     void setMainScriptSourceProvider(ScriptBufferSourceProvider&);
     void addImportedScriptSourceProvider(const URL&, ScriptBufferSourceProvider&);
 
+    ClientOrigin clientOrigin() const { return { topOrigin().data(), securityOrigin()->data() }; }
+
 protected:
     WorkerGlobalScope(WorkerThreadType, const WorkerParameters&, Ref<SecurityOrigin>&&, WorkerThread&, Ref<SecurityOrigin>&& topOrigin, IDBClient::IDBConnectionProxy*, SocketProvider*);
 

Modified: trunk/Source/WebCore/workers/service/ServiceWorkerClients.cpp (292455 => 292456)


--- trunk/Source/WebCore/workers/service/ServiceWorkerClients.cpp	2022-04-06 09:16:42 UTC (rev 292455)
+++ trunk/Source/WebCore/workers/service/ServiceWorkerClients.cpp	2022-04-06 10:05:05 UTC (rev 292456)
@@ -90,38 +90,16 @@
     });
 }
 
-static void matchWindowWithPageIdentifier(ServiceWorkerIdentifier serviceWorkerIdentifier, PageIdentifier pageIdentifier, CompletionHandler<void(ServiceWorkerGlobalScope&, std::optional<ServiceWorkerClientData>)>&& callback)
-{
-    callOnMainThread([serviceWorkerIdentifier, pageIdentifier, callback = WTFMove(callback)] () mutable {
-        auto connection = SWContextManager::singleton().connection();
-        auto options = ServiceWorkerClientQueryOptions { true, ServiceWorkerClientType::Window };
-        connection->matchAll(serviceWorkerIdentifier, options, [serviceWorkerIdentifier, pageIdentifier, callback = WTFMove(callback)] (Vector<ServiceWorkerClientData>&& clientsData) mutable {
-            SWContextManager::singleton().postTaskToServiceWorker(serviceWorkerIdentifier, [pageIdentifier, callback = WTFMove(callback), clientsData = crossThreadCopy(WTFMove(clientsData))] (auto& scope) mutable {
-                for (auto& data : clientsData) {
-                    if (data.pageIdentifier == pageIdentifier) {
-                        callback(scope, data);
-                        return;
-                    }
-                }
-
-                callback(scope, std::nullopt);
-            });
-        });
-    });
-}
-
 void ServiceWorkerClients::openWindow(ScriptExecutionContext& context, const String& urlString, Ref<DeferredPromise>&& promise)
 {
     LOG(ServiceWorker, "WebProcess %i service worker calling openWindow to URL %s", getpid(), urlString.utf8().data());
 
-    auto serviceWorkerIdentifier = downcast<ServiceWorkerGlobalScope>(context).thread().identifier();
-    auto url = ""
-
     if (context.settingsValues().serviceWorkersUserGestureEnabled && !downcast<ServiceWorkerGlobalScope>(context).isProcessingUserGesture()) {
         promise->reject(Exception { InvalidAccessError, "ServiceWorkerClients.openWindow() requires a user gesture"_s });
         return;
     }
 
+    auto url = ""
     if (!url.isValid()) {
         promise->reject(Exception { TypeError, makeString("URL string ", urlString, " cannot successfully be parsed"_s) });
         return;
@@ -132,31 +110,34 @@
         return;
     }
 
+    auto serviceWorkerIdentifier = downcast<ServiceWorkerGlobalScope>(context).thread().identifier();
     callOnMainThread([promiseIdentifier = addPendingPromise(WTFMove(promise)), serviceWorkerIdentifier, url = "" () mutable {
         auto connection = SWContextManager::singleton().connection();
-        connection->openWindow(serviceWorkerIdentifier, url.string(), [promiseIdentifier, serviceWorkerIdentifier] (std::optional<PageIdentifier>&& pageIdentifier) mutable {
-            SWContextManager::singleton().postTaskToServiceWorker(serviceWorkerIdentifier, [promiseIdentifier, pageIdentifier = WTFMove(pageIdentifier), serviceWorkerIdentifier] (ServiceWorkerGlobalScope& scope) mutable {
-                LOG(ServiceWorker, "WebProcess %i finished ServiceWorkerClients::openWindow call. Resulting page identifier is %s", getpid(), pageIdentifier ? pageIdentifier->loggingString().utf8().data() : "<NONE>");
+        connection->openWindow(serviceWorkerIdentifier, url, [promiseIdentifier, serviceWorkerIdentifier] (auto&& result) mutable {
+            SWContextManager::singleton().postTaskToServiceWorker(serviceWorkerIdentifier, [promiseIdentifier, result = crossThreadCopy(WTFMove(result))] (ServiceWorkerGlobalScope& scope) mutable {
+                LOG(ServiceWorker, "WebProcess %i finished ServiceWorkerClients::openWindow call result is %d.", getpid(), !result.hasException());
 
-                if (!pageIdentifier) {
-                    if (auto promise = scope.clients().takePendingPromise(promiseIdentifier))
-                        promise->resolveWithJSValue(JSC::jsNull());
+                auto promise = scope.clients().takePendingPromise(promiseIdentifier);
+                if (!promise)
                     return;
+
+                if (result.hasException()) {
+                    promise->reject(result.releaseException());
+                    return;
                 }
 
-                matchWindowWithPageIdentifier(serviceWorkerIdentifier, *pageIdentifier, [promiseIdentifier] (auto& scope, std::optional<ServiceWorkerClientData> clientData) mutable {
-                    auto promise = scope.clients().takePendingPromise(promiseIdentifier);
-                    if (!promise)
-                        return;
+                auto clientData = result.releaseReturnValue();
+                if (!clientData) {
+                    promise->resolveWithJSValue(JSC::jsNull());
+                    return;
+                }
 
-                    if (!clientData) {
-                        promise->resolveWithJSValue(JSC::jsNull());
-                        return;
-                    }
-
-                    auto client = ServiceWorkerClient::create(scope, WTFMove(*clientData));
-                    promise->template resolve<IDLInterface<ServiceWorkerClient>>(WTFMove(client));
-                });
+#if ASSERT_ENABLED
+                auto originData = SecurityOriginData::fromURL(clientData->url);
+                ClientOrigin clientOrigin { originData, originData };
+#endif
+                ASSERT(scope.clientOrigin() == clientOrigin);
+                promise->template resolve<IDLInterface<ServiceWorkerClient>>(ServiceWorkerClient::create(scope, WTFMove(*clientData)));
             });
         });
     });

Modified: trunk/Source/WebCore/workers/service/context/SWContextManager.h (292455 => 292456)


--- trunk/Source/WebCore/workers/service/context/SWContextManager.h	2022-04-06 09:16:42 UTC (rev 292455)
+++ trunk/Source/WebCore/workers/service/context/SWContextManager.h	2022-04-06 10:05:05 UTC (rev 292456)
@@ -67,9 +67,11 @@
         virtual void findClientByVisibleIdentifier(ServiceWorkerIdentifier, const String&, FindClientByIdentifierCallback&&) = 0;
         virtual void matchAll(ServiceWorkerIdentifier, const ServiceWorkerClientQueryOptions&, ServiceWorkerClientsMatchAllCallback&&) = 0;
         virtual void claim(ServiceWorkerIdentifier, CompletionHandler<void(ExceptionOr<void>&&)>&&) = 0;
-        virtual void focus(ScriptExecutionContextIdentifier, CompletionHandler<void(std::optional<WebCore::ServiceWorkerClientData>&&)>&&) = 0;
-        virtual void openWindow(ServiceWorkerIdentifier, const String& url, CompletionHandler<void(std::optional<PageIdentifier>&&)>&&) = 0;
+        virtual void focus(ScriptExecutionContextIdentifier, CompletionHandler<void(std::optional<ServiceWorkerClientData>&&)>&&) = 0;
 
+        using OpenWindowCallback = CompletionHandler<void(ExceptionOr<std::optional<ServiceWorkerClientData>>&&)>;
+        virtual void openWindow(ServiceWorkerIdentifier, const URL&, OpenWindowCallback&&) = 0;
+
         virtual void didFailHeartBeatCheck(ServiceWorkerIdentifier) = 0;
         virtual void setAsInspected(ServiceWorkerIdentifier, bool) = 0;
 

Modified: trunk/Source/WebCore/workers/service/server/SWServer.cpp (292455 => 292456)


--- trunk/Source/WebCore/workers/service/server/SWServer.cpp	2022-04-06 09:16:42 UTC (rev 292455)
+++ trunk/Source/WebCore/workers/service/server/SWServer.cpp	2022-04-06 10:05:05 UTC (rev 292456)
@@ -112,6 +112,20 @@
     return clientIterator->value;
 }
 
+std::optional<ServiceWorkerClientData> SWServer::topLevelServiceWorkerClientFromPageIdentifier(const ClientOrigin& clientOrigin, PageIdentifier pageIdentifier) const
+{
+    auto iterator = m_clientIdentifiersPerOrigin.find(clientOrigin);
+    if (iterator == m_clientIdentifiersPerOrigin.end())
+        return { };
+
+    for (auto clientIdentifier : iterator->value.identifiers) {
+        auto clientIterator = m_clientsById.find(clientIdentifier);
+        if (clientIterator->value->frameType == ServiceWorkerClientFrameType::TopLevel && clientIterator->value->pageIdentifier == pageIdentifier)
+            return clientIterator->value;
+    }
+    return { };
+}
+
 String SWServer::serviceWorkerClientUserAgent(const ClientOrigin& clientOrigin) const
 {
     auto iterator = m_clientIdentifiersPerOrigin.find(clientOrigin);

Modified: trunk/Source/WebCore/workers/service/server/SWServer.h (292455 => 292456)


--- trunk/Source/WebCore/workers/service/server/SWServer.h	2022-04-06 09:16:42 UTC (rev 292455)
+++ trunk/Source/WebCore/workers/service/server/SWServer.h	2022-04-06 10:05:05 UTC (rev 292456)
@@ -29,6 +29,7 @@
 
 #include "ClientOrigin.h"
 #include "ExceptionOr.h"
+#include "PageIdentifier.h"
 #include "SWServerWorker.h"
 #include "ScriptExecutionContextIdentifier.h"
 #include "SecurityOriginData.h"
@@ -161,6 +162,7 @@
 
     WEBCORE_EXPORT SWServerWorker* workerByID(ServiceWorkerIdentifier) const;
     WEBCORE_EXPORT std::optional<ServiceWorkerClientData> serviceWorkerClientWithOriginByID(const ClientOrigin&, const ScriptExecutionContextIdentifier&) const;
+    WEBCORE_EXPORT std::optional<ServiceWorkerClientData> topLevelServiceWorkerClientFromPageIdentifier(const ClientOrigin&, PageIdentifier) const;
     String serviceWorkerClientUserAgent(const ClientOrigin&) const;
     WEBCORE_EXPORT SWServerWorker* activeWorkerFromRegistrationID(ServiceWorkerRegistrationIdentifier);
 

Modified: trunk/Source/WebCore/workers/service/server/SWServerToContextConnection.h (292455 => 292456)


--- trunk/Source/WebCore/workers/service/server/SWServerToContextConnection.h	2022-04-06 09:16:42 UTC (rev 292455)
+++ trunk/Source/WebCore/workers/service/server/SWServerToContextConnection.h	2022-04-06 10:05:05 UTC (rev 292456)
@@ -86,7 +86,8 @@
     WEBCORE_EXPORT void setAsInspected(ServiceWorkerIdentifier, bool);
     WEBCORE_EXPORT void findClientByVisibleIdentifier(ServiceWorkerIdentifier, const String& clientIdentifier, CompletionHandler<void(std::optional<WebCore::ServiceWorkerClientData>&&)>&&);
 
-    virtual void openWindow(ServiceWorkerIdentifier, const String& urlString, CompletionHandler<void(std::optional<WebCore::PageIdentifier>&&)>&&) = 0;
+    using OpenWindowCallback = CompletionHandler<void(Expected<std::optional<ServiceWorkerClientData>, ExceptionData>&&)>;
+    virtual void openWindow(ServiceWorkerIdentifier, const URL&, OpenWindowCallback&&) = 0;
 
     const RegistrableDomain& registrableDomain() const { return m_registrableDomain; }
     std::optional<ScriptExecutionContextIdentifier> serviceWorkerPageIdentifier() const { return m_serviceWorkerPageIdentifier; }

Modified: trunk/Source/WebKit/ChangeLog (292455 => 292456)


--- trunk/Source/WebKit/ChangeLog	2022-04-06 09:16:42 UTC (rev 292455)
+++ trunk/Source/WebKit/ChangeLog	2022-04-06 10:05:05 UTC (rev 292456)
@@ -1,5 +1,21 @@
 2022-04-06  Youenn Fablet  <you...@apple.com>
 
+        ServiceWorkerClients.openWindow should not need to get all clients asynchronously to resolve its promise
+        https://bugs.webkit.org/show_bug.cgi?id=238503
+
+        Reviewed by Chris Dumez.
+
+        Add logic to get the client from its page ID.
+        In case of internal error case, trigger promise rejection instead of promise resolution with null.
+
+        * NetworkProcess/ServiceWorker/WebSWServerToContextConnection.cpp:
+        * NetworkProcess/ServiceWorker/WebSWServerToContextConnection.h:
+        * NetworkProcess/ServiceWorker/WebSWServerToContextConnection.messages.in:
+        * WebProcess/Storage/WebSWContextManagerConnection.cpp:
+        * WebProcess/Storage/WebSWContextManagerConnection.h:
+
+2022-04-06  Youenn Fablet  <you...@apple.com>
+
         Remove Notification::m_relatedNotificationIdentifier
         https://bugs.webkit.org/show_bug.cgi?id=238603
 

Modified: trunk/Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerToContextConnection.cpp (292455 => 292456)


--- trunk/Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerToContextConnection.cpp	2022-04-06 09:16:42 UTC (rev 292455)
+++ trunk/Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerToContextConnection.cpp	2022-04-06 10:05:05 UTC (rev 292456)
@@ -170,25 +170,36 @@
     m_connection.networkProcess().parentProcessConnection()->send(Messages::NetworkProcessProxy::TerminateUnresponsiveServiceWorkerProcesses { webProcessIdentifier() }, 0);
 }
 
-void WebSWServerToContextConnection::openWindow(WebCore::ServiceWorkerIdentifier identifier, const String& urlString, CompletionHandler<void(std::optional<WebCore::PageIdentifier>&&)>&& callback)
+void WebSWServerToContextConnection::openWindow(WebCore::ServiceWorkerIdentifier identifier, const URL& url, OpenWindowCallback&& callback)
 {
     auto* server = this->server();
     if (!server) {
-        callback(std::nullopt);
+        callback(makeUnexpected(ExceptionData { TypeError, "No SWServer"_s }));
         return;
     }
 
     auto* worker = server->workerByID(identifier);
     if (!worker) {
-        callback(std::nullopt);
+        callback(makeUnexpected(ExceptionData { TypeError, "No remaining service worker"_s }));
         return;
     }
 
-    auto innerCallback = [callback = WTFMove(callback)](std::optional<WebCore::PageIdentifier>&& pageIdentifier) mutable {
-        callback(WTFMove(pageIdentifier));
+    auto innerCallback = [callback = WTFMove(callback), server = WeakPtr { *server }, origin = worker->origin()](std::optional<WebCore::PageIdentifier>&& pageIdentifier) mutable {
+        if (!pageIdentifier) {
+            // FIXME: validate whether we should reject or resolve with null, https://github.com/w3c/ServiceWorker/issues/1639
+            callback({ });
+            return;
+        }
+
+        if (!server) {
+            callback(makeUnexpected(ExceptionData { TypeError, "No SWServer"_s }));
+            return;
+        }
+
+        callback(server->topLevelServiceWorkerClientFromPageIdentifier(origin, *pageIdentifier));
     };
 
-    m_connection.networkProcess().parentProcessConnection()->sendWithAsyncReply(Messages::NetworkProcessProxy::OpenWindowFromServiceWorker { server->sessionID(), urlString, worker->origin().clientOrigin }, WTFMove(innerCallback));
+    m_connection.networkProcess().parentProcessConnection()->sendWithAsyncReply(Messages::NetworkProcessProxy::OpenWindowFromServiceWorker { m_connection.sessionID(), url.string(), worker->origin().clientOrigin }, WTFMove(innerCallback));
 }
 
 void WebSWServerToContextConnection::matchAllCompleted(uint64_t requestIdentifier, const Vector<ServiceWorkerClientData>& clientsData)

Modified: trunk/Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerToContextConnection.h (292455 => 292456)


--- trunk/Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerToContextConnection.h	2022-04-06 09:16:42 UTC (rev 292455)
+++ trunk/Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerToContextConnection.h	2022-04-06 10:05:05 UTC (rev 292456)
@@ -103,7 +103,7 @@
 
     void connectionIsNoLongerNeeded() final;
     void terminateDueToUnresponsiveness() final;
-    void openWindow(WebCore::ServiceWorkerIdentifier, const String& urlString, CompletionHandler<void(std::optional<WebCore::PageIdentifier>&&)>&&) final;
+    void openWindow(WebCore::ServiceWorkerIdentifier, const URL&, OpenWindowCallback&&) final;
 
     void connectionClosed();
 

Modified: trunk/Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerToContextConnection.messages.in (292455 => 292456)


--- trunk/Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerToContextConnection.messages.in	2022-04-06 09:16:42 UTC (rev 292455)
+++ trunk/Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerToContextConnection.messages.in	2022-04-06 10:05:05 UTC (rev 292456)
@@ -41,7 +41,7 @@
     DidFailHeartBeatCheck(WebCore::ServiceWorkerIdentifier identifier)
     SetAsInspected(WebCore::ServiceWorkerIdentifier identifier, bool isInspected)
 
-    OpenWindow(WebCore::ServiceWorkerIdentifier identifier, String urlString) -> (std::optional<WebCore::PageIdentifier> newClientData)
+    OpenWindow(WebCore::ServiceWorkerIdentifier identifier, URL url) -> (Expected<std::optional<WebCore::ServiceWorkerClientData>, WebCore::ExceptionData> newClientData)
 }
 
 #endif // ENABLE(SERVICE_WORKER)

Modified: trunk/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.cpp (292455 => 292456)


--- trunk/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.cpp	2022-04-06 09:16:42 UTC (rev 292455)
+++ trunk/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.cpp	2022-04-06 10:05:05 UTC (rev 292456)
@@ -337,9 +337,15 @@
         callback(WTFMove(clientsData));
 }
 
-void WebSWContextManagerConnection::openWindow(WebCore::ServiceWorkerIdentifier serviceWorkerIdentifier, const String& url, CompletionHandler<void(std::optional<WebCore::PageIdentifier>&&)>&& callback)
+void WebSWContextManagerConnection::openWindow(WebCore::ServiceWorkerIdentifier serviceWorkerIdentifier, const URL& url, OpenWindowCallback&& callback)
 {
-    m_connectionToNetworkProcess->sendWithAsyncReply(Messages::WebSWServerToContextConnection::OpenWindow { serviceWorkerIdentifier, url }, WTFMove(callback));
+    m_connectionToNetworkProcess->sendWithAsyncReply(Messages::WebSWServerToContextConnection::OpenWindow { serviceWorkerIdentifier, url }, [callback = WTFMove(callback)] (auto&& result) mutable {
+        if (!result.has_value()) {
+            callback(result.error().toException());
+            return;
+        }
+        callback(WTFMove(result.value()));
+    });
 }
 
 void WebSWContextManagerConnection::claim(ServiceWorkerIdentifier serviceWorkerIdentifier, CompletionHandler<void(ExceptionOr<void>&&)>&& callback)

Modified: trunk/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.h (292455 => 292456)


--- trunk/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.h	2022-04-06 09:16:42 UTC (rev 292455)
+++ trunk/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.h	2022-04-06 10:05:05 UTC (rev 292456)
@@ -87,7 +87,7 @@
     bool isThrottleable() const final;
     void didFailHeartBeatCheck(WebCore::ServiceWorkerIdentifier) final;
     void setAsInspected(WebCore::ServiceWorkerIdentifier, bool) final;
-    void openWindow(WebCore::ServiceWorkerIdentifier, const String& url, CompletionHandler<void(std::optional<WebCore::PageIdentifier>&&)>&&) final;
+    void openWindow(WebCore::ServiceWorkerIdentifier, const URL&, OpenWindowCallback&&) final;
 
     // IPC messages.
     void serviceWorkerStarted(std::optional<WebCore::ServiceWorkerJobDataIdentifier>, WebCore::ServiceWorkerIdentifier, bool doesHandleFetch) final;

Modified: trunk/Tools/ChangeLog (292455 => 292456)


--- trunk/Tools/ChangeLog	2022-04-06 09:16:42 UTC (rev 292455)
+++ trunk/Tools/ChangeLog	2022-04-06 10:05:05 UTC (rev 292456)
@@ -1,3 +1,12 @@
+2022-04-06  Youenn Fablet  <you...@apple.com>
+
+        ServiceWorkerClients.openWindow should not need to get all clients asynchronously to resolve its promise
+        https://bugs.webkit.org/show_bug.cgi?id=238503
+
+        Reviewed by Chris Dumez.
+
+        * TestWebKitAPI/Tests/WebKitCocoa/ServiceWorkerBasic.mm:
+
 2022-04-06  Lauro Moura  <lmo...@igalia.com>
 
         [Flatpak SDK][AT-SPI] Use xdg-dbus-proxy to expose the a11y bus

Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ServiceWorkerBasic.mm (292455 => 292456)


--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ServiceWorkerBasic.mm	2022-04-06 09:16:42 UTC (rev 292455)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ServiceWorkerBasic.mm	2022-04-06 10:05:05 UTC (rev 292456)
@@ -2966,3 +2966,84 @@
     [webView evaluateJavaScript:@"focusClient()" completionHandler: nil];
     TestWebKitAPI::Util::run(&done);
 }
+
+static constexpr auto ServiceWorkerWindowClientOpenWindowMain =
+"<div id='log'>test page</div>"
+"<script>"
+"let worker;"
+"async function test() {"
+"    log.innerHTML = 'test';"
+"    try {"
+"        const registration = await navigator.serviceWorker.register('/sw.js');"
+"        log.innerHTML = 'registered';"
+"        if (registration.active) {"
+"            worker = registration.active;"
+"            alert('already active');"
+"            return;"
+"        }"
+"        worker = registration.installing;"
+"        worker.addEventListener('statechange', () => {"
+"           log.innerHTML = 'worker.state=' + worker.state;"
+"            if (worker.state == 'activated')"
+"                alert('successfully registered');"
+"        });"
+"    } catch(e) {"
+"        alert('Exception: ' + e);"
+"    }"
+"}"
+"window._onload_ = test;"
+""
+"function openWindowClient() {"
+"    log.innerHTML = 'openWindowClient';"
+"    worker.postMessage('start');"
+"    navigator.serviceWorker._onmessage_ = (event) => {"
+"        window.webkit.messageHandlers.sw.postMessage(event.data);"
+"    }"
+"}"
+"</script>"_s;
+static constexpr auto ServiceWorkerWindowClientOpenWindowJS =
+"self.addEventListener('message', (event) => {"
+"   self.clients.openWindow('/sw.js').then((client) => {"
+"       event.source.postMessage(client ? 'opened with client' : 'opened without client');"
+"   }, (error) => {"
+"       event.source.postMessage('not opened');"
+"   });"
+"});"_s;
+
+TEST(ServiceWorker, openWindowWithoutDelegate)
+{
+    [WKWebsiteDataStore _allowWebsiteDataRecordsForAllOrigins];
+
+    // Start with a clean slate data store
+    [[WKWebsiteDataStore defaultDataStore] removeDataOfTypes:[WKWebsiteDataStore allWebsiteDataTypes] modifiedSince:[NSDate distantPast] completionHandler:^() {
+        done = true;
+    }];
+    TestWebKitAPI::Util::run(&done);
+    done = false;
+
+    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
+    auto preferences = [configuration preferences];
+
+    for (_WKInternalDebugFeature *feature in [WKPreferences _internalDebugFeatures]) {
+        if ([feature.key isEqualToString:@"ServiceWorkersUserGestureEnabled"])
+            [preferences _setEnabled:NO forInternalDebugFeature:feature];
+    }
+
+    auto messageHandler = adoptNS([[SWMessageHandlerWithExpectedMessage alloc] init]);
+    [[configuration userContentController] addScriptMessageHandler:messageHandler.get() name:@"sw"];
+
+    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 300, 300) configuration:configuration.get() addToWindow:YES]);
+
+    TestWebKitAPI::HTTPServer server({
+        { "/"_s, { ServiceWorkerWindowClientOpenWindowMain } },
+        { "/sw.js"_s, { {{ "Content-Type"_s, "application/_javascript_"_s }}, ServiceWorkerWindowClientOpenWindowJS } }
+    });
+
+    [webView loadRequest:server.request()];
+    EXPECT_WK_STREQ([webView _test_waitForAlert], "successfully registered");
+
+    done = false;
+    expectedMessage = "opened without client"_s;
+    [webView evaluateJavaScript:@"openWindowClient()" completionHandler: nil];
+    TestWebKitAPI::Util::run(&done);
+}
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to