Diff
Modified: trunk/LayoutTests/ChangeLog (225010 => 225011)
--- trunk/LayoutTests/ChangeLog 2017-11-18 03:02:20 UTC (rev 225010)
+++ trunk/LayoutTests/ChangeLog 2017-11-18 03:42:17 UTC (rev 225011)
@@ -1,3 +1,15 @@
+2017-11-17 Chris Dumez <[email protected]>
+
+ [Service Workers] Implement "Notify Controller Change" algorithm
+ https://bugs.webkit.org/show_bug.cgi?id=179822
+
+ Reviewed by Youenn Fablet.
+
+ Add layout test coverage.
+
+ * http/tests/workers/service/controller-change-expected.txt: Added.
+ * http/tests/workers/service/controller-change.html: Added.
+
2017-11-17 Joseph Pecoraro <[email protected]>
Web Inspector: Fix grammar typo in tests
Added: trunk/LayoutTests/http/tests/workers/service/controller-change-expected.txt (0 => 225011)
--- trunk/LayoutTests/http/tests/workers/service/controller-change-expected.txt (rev 0)
+++ trunk/LayoutTests/http/tests/workers/service/controller-change-expected.txt 2017-11-18 03:42:17 UTC (rev 225011)
@@ -0,0 +1,5 @@
+
+PASS: frame has a controller
+PASS: controllerchange event has been fired
+PASS: controller has been updated
+
Added: trunk/LayoutTests/http/tests/workers/service/controller-change.html (0 => 225011)
--- trunk/LayoutTests/http/tests/workers/service/controller-change.html (rev 0)
+++ trunk/LayoutTests/http/tests/workers/service/controller-change.html 2017-11-18 03:42:17 UTC (rev 225011)
@@ -0,0 +1,44 @@
+<html>
+<head>
+<script src=""
+</head>
+<body>
+<script>
+let initialController = null;
+
+function listenForControllerChange(frame)
+{
+ frame.contentWindow.navigator.serviceWorker.addEventListener("controllerchange", function() {
+ log("PASS: controllerchange event has been fired");
+
+ let newController = frame.contentWindow.navigator.serviceWorker.controller;
+ if (newController != null && newController != initialController)
+ log("PASS: controller has been updated");
+ else
+ log("FAIL: controller has not been updated");
+
+ finishSWTest();
+ });
+}
+
+async function test() {
+ let scopeURL = "/";
+ let registration = await registerAndWaitForActive("resources/service-worker-fetch-worker.js", scopeURL);
+ let frame = await withFrame(scopeURL);
+ initialController = frame.contentWindow.navigator.serviceWorker.controller;
+ if (initialController === null) {
+ log("FAIL: frame does not have a controller");
+ finishSWTest();
+ return;
+ }
+
+ log("PASS: frame has a controller");
+
+ listenForControllerChange(frame);
+ registration.update();
+}
+
+test();
+</script>
+</body>
+</html>
Modified: trunk/LayoutTests/http/tests/workers/service/resources/sw-test-pre.js (225010 => 225011)
--- trunk/LayoutTests/http/tests/workers/service/resources/sw-test-pre.js 2017-11-18 03:02:20 UTC (rev 225010)
+++ trunk/LayoutTests/http/tests/workers/service/resources/sw-test-pre.js 2017-11-18 03:42:17 UTC (rev 225011)
@@ -39,23 +39,10 @@
testRunner.notifyDone();
}
-async function interceptedFrame(workerURL, scopeURL)
+function withFrame(scopeURL)
{
- var registration = await navigator.serviceWorker.register(workerURL, { scope : scopeURL });
- await new Promise(resolve => {
- if (registration.active)
- resolve();
- worker = registration.installing;
- if (worker.state === "activated")
- resolve();
- worker.addEventListener("statechange", () => {
- if (worker.state === "activated")
- resolve();
- });
- });
-
- return await new Promise((resolve) => {
- var frame = document.createElement('iframe');
+ return new Promise((resolve) => {
+ let frame = document.createElement('iframe');
frame.src = ""
frame._onload_ = function() { resolve(frame); };
document.body.appendChild(frame);
@@ -62,6 +49,27 @@
});
}
+function registerAndWaitForActive(workerURL, scopeURL)
+{
+ return navigator.serviceWorker.register(workerURL, { scope : scopeURL }).then(function(registration) {
+ return new Promise(resolve => {
+ if (registration.active)
+ resolve(registration);
+ worker = registration.installing;
+ worker.addEventListener("statechange", () => {
+ if (worker.state === "activated")
+ resolve(registration);
+ });
+ });
+ });
+}
+
+async function interceptedFrame(workerURL, scopeURL)
+{
+ await registerAndWaitForActive(workerURL, scopeURL);
+ return await withFrame(scopeURL);
+}
+
function gc() {
if (typeof GCController !== "undefined")
GCController.collect();
Modified: trunk/Source/WebCore/ChangeLog (225010 => 225011)
--- trunk/Source/WebCore/ChangeLog 2017-11-18 03:02:20 UTC (rev 225010)
+++ trunk/Source/WebCore/ChangeLog 2017-11-18 03:42:17 UTC (rev 225011)
@@ -1,5 +1,33 @@
2017-11-17 Chris Dumez <[email protected]>
+ [Service Workers] Implement "Notify Controller Change" algorithm
+ https://bugs.webkit.org/show_bug.cgi?id=179822
+
+ Reviewed by Youenn Fablet.
+
+ Implement "Notify Controller Change" algorithm:
+ - https://w3c.github.io/ServiceWorker/#notify-controller-change
+
+ Use it to support step 7 of "Activate" algorithm:
+ - https://w3c.github.io/ServiceWorker/#activate
+
+ Test: http/tests/workers/service/controller-change.html
+
+ * workers/service/ServiceWorkerContainer.cpp:
+ (WebCore::ServiceWorkerContainer::scheduleTaskToFireControllerChangeEvent):
+ * workers/service/ServiceWorkerContainer.h:
+ * workers/service/server/SWClientConnection.cpp:
+ (WebCore::SWClientConnection::notifyClientsOfControllerChange):
+ * workers/service/server/SWClientConnection.h:
+ * workers/service/server/SWServer.h:
+ * workers/service/server/SWServerJobQueue.cpp:
+ (WebCore::SWServerJobQueue::activate):
+ * workers/service/server/SWServerRegistration.cpp:
+ (WebCore::SWServerRegistration::notifyClientsOfControllerChange):
+ * workers/service/server/SWServerRegistration.h:
+
+2017-11-17 Chris Dumez <[email protected]>
+
Unreviewed attempt to fix build after r225006.
* platform/network/cf/NetworkStorageSessionCFNet.cpp:
Modified: trunk/Source/WebCore/workers/service/ServiceWorkerContainer.cpp (225010 => 225011)
--- trunk/Source/WebCore/workers/service/ServiceWorkerContainer.cpp 2017-11-18 03:02:20 UTC (rev 225010)
+++ trunk/Source/WebCore/workers/service/ServiceWorkerContainer.cpp 2017-11-18 03:42:17 UTC (rev 225011)
@@ -411,6 +411,19 @@
m_registrations.remove(registration.identifier());
}
+void ServiceWorkerContainer::scheduleTaskToFireControllerChangeEvent()
+{
+ if (m_isStopped)
+ return;
+
+ scriptExecutionContext()->postTask([this, protectedThis = makeRef(*this)](ScriptExecutionContext&) mutable {
+ if (m_isStopped)
+ return;
+
+ dispatchEvent(Event::create(eventNames().controllerchangeEvent, false, false));
+ });
+}
+
} // namespace WebCore
#endif // ENABLE(SERVICE_WORKER)
Modified: trunk/Source/WebCore/workers/service/ServiceWorkerContainer.h (225010 => 225011)
--- trunk/Source/WebCore/workers/service/ServiceWorkerContainer.h 2017-11-18 03:02:20 UTC (rev 225010)
+++ trunk/Source/WebCore/workers/service/ServiceWorkerContainer.h 2017-11-18 03:42:17 UTC (rev 225011)
@@ -67,6 +67,7 @@
void getRegistration(const String& clientURL, Ref<DeferredPromise>&&);
void scheduleTaskToUpdateRegistrationState(ServiceWorkerRegistrationIdentifier, ServiceWorkerRegistrationState, const std::optional<ServiceWorkerData>&);
void scheduleTaskToFireUpdateFoundEvent(ServiceWorkerRegistrationIdentifier);
+ void scheduleTaskToFireControllerChangeEvent();
using RegistrationsPromise = DOMPromiseDeferred<IDLSequence<IDLInterface<ServiceWorkerRegistration>>>;
void getRegistrations(RegistrationsPromise&&);
Modified: trunk/Source/WebCore/workers/service/server/SWClientConnection.cpp (225010 => 225011)
--- trunk/Source/WebCore/workers/service/server/SWClientConnection.cpp 2017-11-18 03:02:20 UTC (rev 225010)
+++ trunk/Source/WebCore/workers/service/server/SWClientConnection.cpp 2017-11-18 03:42:17 UTC (rev 225011)
@@ -165,6 +165,24 @@
});
}
+void SWClientConnection::notifyClientsOfControllerChange(const HashSet<uint64_t>& scriptExecutionContexts, ServiceWorkerData&& newController)
+{
+ ASSERT(!scriptExecutionContexts.isEmpty());
+
+ for (auto& clientIdentifier : scriptExecutionContexts) {
+ // FIXME: Support worker contexts.
+ auto* client = Document::allDocumentsMap().get(clientIdentifier);
+ if (!client)
+ continue;
+
+ ASSERT(client->activeServiceWorker());
+ ASSERT(client->activeServiceWorker()->identifier() != newController.identifier);
+ client->setActiveServiceWorker(ServiceWorker::getOrCreate(*client, ServiceWorkerData { newController }));
+ if (auto* container = client->serviceWorkerContainer())
+ container->scheduleTaskToFireControllerChangeEvent();
+ }
+}
+
} // namespace WebCore
#endif // ENABLE(SERVICE_WORKER)
Modified: trunk/Source/WebCore/workers/service/server/SWClientConnection.h (225010 => 225011)
--- trunk/Source/WebCore/workers/service/server/SWClientConnection.h 2017-11-18 03:02:20 UTC (rev 225010)
+++ trunk/Source/WebCore/workers/service/server/SWClientConnection.h 2017-11-18 03:42:17 UTC (rev 225011)
@@ -86,6 +86,7 @@
WEBCORE_EXPORT void updateRegistrationState(ServiceWorkerRegistrationIdentifier, ServiceWorkerRegistrationState, const std::optional<ServiceWorkerData>&);
WEBCORE_EXPORT void updateWorkerState(ServiceWorkerIdentifier, ServiceWorkerState);
WEBCORE_EXPORT void fireUpdateFoundEvent(ServiceWorkerRegistrationIdentifier);
+ WEBCORE_EXPORT void notifyClientsOfControllerChange(const HashSet<uint64_t>& scriptExecutionContexts, ServiceWorkerData&& newController);
private:
virtual void scheduleJobInServer(const ServiceWorkerJobData&) = 0;
Modified: trunk/Source/WebCore/workers/service/server/SWServer.h (225010 => 225011)
--- trunk/Source/WebCore/workers/service/server/SWServer.h 2017-11-18 03:02:20 UTC (rev 225010)
+++ trunk/Source/WebCore/workers/service/server/SWServer.h 2017-11-18 03:42:17 UTC (rev 225011)
@@ -73,6 +73,7 @@
virtual void updateRegistrationStateInClient(ServiceWorkerRegistrationIdentifier, ServiceWorkerRegistrationState, const std::optional<ServiceWorkerData>&) = 0;
virtual void updateWorkerStateInClient(ServiceWorkerIdentifier, ServiceWorkerState) = 0;
virtual void fireUpdateFoundEvent(ServiceWorkerRegistrationIdentifier) = 0;
+ virtual void notifyClientsOfControllerChange(const HashSet<uint64_t>& scriptExecutionContexts, const ServiceWorkerData& newController) = 0;
protected:
WEBCORE_EXPORT explicit Connection(SWServer&);
Modified: trunk/Source/WebCore/workers/service/server/SWServerJobQueue.cpp (225010 => 225011)
--- trunk/Source/WebCore/workers/service/server/SWServerJobQueue.cpp 2017-11-18 03:02:20 UTC (rev 225010)
+++ trunk/Source/WebCore/workers/service/server/SWServerJobQueue.cpp 2017-11-18 03:42:17 UTC (rev 225011)
@@ -230,7 +230,12 @@
// Run the Update Worker State algorithm passing registration's active worker and activating as the arguments.
registration.updateWorkerState(*registration.activeWorker(), ServiceWorkerState::Activating);
// FIXME: For each service worker client client whose creation URL matches registration's scope url...
- // FIXME: For each service worker client client who is using registration...
+
+ // For each service worker client client who is using registration:
+ // - Set client's active worker to registration's active worker.
+ // - Invoke Notify Controller Change algorithm with client as the argument.
+ registration.notifyClientsOfControllerChange();
+
// FIXME: Invoke Run Service Worker algorithm with activeWorker as the argument.
// Queue a task to fire the activate event.
Modified: trunk/Source/WebCore/workers/service/server/SWServerRegistration.cpp (225010 => 225011)
--- trunk/Source/WebCore/workers/service/server/SWServerRegistration.cpp 2017-11-18 03:02:20 UTC (rev 225010)
+++ trunk/Source/WebCore/workers/service/server/SWServerRegistration.cpp 2017-11-18 03:42:17 UTC (rev 225011)
@@ -163,6 +163,17 @@
m_clientsUsingRegistration.remove(iterator);
}
+// https://w3c.github.io/ServiceWorker/#notify-controller-change
+void SWServerRegistration::notifyClientsOfControllerChange()
+{
+ ASSERT(activeWorker());
+
+ for (auto& item : m_clientsUsingRegistration) {
+ if (auto* connection = m_server.getConnection(item.key))
+ connection->notifyClientsOfControllerChange(item.value, activeWorker()->data());
+ }
+}
+
void SWServerRegistration::unregisterServerConnection(SWServerConnectionIdentifier serverConnectionIdentifier)
{
m_connectionsWithClientRegistrations.removeAll(serverConnectionIdentifier);
Modified: trunk/Source/WebCore/workers/service/server/SWServerRegistration.h (225010 => 225011)
--- trunk/Source/WebCore/workers/service/server/SWServerRegistration.h 2017-11-18 03:02:20 UTC (rev 225010)
+++ trunk/Source/WebCore/workers/service/server/SWServerRegistration.h 2017-11-18 03:42:17 UTC (rev 225011)
@@ -78,6 +78,8 @@
void removeClientUsingRegistration(const ServiceWorkerClientIdentifier&);
void unregisterServerConnection(SWServerConnectionIdentifier);
+ void notifyClientsOfControllerChange();
+
private:
void forEachConnection(const WTF::Function<void(SWServer::Connection&)>&);
Modified: trunk/Source/WebKit/ChangeLog (225010 => 225011)
--- trunk/Source/WebKit/ChangeLog 2017-11-18 03:02:20 UTC (rev 225010)
+++ trunk/Source/WebKit/ChangeLog 2017-11-18 03:42:17 UTC (rev 225011)
@@ -1,5 +1,19 @@
2017-11-17 Chris Dumez <[email protected]>
+ [Service Workers] Implement "Notify Controller Change" algorithm
+ https://bugs.webkit.org/show_bug.cgi?id=179822
+
+ Reviewed by Youenn Fablet.
+
+ * Scripts/webkit/messages.py:
+ (class_template_headers):
+ * StorageProcess/ServiceWorker/WebSWServerConnection.cpp:
+ (WebKit::WebSWServerConnection::notifyClientsOfControllerChange):
+ * StorageProcess/ServiceWorker/WebSWServerConnection.h:
+ * WebProcess/Storage/WebSWClientConnection.messages.in:
+
+2017-11-17 Chris Dumez <[email protected]>
+
Use a strongly typed identifier for SWServer::Connection
https://bugs.webkit.org/show_bug.cgi?id=179848
Modified: trunk/Source/WebKit/Scripts/webkit/messages.py (225010 => 225011)
--- trunk/Source/WebKit/Scripts/webkit/messages.py 2017-11-18 03:02:20 UTC (rev 225010)
+++ trunk/Source/WebKit/Scripts/webkit/messages.py 2017-11-18 03:42:17 UTC (rev 225011)
@@ -300,6 +300,7 @@
class_template_types = {
'WebCore::RectEdges': {'headers': ['<WebCore/RectEdges.h>'], 'argument_coder_headers': ['"ArgumentCoders.h"']},
'HashMap': {'headers': ['<wtf/HashMap.h>'], 'argument_coder_headers': ['"ArgumentCoders.h"']},
+ 'HashSet': {'headers': ['<wtf/HashSet.h>'], 'argument_coder_headers': ['"ArgumentCoders.h"']},
'std::optional': {'headers': ['<wtf/Optional.h>'], 'argument_coder_headers': ['"ArgumentCoders.h"']},
'OptionSet': {'headers': ['<wtf/OptionSet.h>'], 'argument_coder_headers': ['"ArgumentCoders.h"']},
'Vector': {'headers': ['<wtf/Vector.h>'], 'argument_coder_headers': ['"ArgumentCoders.h"']},
Modified: trunk/Source/WebKit/StorageProcess/ServiceWorker/WebSWServerConnection.cpp (225010 => 225011)
--- trunk/Source/WebKit/StorageProcess/ServiceWorker/WebSWServerConnection.cpp 2017-11-18 03:02:20 UTC (rev 225010)
+++ trunk/Source/WebKit/StorageProcess/ServiceWorker/WebSWServerConnection.cpp 2017-11-18 03:42:17 UTC (rev 225011)
@@ -102,6 +102,11 @@
send(Messages::WebSWClientConnection::FireUpdateFoundEvent(identifier));
}
+void WebSWServerConnection::notifyClientsOfControllerChange(const HashSet<uint64_t>& scriptExecutionContexts, const ServiceWorkerData& newController)
+{
+ send(Messages::WebSWClientConnection::NotifyClientsOfControllerChange(scriptExecutionContexts, newController));
+}
+
void WebSWServerConnection::updateWorkerStateInClient(ServiceWorkerIdentifier worker, ServiceWorkerState state)
{
send(Messages::WebSWClientConnection::UpdateWorkerState(worker, state));
Modified: trunk/Source/WebKit/StorageProcess/ServiceWorker/WebSWServerConnection.h (225010 => 225011)
--- trunk/Source/WebKit/StorageProcess/ServiceWorker/WebSWServerConnection.h 2017-11-18 03:02:20 UTC (rev 225010)
+++ trunk/Source/WebKit/StorageProcess/ServiceWorker/WebSWServerConnection.h 2017-11-18 03:42:17 UTC (rev 225011)
@@ -73,6 +73,7 @@
void updateRegistrationStateInClient(WebCore::ServiceWorkerRegistrationIdentifier, WebCore::ServiceWorkerRegistrationState, const std::optional<WebCore::ServiceWorkerData>&) final;
void updateWorkerStateInClient(WebCore::ServiceWorkerIdentifier, WebCore::ServiceWorkerState) final;
void fireUpdateFoundEvent(WebCore::ServiceWorkerRegistrationIdentifier) final;
+ void notifyClientsOfControllerChange(const HashSet<uint64_t>& scriptExecutionContexts, const WebCore::ServiceWorkerData& newController);
void startFetch(uint64_t fetchIdentifier, std::optional<WebCore::ServiceWorkerIdentifier>, const WebCore::ResourceRequest&, const WebCore::FetchOptions&, const IPC::FormDataReference&);
Modified: trunk/Source/WebKit/WebProcess/Storage/WebSWClientConnection.messages.in (225010 => 225011)
--- trunk/Source/WebKit/WebProcess/Storage/WebSWClientConnection.messages.in 2017-11-18 03:02:20 UTC (rev 225010)
+++ trunk/Source/WebKit/WebProcess/Storage/WebSWClientConnection.messages.in 2017-11-18 03:42:17 UTC (rev 225011)
@@ -31,6 +31,7 @@
UpdateRegistrationState(WebCore::ServiceWorkerRegistrationIdentifier identifier, enum WebCore::ServiceWorkerRegistrationState state, std::optional<WebCore::ServiceWorkerData> serviceWorkerIdentifier)
UpdateWorkerState(WebCore::ServiceWorkerIdentifier serviceWorkerIdentifier, enum WebCore::ServiceWorkerState state)
FireUpdateFoundEvent(WebCore::ServiceWorkerRegistrationIdentifier identifier)
+ NotifyClientsOfControllerChange(HashSet<uint64_t> scriptExecutionContexts, struct WebCore::ServiceWorkerData newController)
InitializeSWOriginTableAsEmpty()
SetSWOriginTableSharedMemory(WebKit::SharedMemory::Handle handle)