Diff
Modified: trunk/LayoutTests/ChangeLog (225512 => 225513)
--- trunk/LayoutTests/ChangeLog 2017-12-05 01:37:20 UTC (rev 225512)
+++ trunk/LayoutTests/ChangeLog 2017-12-05 02:06:26 UTC (rev 225513)
@@ -1,3 +1,16 @@
+2017-12-04 Chris Dumez <cdu...@apple.com>
+
+ Support container.getRegistration() / getRegistrations() inside service workers
+ https://bugs.webkit.org/show_bug.cgi?id=180360
+
+ Reviewed by Youenn Fablet.
+
+ Add layout test coverage.
+
+ * http/tests/workers/service/ServiceWorkerGlobalScope_getRegistration-expected.txt: Added.
+ * http/tests/workers/service/ServiceWorkerGlobalScope_getRegistration.html: Added.
+ * http/tests/workers/service/resources/ServiceWorkerGlobalScope_getRegistration-worker.js: Added.
+
2017-12-04 Nan Wang <n_w...@apple.com>
AX: AOM: Implement relation type properties
Modified: trunk/LayoutTests/TestExpectations (225512 => 225513)
--- trunk/LayoutTests/TestExpectations 2017-12-05 01:37:20 UTC (rev 225512)
+++ trunk/LayoutTests/TestExpectations 2017-12-05 02:06:26 UTC (rev 225513)
@@ -161,7 +161,6 @@
webkit.org/b/179452 imported/w3c/web-platform-tests/service-workers/service-worker/register-same-scope-different-script-url.https.html [ Skip ]
imported/w3c/web-platform-tests/service-workers/service-worker/respond-with-body-accessed-response.https.html [ Skip ]
imported/w3c/web-platform-tests/service-workers/service-worker/sandboxed-iframe-fetch-event.https.html [ Skip ]
-imported/w3c/web-platform-tests/service-workers/service-worker/skip-waiting-using-registration.https.html [ Skip ]
imported/w3c/web-platform-tests/service-workers/service-worker/unregister-then-register-new-script.https.html [ Skip ]
imported/w3c/web-platform-tests/service-workers/service-worker/update-after-navigation-fetch-event.https.html [ Skip ]
imported/w3c/web-platform-tests/service-workers/service-worker/update-after-oneday.https.html [ Skip ]
Added: trunk/LayoutTests/http/tests/workers/service/ServiceWorkerGlobalScope_getRegistration-expected.txt (0 => 225513)
--- trunk/LayoutTests/http/tests/workers/service/ServiceWorkerGlobalScope_getRegistration-expected.txt (rev 0)
+++ trunk/LayoutTests/http/tests/workers/service/ServiceWorkerGlobalScope_getRegistration-expected.txt 2017-12-05 02:06:26 UTC (rev 225513)
@@ -0,0 +1,8 @@
+* Tests that serviceWorker.getRegistration() / getRegistrations() inside service workers
+
+PASS: Registration succeeded
+PASS: getRegistration() returned the right registration
+PASS: getRegistrations() returned 2 registrations
+PASS: getRegistrations()[0] is the right registration
+PASS: getRegistrations()[1] is the right registration
+
Added: trunk/LayoutTests/http/tests/workers/service/ServiceWorkerGlobalScope_getRegistration.html (0 => 225513)
--- trunk/LayoutTests/http/tests/workers/service/ServiceWorkerGlobalScope_getRegistration.html (rev 0)
+++ trunk/LayoutTests/http/tests/workers/service/ServiceWorkerGlobalScope_getRegistration.html 2017-12-05 02:06:26 UTC (rev 225513)
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html>
+<body>
+<script src=""
+<script>
+log("* Tests that serviceWorker.getRegistration() / getRegistrations() inside service workers");
+log("");
+
+navigator.serviceWorker.addEventListener("message", function(event) {
+ if (event.data ="" "DONE") {
+ finishSWTest();
+ return;
+ }
+ log(event.data);
+});
+
+navigator.serviceWorker.register("resources/ServiceWorkerGlobalScope_getRegistration-worker.js", { }).then(function(registration) {
+ registration.installing.postMessage("runTest");
+});
+</script>
+</body>
+</html>
Added: trunk/LayoutTests/http/tests/workers/service/resources/ServiceWorkerGlobalScope_getRegistration-worker.js (0 => 225513)
--- trunk/LayoutTests/http/tests/workers/service/resources/ServiceWorkerGlobalScope_getRegistration-worker.js (rev 0)
+++ trunk/LayoutTests/http/tests/workers/service/resources/ServiceWorkerGlobalScope_getRegistration-worker.js 2017-12-05 02:06:26 UTC (rev 225513)
@@ -0,0 +1,49 @@
+let client = null;
+
+function log(msg)
+{
+ client.postMessage(msg);
+}
+
+async function runTest()
+{
+ try {
+ let r = await navigator.serviceWorker.register("empty-worker.js", { scope: "/test" });
+ log("PASS: Registration succeeded");
+
+ let retrievedRegistration = await navigator.serviceWorker.getRegistration("/test");
+ if (r === retrievedRegistration)
+ log("PASS: getRegistration() returned the right registration");
+ else
+ log("FAIL: getRegistration() did not return the right registration");
+
+ let retrievedRegistrations = await navigator.serviceWorker.getRegistrations();
+ if (retrievedRegistrations.length === 2)
+ log("PASS: getRegistrations() returned 2 registrations");
+ else {
+ log("FAIL: getRegistrations() returned " + retrievedRegistrations.length + " registration(s)");
+ log("DONE");
+ return;
+ }
+
+ if (retrievedRegistrations[0] === self.registration)
+ log("PASS: getRegistrations()[0] is the right registration");
+ else
+ log("FAIL: getRegistrations()[0] is not the right registration");
+
+ if (retrievedRegistrations[1] === r)
+ log("PASS: getRegistrations()[1] is the right registration");
+ else
+ log("FAIL: getRegistrations()[1] is not the right registration");
+
+ log("DONE");
+ } catch (e) {
+ log("FAIL: " + e);
+ log("DONE");
+ }
+}
+
+self.addEventListener("message", (event) => {
+ client = event.source;
+ runTest();
+});
Modified: trunk/LayoutTests/imported/w3c/ChangeLog (225512 => 225513)
--- trunk/LayoutTests/imported/w3c/ChangeLog 2017-12-05 01:37:20 UTC (rev 225512)
+++ trunk/LayoutTests/imported/w3c/ChangeLog 2017-12-05 02:06:26 UTC (rev 225513)
@@ -1,3 +1,20 @@
+2017-12-04 Chris Dumez <cdu...@apple.com>
+
+ Support container.getRegistration() / getRegistrations() inside service workers
+ https://bugs.webkit.org/show_bug.cgi?id=180360
+
+ Reviewed by Youenn Fablet.
+
+ * web-platform-tests/service-workers/service-worker/activation.https-expected.txt:
+ Rebaseline test with slightly different output.
+
+ * web-platform-tests/service-workers/service-worker/skip-waiting-without-using-registration.https-expected.txt:
+ * web-platform-tests/service-workers/service-worker/skip-waiting-without-using-registration.https.html:
+ With my change, this test started running and passing a check before timing out. When investigating the time
+ out, I found out that this is caused by the test unregistering the worker while the test is still running
+ in the service worker, which causes the worker to terminate early. To address the issue, we no longer add
+ a cleanup step to unregister. The test now passes all checks.
+
2017-12-03 Chris Dumez <cdu...@apple.com>
Re-sync Service Workers web-platform-tests from upstream
Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/activation.https-expected.txt (225512 => 225513)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/activation.https-expected.txt 2017-12-05 01:37:20 UTC (rev 225512)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/activation.https-expected.txt 2017-12-05 02:06:26 UTC (rev 225513)
@@ -1,5 +1,5 @@
-
+
FAIL loss of controllees triggers activation assert_not_equals: got disallowed value null
FAIL finishing a request triggers activation assert_not_equals: got disallowed value null
FAIL skipWaiting bypasses no controllee requirement assert_not_equals: got disallowed value null
Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/skip-waiting-using-registration.https-expected.txt (225512 => 225513)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/skip-waiting-using-registration.https-expected.txt 2017-12-05 01:37:20 UTC (rev 225512)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/skip-waiting-using-registration.https-expected.txt 2017-12-05 02:06:26 UTC (rev 225513)
@@ -1,6 +1,4 @@
-Harness Error (TIMEOUT), message = null
-
PASS Test skipWaiting while a client is using the registration
-TIMEOUT skipWaiting Test timed out
+PASS skipWaiting
Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/skip-waiting-using-registration.https.html (225512 => 225513)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/skip-waiting-using-registration.https.html 2017-12-05 01:37:20 UTC (rev 225512)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/skip-waiting-using-registration.https.html 2017-12-05 02:06:26 UTC (rev 225513)
@@ -50,9 +50,6 @@
})
.then(function(registration) {
sw_registration = registration;
- t.add_cleanup(function() {
- registration.unregister();
- });
return saw_controllerchanged;
})
.then(function() {
Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/skip-waiting-without-using-registration.https-expected.txt (225512 => 225513)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/skip-waiting-without-using-registration.https-expected.txt 2017-12-05 01:37:20 UTC (rev 225512)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/skip-waiting-without-using-registration.https-expected.txt 2017-12-05 02:06:26 UTC (rev 225513)
@@ -1,3 +1,4 @@
-FAIL Test skipWaiting while a client is not being controlled promise_test: Unhandled rejection with value: object "TypeError: null is not an object (evaluating 'document.body.appendChild')"
+PASS Test skipWaiting while a client is not being controlled
+PASS skipWaiting
Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/skip-waiting-without-using-registration.https.html (225512 => 225513)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/skip-waiting-without-using-registration.https.html 2017-12-05 01:37:20 UTC (rev 225512)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/skip-waiting-without-using-registration.https.html 2017-12-05 02:06:26 UTC (rev 225513)
@@ -26,9 +26,6 @@
})
.then(function(registration) {
sw_registration = registration;
- t.add_cleanup(function() {
- registration.unregister();
- });
return wait_for_state(t, registration.installing, 'activated');
})
.then(function() {
Modified: trunk/Source/WebCore/ChangeLog (225512 => 225513)
--- trunk/Source/WebCore/ChangeLog 2017-12-05 01:37:20 UTC (rev 225512)
+++ trunk/Source/WebCore/ChangeLog 2017-12-05 02:06:26 UTC (rev 225513)
@@ -1,3 +1,33 @@
+2017-12-04 Chris Dumez <cdu...@apple.com>
+
+ Support container.getRegistration() / getRegistrations() inside service workers
+ https://bugs.webkit.org/show_bug.cgi?id=180360
+
+ Reviewed by Youenn Fablet.
+
+ Support container.getRegistration() / getRegistrations() inside service workers
+ by making sure we hop to the right thread when needed.
+
+ Test: http/tests/workers/service/ServiceWorkerGlobalScope_getRegistration.html
+
+ * dom/ScriptExecutionContext.cpp:
+ (WebCore::ScriptExecutionContext::postTaskTo):
+ * dom/ScriptExecutionContext.h:
+ * workers/service/SWClientConnection.cpp:
+ (WebCore::SWClientConnection::jobRejectedInServer):
+ (WebCore::SWClientConnection::registrationJobResolvedInServer):
+ (WebCore::SWClientConnection::unregistrationJobResolvedInServer):
+ (WebCore::SWClientConnection::startScriptFetchForServer):
+ (WebCore::SWClientConnection::clearPendingJobs):
+ * workers/service/SWClientConnection.h:
+ * workers/service/ServiceWorkerContainer.cpp:
+ (WebCore::ServiceWorkerContainer::getRegistration):
+ (WebCore::ServiceWorkerContainer::didFinishGetRegistrationRequest):
+ (WebCore::ServiceWorkerContainer::getRegistrations):
+ (WebCore::ServiceWorkerContainer::didFinishGetRegistrationsRequest):
+ (WebCore::ServiceWorkerContainer::stop):
+ * workers/service/ServiceWorkerContainer.h:
+
2017-12-04 Simon Fraser <simon.fra...@apple.com>
Cleanup code that computes iframe content offsets in FrameView
Modified: trunk/Source/WebCore/dom/ScriptExecutionContext.cpp (225512 => 225513)
--- trunk/Source/WebCore/dom/ScriptExecutionContext.cpp 2017-12-05 01:37:20 UTC (rev 225512)
+++ trunk/Source/WebCore/dom/ScriptExecutionContext.cpp 2017-12-05 02:06:26 UTC (rev 225513)
@@ -44,8 +44,10 @@
#include "RejectedPromiseTracker.h"
#include "ResourceRequest.h"
#include "SWClientConnection.h"
+#include "SWContextManager.h"
#include "ScriptState.h"
#include "ServiceWorker.h"
+#include "ServiceWorkerGlobalScope.h"
#include "ServiceWorkerProvider.h"
#include "Settings.h"
#include "WorkerGlobalScope.h"
@@ -582,6 +584,24 @@
return navigator ? &navigator->serviceWorker() : nullptr;
}
+
+void ScriptExecutionContext::postTaskTo(const DocumentOrWorkerIdentifier& contextIdentifier, WTF::Function<void(ScriptExecutionContext&)>&& task)
+{
+ ASSERT(isMainThread());
+
+ switchOn(contextIdentifier, [&] (DocumentIdentifier identifier) {
+ auto* document = Document::allDocumentsMap().get(identifier);
+ if (!document)
+ return;
+ document->postTask([task = WTFMove(task)](auto& scope) {
+ task(scope);
+ });
+ }, [&](ServiceWorkerIdentifier identifier) {
+ SWContextManager::singleton().postTaskToServiceWorker(identifier, [task = WTFMove(task)](auto& scope) {
+ task(scope);
+ });
+ });
+}
#endif
} // namespace WebCore
Modified: trunk/Source/WebCore/dom/ScriptExecutionContext.h (225512 => 225513)
--- trunk/Source/WebCore/dom/ScriptExecutionContext.h 2017-12-05 01:37:20 UTC (rev 225512)
+++ trunk/Source/WebCore/dom/ScriptExecutionContext.h 2017-12-05 02:06:26 UTC (rev 225513)
@@ -30,7 +30,7 @@
#include "ActiveDOMObject.h"
#include "DOMTimer.h"
#include "SecurityContext.h"
-#include "ServiceWorkerIdentifier.h"
+#include "ServiceWorkerTypes.h"
#include <heap/HandleTypes.h>
#include <runtime/ConsoleTypes.h>
#include <wtf/CrossThreadTask.h>
@@ -246,6 +246,8 @@
ServiceWorker* serviceWorker(ServiceWorkerIdentifier identifier) { return m_serviceWorkers.get(identifier); }
ServiceWorkerContainer* serviceWorkerContainer();
+
+ WEBCORE_EXPORT static void postTaskTo(const DocumentOrWorkerIdentifier&, WTF::Function<void(ScriptExecutionContext&)>&&);
#endif
protected:
Modified: trunk/Source/WebCore/workers/service/SWClientConnection.cpp (225512 => 225513)
--- trunk/Source/WebCore/workers/service/SWClientConnection.cpp 2017-12-05 01:37:20 UTC (rev 225512)
+++ trunk/Source/WebCore/workers/service/SWClientConnection.cpp 2017-12-05 02:06:26 UTC (rev 225513)
@@ -81,7 +81,7 @@
return;
}
- postTaskTo(job->contextIdentifier(), [job, exceptionData = exceptionData.isolatedCopy()] {
+ ScriptExecutionContext::postTaskTo(job->contextIdentifier(), [job, exceptionData = exceptionData.isolatedCopy()](ScriptExecutionContext&) {
job->failedWithException(exceptionData.toException());
});
}
@@ -96,7 +96,7 @@
return;
}
- postTaskTo(job->contextIdentifier(), [job, registrationData = registrationData.isolatedCopy(), shouldNotifyWhenResolved]() mutable {
+ ScriptExecutionContext::postTaskTo(job->contextIdentifier(), [job, registrationData = registrationData.isolatedCopy(), shouldNotifyWhenResolved](ScriptExecutionContext&) mutable {
job->resolvedWithRegistration(WTFMove(registrationData), shouldNotifyWhenResolved);
});
}
@@ -111,7 +111,7 @@
return;
}
- postTaskTo(job->contextIdentifier(), [job, unregistrationResult] {
+ ScriptExecutionContext::postTaskTo(job->contextIdentifier(), [job, unregistrationResult](ScriptExecutionContext&) {
job->resolvedWithUnregistrationResult(unregistrationResult);
});
}
@@ -131,7 +131,7 @@
return;
}
- postTaskTo(job->contextIdentifier(), [job] {
+ ScriptExecutionContext::postTaskTo(job->contextIdentifier(), [job](ScriptExecutionContext&) {
job->startScriptFetch();
});
}
@@ -232,30 +232,12 @@
auto jobs = WTFMove(m_scheduledJobs);
for (auto& job : jobs.values()) {
- postTaskTo(job->contextIdentifier(), [job] {
+ ScriptExecutionContext::postTaskTo(job->contextIdentifier(), [job](ScriptExecutionContext&) {
job->failedWithException(Exception { TypeError, ASCIILiteral("Internal error") });
});
}
}
-void SWClientConnection::postTaskTo(const DocumentOrWorkerIdentifier& contextIdentifier, WTF::Function<void()>&& task)
-{
- ASSERT(isMainThread());
-
- switchOn(contextIdentifier, [&](DocumentIdentifier identifier) {
- auto* document = Document::allDocumentsMap().get(identifier);
- if (!document)
- return;
- document->postTask([task = WTFMove(task)](ScriptExecutionContext&) {
- task();
- });
- }, [&](ServiceWorkerIdentifier identifier) {
- SWContextManager::singleton().postTaskToServiceWorker(identifier, [task = WTFMove(task)](ServiceWorkerGlobalScope&) {
- task();
- });
- });
-}
-
} // namespace WebCore
#endif // ENABLE(SERVICE_WORKER)
Modified: trunk/Source/WebCore/workers/service/SWClientConnection.h (225512 => 225513)
--- trunk/Source/WebCore/workers/service/SWClientConnection.h 2017-12-05 01:37:20 UTC (rev 225512)
+++ trunk/Source/WebCore/workers/service/SWClientConnection.h 2017-12-05 02:06:26 UTC (rev 225513)
@@ -98,7 +98,6 @@
WEBCORE_EXPORT void notifyClientsOfControllerChange(const HashSet<DocumentIdentifier>& contextIdentifiers, ServiceWorkerData&& newController);
WEBCORE_EXPORT void clearPendingJobs();
- WEBCORE_EXPORT void postTaskTo(const DocumentOrWorkerIdentifier&, WTF::Function<void()>&&);
private:
virtual void scheduleJobInServer(const ServiceWorkerJobData&) = 0;
Modified: trunk/Source/WebCore/workers/service/ServiceWorkerContainer.cpp (225512 => 225513)
--- trunk/Source/WebCore/workers/service/ServiceWorkerContainer.cpp 2017-12-05 01:37:20 UTC (rev 225512)
+++ trunk/Source/WebCore/workers/service/ServiceWorkerContainer.cpp 2017-12-05 02:06:26 UTC (rev 225513)
@@ -218,12 +218,6 @@
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") });
@@ -230,20 +224,41 @@
return;
}
- return ensureSWClientConnection().matchRegistration(context->topOrigin(), parsedURL, [promise = WTFMove(promise), protectingThis = makePendingActivity(*this), this] (auto&& result) mutable {
- if (m_isStopped)
- return;
+ uint64_t pendingPromiseIdentifier = ++m_lastPendingPromiseIdentifier;
+ auto pendingPromise = std::make_unique<PendingPromise>(WTFMove(promise), makePendingActivity(*this));
+ m_pendingPromises.add(pendingPromiseIdentifier, WTFMove(pendingPromise));
- if (!result) {
- promise->resolve();
- return;
- }
-
- auto registration = ServiceWorkerRegistration::getOrCreate(*scriptExecutionContext(), *this, WTFMove(result.value()));
- promise->resolve<IDLInterface<ServiceWorkerRegistration>>(WTFMove(registration));
+ auto contextIdentifier = this->contextIdentifier();
+ callOnMainThread([connection = makeRef(ensureSWClientConnection()), this, topOrigin = context->topOrigin().isolatedCopy(), parsedURL = parsedURL.isolatedCopy(), contextIdentifier, pendingPromiseIdentifier]() mutable {
+ connection->matchRegistration(topOrigin, parsedURL, [this, contextIdentifier, pendingPromiseIdentifier] (auto&& result) mutable {
+ ScriptExecutionContext::postTaskTo(contextIdentifier, [this, pendingPromiseIdentifier, result = crossThreadCopy(result)](ScriptExecutionContext&) mutable {
+ didFinishGetRegistrationRequest(pendingPromiseIdentifier, WTFMove(result));
+ });
+ });
});
}
+void ServiceWorkerContainer::didFinishGetRegistrationRequest(uint64_t pendingPromiseIdentifier, std::optional<ServiceWorkerRegistrationData>&& result)
+{
+#ifndef NDEBUG
+ ASSERT(m_creationThread.ptr() == &Thread::current());
+#endif
+
+ auto pendingPromise = m_pendingPromises.take(pendingPromiseIdentifier);
+ if (!pendingPromise)
+ return;
+
+ ASSERT(!m_isStopped);
+
+ if (!result) {
+ pendingPromise->promise->resolve();
+ return;
+ }
+
+ auto registration = ServiceWorkerRegistration::getOrCreate(*scriptExecutionContext(), *this, WTFMove(result.value()));
+ pendingPromise->promise->resolve<IDLInterface<ServiceWorkerRegistration>>(WTFMove(registration));
+}
+
void ServiceWorkerContainer::scheduleTaskToUpdateRegistrationState(ServiceWorkerRegistrationIdentifier identifier, ServiceWorkerRegistrationState state, const std::optional<ServiceWorkerData>& serviceWorkerData)
{
auto* context = scriptExecutionContext();
@@ -260,33 +275,46 @@
});
}
-void ServiceWorkerContainer::getRegistrations(RegistrationsPromise&& promise)
+void ServiceWorkerContainer::getRegistrations(Ref<DeferredPromise>&& promise)
{
auto* context = scriptExecutionContext();
if (!context) {
- promise.reject(Exception { InvalidStateError });
+ promise->reject(Exception { InvalidStateError });
return;
}
- // FIXME: Add support in workers.
- if (!is<Document>(*context)) {
- promise.reject(Exception { NotSupportedError, ASCIILiteral("serviceWorker.getRegistrations() is not yet supported in workers") });
+ uint64_t pendingPromiseIdentifier = ++m_lastPendingPromiseIdentifier;
+ auto pendingPromise = std::make_unique<PendingPromise>(WTFMove(promise), makePendingActivity(*this));
+ m_pendingPromises.add(pendingPromiseIdentifier, WTFMove(pendingPromise));
+
+ auto contextIdentifier = this->contextIdentifier();
+ auto contextURL = context->url();
+ callOnMainThread([connection = makeRef(ensureSWClientConnection()), this, topOrigin = context->topOrigin().isolatedCopy(), contextURL = contextURL.isolatedCopy(), contextIdentifier, pendingPromiseIdentifier]() mutable {
+ connection->getRegistrations(topOrigin, contextURL, [this, contextIdentifier, pendingPromiseIdentifier] (auto&& registrationDatas) mutable {
+ ScriptExecutionContext::postTaskTo(contextIdentifier, [this, pendingPromiseIdentifier, registrationDatas = crossThreadCopy(registrationDatas)](ScriptExecutionContext&) mutable {
+ didFinishGetRegistrationsRequest(pendingPromiseIdentifier, WTFMove(registrationDatas));
+ });
+ });
+ });
+}
+
+void ServiceWorkerContainer::didFinishGetRegistrationsRequest(uint64_t pendingPromiseIdentifier, Vector<ServiceWorkerRegistrationData>&& registrationDatas)
+{
+#ifndef NDEBUG
+ ASSERT(m_creationThread.ptr() == &Thread::current());
+#endif
+
+ auto pendingPromise = m_pendingPromises.take(pendingPromiseIdentifier);
+ if (!pendingPromise)
return;
- }
- return ensureSWClientConnection().getRegistrations(context->topOrigin(), context->url(), [this, pendingActivity = makePendingActivity(*this), promise = WTFMove(promise)] (auto&& registrationDatas) mutable {
- if (m_isStopped)
- return;
+ ASSERT(!m_isStopped);
- Vector<Ref<ServiceWorkerRegistration>> registrations;
- registrations.reserveInitialCapacity(registrationDatas.size());
- for (auto& registrationData : registrationDatas) {
- auto registration = ServiceWorkerRegistration::getOrCreate(*scriptExecutionContext(), *this, WTFMove(registrationData));
- registrations.uncheckedAppend(WTFMove(registration));
- }
+ auto registrations = WTF::map(WTFMove(registrationDatas), [&] (auto&& registrationData) {
+ return ServiceWorkerRegistration::getOrCreate(*scriptExecutionContext(), *this, WTFMove(registrationData));
+ });
- promise.resolve(WTFMove(registrations));
- });
+ pendingPromise->promise->resolve<IDLSequence<IDLInterface<ServiceWorkerRegistration>>>(WTFMove(registrations));
}
void ServiceWorkerContainer::startMessages()
@@ -508,6 +536,7 @@
{
m_isStopped = true;
removeAllEventListeners();
+ m_pendingPromises.clear();
}
DocumentOrWorkerIdentifier ServiceWorkerContainer::contextIdentifier()
Modified: trunk/Source/WebCore/workers/service/ServiceWorkerContainer.h (225512 => 225513)
--- trunk/Source/WebCore/workers/service/ServiceWorkerContainer.h 2017-12-05 01:37:20 UTC (rev 225512)
+++ trunk/Source/WebCore/workers/service/ServiceWorkerContainer.h 2017-12-05 02:06:26 UTC (rev 225513)
@@ -68,8 +68,7 @@
void scheduleTaskToFireUpdateFoundEvent(ServiceWorkerRegistrationIdentifier);
void scheduleTaskToFireControllerChangeEvent();
- using RegistrationsPromise = DOMPromiseDeferred<IDLSequence<IDLInterface<ServiceWorkerRegistration>>>;
- void getRegistrations(RegistrationsPromise&&);
+ void getRegistrations(Ref<DeferredPromise>&&);
ServiceWorkerRegistration* registration(ServiceWorkerRegistrationIdentifier identifier) const { return m_registrations.get(identifier); }
@@ -95,6 +94,9 @@
void jobDidFinish(ServiceWorkerJob&);
+ void didFinishGetRegistrationRequest(uint64_t requestIdentifier, std::optional<ServiceWorkerRegistrationData>&&);
+ void didFinishGetRegistrationsRequest(uint64_t requestIdentifier, Vector<ServiceWorkerRegistrationData>&&);
+
SWServerConnectionIdentifier connectionIdentifier() final;
DocumentOrWorkerIdentifier contextIdentifier() final;
@@ -121,6 +123,19 @@
#ifndef NDEBUG
Ref<Thread> m_creationThread { Thread::current() };
#endif
+
+ struct PendingPromise {
+ PendingPromise(Ref<DeferredPromise>&& promise, Ref<PendingActivity<ServiceWorkerContainer>>&& pendingActivity)
+ : promise(WTFMove(promise))
+ , pendingActivity(WTFMove(pendingActivity))
+ { }
+
+ Ref<DeferredPromise> promise;
+ Ref<PendingActivity<ServiceWorkerContainer>> pendingActivity;
+ };
+
+ uint64_t m_lastPendingPromiseIdentifier { 0 };
+ HashMap<uint64_t, std::unique_ptr<PendingPromise>> m_pendingPromises;
};
} // namespace WebCore
Modified: trunk/Source/WebKit/ChangeLog (225512 => 225513)
--- trunk/Source/WebKit/ChangeLog 2017-12-05 01:37:20 UTC (rev 225512)
+++ trunk/Source/WebKit/ChangeLog 2017-12-05 02:06:26 UTC (rev 225513)
@@ -1,3 +1,16 @@
+2017-12-04 Chris Dumez <cdu...@apple.com>
+
+ Support container.getRegistration() / getRegistrations() inside service workers
+ https://bugs.webkit.org/show_bug.cgi?id=180360
+
+ Reviewed by Youenn Fablet.
+
+ * WebProcess/Storage/WebSWClientConnection.cpp:
+ (WebKit::WebSWClientConnection::didMatchRegistration):
+ (WebKit::WebSWClientConnection::didGetRegistrations):
+ (WebKit::WebSWClientConnection::matchRegistration):
+ (WebKit::WebSWClientConnection::getRegistrations):
+
2017-12-04 Brady Eidson <beid...@apple.com>
Followup to:
Modified: trunk/Source/WebKit/WebProcess/Storage/WebSWClientConnection.cpp (225512 => 225513)
--- trunk/Source/WebKit/WebProcess/Storage/WebSWClientConnection.cpp 2017-12-05 01:37:20 UTC (rev 225512)
+++ trunk/Source/WebKit/WebProcess/Storage/WebSWClientConnection.cpp 2017-12-05 02:06:26 UTC (rev 225513)
@@ -137,6 +137,8 @@
void WebSWClientConnection::didMatchRegistration(uint64_t matchingRequest, std::optional<ServiceWorkerRegistrationData>&& result)
{
+ ASSERT(isMainThread());
+
if (auto completionHandler = m_ongoingMatchRegistrationTasks.take(matchingRequest))
completionHandler(WTFMove(result));
}
@@ -143,6 +145,8 @@
void WebSWClientConnection::didGetRegistrations(uint64_t matchingRequest, Vector<ServiceWorkerRegistrationData>&& registrations)
{
+ ASSERT(isMainThread());
+
if (auto completionHandler = m_ongoingGetRegistrationsTasks.take(matchingRequest))
completionHandler(WTFMove(registrations));
}
@@ -149,6 +153,8 @@
void WebSWClientConnection::matchRegistration(const SecurityOrigin& topOrigin, const URL& clientURL, RegistrationCallback&& callback)
{
+ ASSERT(isMainThread());
+
if (!mayHaveServiceWorkerRegisteredForOrigin(topOrigin)) {
callback(std::nullopt);
return;
@@ -161,6 +167,8 @@
void WebSWClientConnection::getRegistrations(const SecurityOrigin& topOrigin, const URL& clientURL, GetRegistrationsCallback&& callback)
{
+ ASSERT(isMainThread());
+
if (!mayHaveServiceWorkerRegisteredForOrigin(topOrigin)) {
callback({ });
return;