Diff
Modified: trunk/LayoutTests/ChangeLog (226676 => 226677)
--- trunk/LayoutTests/ChangeLog 2018-01-10 03:31:28 UTC (rev 226676)
+++ trunk/LayoutTests/ChangeLog 2018-01-10 04:08:33 UTC (rev 226677)
@@ -1,5 +1,25 @@
2018-01-09 Chris Dumez <[email protected]>
+ Make service workers behave correctly with regards to Page Cache
+ https://bugs.webkit.org/show_bug.cgi?id=181446
+ <rdar://problem/36164291>
+
+ Reviewed by Youenn Fablet.
+
+ Add layout test coverage.
+
+ * http/tests/workers/service/client-added-to-clients-when-restored-from-page-cache-expected.txt: Added.
+ * http/tests/workers/service/client-added-to-clients-when-restored-from-page-cache.html: Added.
+ * http/tests/workers/service/client-removed-from-clients-while-in-page-cache-expected.txt: Added.
+ * http/tests/workers/service/client-removed-from-clients-while-in-page-cache.html: Added.
+ * http/tests/workers/service/no-page-cache-when-controlled-expected.txt: Added.
+ * http/tests/workers/service/no-page-cache-when-controlled.html: Added.
+ * http/tests/workers/service/other_resources/test.html: Added.
+ * http/tests/workers/service/resources/getClientCount-worker.js: Added.
+ (event.then):
+
+2018-01-09 Chris Dumez <[email protected]>
+
We should not return undefined for most properties of a detached Window
https://bugs.webkit.org/show_bug.cgi?id=181416
<rdar://problem/36162489>
Added: trunk/LayoutTests/http/tests/workers/service/client-added-to-clients-when-restored-from-page-cache-expected.txt (0 => 226677)
--- trunk/LayoutTests/http/tests/workers/service/client-added-to-clients-when-restored-from-page-cache-expected.txt (rev 0)
+++ trunk/LayoutTests/http/tests/workers/service/client-added-to-clients-when-restored-from-page-cache-expected.txt 2018-01-10 04:08:33 UTC (rev 226677)
@@ -0,0 +1,6 @@
+* Tests that a client is re-added to the list of service worker clients when it is restored from the page cache
+
+PASS: service worker has initially 2 clients
+PASS: page is about to enter page cache
+PASS: service worker now has 2 clients again after restoring the second one from page cache
+
Added: trunk/LayoutTests/http/tests/workers/service/client-added-to-clients-when-restored-from-page-cache.html (0 => 226677)
--- trunk/LayoutTests/http/tests/workers/service/client-added-to-clients-when-restored-from-page-cache.html (rev 0)
+++ trunk/LayoutTests/http/tests/workers/service/client-added-to-clients-when-restored-from-page-cache.html 2018-01-10 04:08:33 UTC (rev 226677)
@@ -0,0 +1,69 @@
+<!DOCTYPE html>
+<html>
+<body>
+<script src=""
+<script>
+log("* Tests that a client is re-added to the list of service worker clients when it is restored from the page cache");
+log("");
+
+if (window.testRunner) {
+ testRunner.setCanOpenWindows();
+ testRunner.overridePreference("WebKitUsesPageCachePreferenceKey", 1);
+}
+
+navigator.serviceWorker.addEventListener("message", function(event) {
+ if (step == "BothClientsInitiallyActive") {
+ if (event.data != 2) {
+ log("FAIL: Wrong initial number of clients: " + event.data);
+ finishSWTest();
+ return;
+ }
+ log("PASS: service worker has initially 2 clients");
+
+ otherWindow.addEventListener("pagehide", function(event) {
+ if (!event.persisted) {
+ log("FAIL: page failed to enter page cache");
+ finishSWTest();
+ return;
+ }
+ log("PASS: page is about to enter page cache");
+ });
+
+ otherWindow.addEventListener("pageshow", function(event) {
+ if (!event.persisted) {
+ log("FAIL: page was not restored from page cache");
+ finishSWTest();
+ return;
+ }
+ setTimeout(function() {
+ step = "SecondClientRestoredFromPageCache";
+ worker.postMessage("getClientCount");
+ }, 0);
+ });
+
+ otherWindow.location.href = ""
+ return;
+ }
+
+ if (step == "SecondClientRestoredFromPageCache") {
+ if (event.data != 2) {
+ log("FAIL: Wrong number of clients after one client was restored from page cache: " + event.data);
+ finishSWTest();
+ }
+
+ log("PASS: service worker now has 2 clients again after restoring the second one from page cache");
+ finishSWTest();
+ }
+});
+
+navigator.serviceWorker.register("resources/getClientCount-worker.js", { }).then(function(registration) {
+ worker = registration.installing;
+ otherWindow = open("other_resources/test.html");
+ otherWindow._onload_ = function() {
+ step = "BothClientsInitiallyActive"
+ worker.postMessage("getClientCount");
+ };
+});
+</script>
+</body>
+</html>
Added: trunk/LayoutTests/http/tests/workers/service/client-removed-from-clients-while-in-page-cache-expected.txt (0 => 226677)
--- trunk/LayoutTests/http/tests/workers/service/client-removed-from-clients-while-in-page-cache-expected.txt (rev 0)
+++ trunk/LayoutTests/http/tests/workers/service/client-removed-from-clients-while-in-page-cache-expected.txt 2018-01-10 04:08:33 UTC (rev 226677)
@@ -0,0 +1,6 @@
+* Tests that a client is removed from the list of service worker clients while it is in the page cache
+
+PASS: service worker has initially 2 clients
+PASS: page is about to enter page cache
+PASS: service worker has only 1 client after 1 entered page cache
+
Added: trunk/LayoutTests/http/tests/workers/service/client-removed-from-clients-while-in-page-cache.html (0 => 226677)
--- trunk/LayoutTests/http/tests/workers/service/client-removed-from-clients-while-in-page-cache.html (rev 0)
+++ trunk/LayoutTests/http/tests/workers/service/client-removed-from-clients-while-in-page-cache.html 2018-01-10 04:08:33 UTC (rev 226677)
@@ -0,0 +1,62 @@
+<!DOCTYPE html>
+<html>
+<body>
+<script src=""
+<script>
+log("* Tests that a client is removed from the list of service worker clients while it is in the page cache");
+log("");
+
+if (window.testRunner) {
+ testRunner.setCanOpenWindows();
+ testRunner.overridePreference("WebKitUsesPageCachePreferenceKey", 1);
+}
+
+navigator.serviceWorker.addEventListener("message", function(event) {
+ if (step == "BothClientsInitiallyActive") {
+ if (event.data != 2) {
+ log("FAIL: Wrong initial number of clients: " + event.data);
+ finishSWTest();
+ return;
+ }
+ log("PASS: service worker has initially 2 clients");
+
+ otherWindow.addEventListener("pagehide", function(event) {
+ if (!event.persisted) {
+ log("FAIL: page failed to enter page cache");
+ finishSWTest();
+ return;
+ }
+ log("PASS: page is about to enter page cache");
+
+ setTimeout(function() {
+ step = "OnlyOneClientRemainsActive"
+ worker.postMessage("getClientCount");
+ }, 0);
+ });
+
+ otherWindow.location.href = ""
+ return;
+ }
+
+ if (step == "OnlyOneClientRemainsActive") {
+ if (event.data != 1) {
+ log("FAIL: Wrong number of clients after one client entered page cache: " + event.data);
+ finishSWTest();
+ }
+
+ log("PASS: service worker has only 1 client after 1 entered page cache");
+ finishSWTest();
+ }
+});
+
+navigator.serviceWorker.register("resources/getClientCount-worker.js", { }).then(function(registration) {
+ worker = registration.installing;
+ otherWindow = open("other_resources/test.html");
+ otherWindow._onload_ = function() {
+ step = "BothClientsInitiallyActive"
+ worker.postMessage("getClientCount");
+ };
+});
+</script>
+</body>
+</html>
Added: trunk/LayoutTests/http/tests/workers/service/no-page-cache-when-controlled-expected.txt (0 => 226677)
--- trunk/LayoutTests/http/tests/workers/service/no-page-cache-when-controlled-expected.txt (rev 0)
+++ trunk/LayoutTests/http/tests/workers/service/no-page-cache-when-controlled-expected.txt 2018-01-10 04:08:33 UTC (rev 226677)
@@ -0,0 +1,3 @@
+pageshow - not from page cache
+PASS: page did not enter page cache
+
Added: trunk/LayoutTests/http/tests/workers/service/no-page-cache-when-controlled.html (0 => 226677)
--- trunk/LayoutTests/http/tests/workers/service/no-page-cache-when-controlled.html (rev 0)
+++ trunk/LayoutTests/http/tests/workers/service/no-page-cache-when-controlled.html 2018-01-10 04:08:33 UTC (rev 226677)
@@ -0,0 +1,57 @@
+<html>
+<head>
+<script src=""
+</head>
+<body>
+<script>
+let initialController = null;
+
+if (window.testRunner) {
+ testRunner.setCanOpenWindows();
+ testRunner.overridePreference("WebKitUsesPageCachePreferenceKey", 1);
+}
+
+window.addEventListener("pageshow", function(event) {
+ log("pageshow - " + (event.persisted ? "" : "not ") + "from page cache");
+ if (!window.sessionStorage.sw_page_cache_with_controller_test_started)
+ return;
+
+ if (event.persisted)
+ log("FAIL: page entered page cache even though its iframe has a controller");
+ else
+ log("PASS: page did not enter page cache");
+
+ finishSWTest();
+});
+
+window.addEventListener("pagehide", function(event) {
+ log("pagehide - " + (event.persisted ? "" : "not ") + "entering page cache");
+ if (event.persisted) {
+ log("FAIL: page entering page cache even though its iframe has a controller");
+ finishSWTest();
+ }
+});
+
+async function test() {
+ let scopeURL = "/workers/service/resources/";
+ await registerAndWaitForActive("resources/updating-fetch-worker.php", scopeURL);
+ let frame = await withFrame(scopeURL);
+ if (frame.contentWindow.navigator.serviceWorker.controller === null) {
+ log("FAIL: frame does not have a controller");
+ finishSWTest();
+ return;
+ }
+
+ log("PASS: frame has a controller");
+
+ gc();
+ setTimeout(function() {
+ window.sessionStorage.sw_page_cache_with_controller_test_started = true;
+ location.href = ""
+ }, 0);
+}
+
+window._onload_ = test;
+</script>
+</body>
+</html>
Added: trunk/LayoutTests/http/tests/workers/service/other_resources/test.html (0 => 226677)
--- trunk/LayoutTests/http/tests/workers/service/other_resources/test.html (rev 0)
+++ trunk/LayoutTests/http/tests/workers/service/other_resources/test.html 2018-01-10 04:08:33 UTC (rev 226677)
@@ -0,0 +1 @@
+TEST
Added: trunk/LayoutTests/http/tests/workers/service/resources/getClientCount-worker.js (0 => 226677)
--- trunk/LayoutTests/http/tests/workers/service/resources/getClientCount-worker.js (rev 0)
+++ trunk/LayoutTests/http/tests/workers/service/resources/getClientCount-worker.js 2018-01-10 04:08:33 UTC (rev 226677)
@@ -0,0 +1,6 @@
+self.addEventListener("message", (event) => {
+ source = event.source;
+ clients.matchAll({ includeUncontrolled : true }).then(function(clientList) {
+ source.postMessage(clientList.length);
+ });
+});
Modified: trunk/Source/WebCore/ChangeLog (226676 => 226677)
--- trunk/Source/WebCore/ChangeLog 2018-01-10 03:31:28 UTC (rev 226676)
+++ trunk/Source/WebCore/ChangeLog 2018-01-10 04:08:33 UTC (rev 226677)
@@ -1,5 +1,32 @@
2018-01-09 Chris Dumez <[email protected]>
+ Make service workers behave correctly with regards to Page Cache
+ https://bugs.webkit.org/show_bug.cgi?id=181446
+ <rdar://problem/36164291>
+
+ Reviewed by Youenn Fablet.
+
+ Make service workers behave correctly with regards to Page Cache:
+ 1. If a document has an active service worker, do not let it go into PageCache
+ 2. When a document goes into page cache, unregister it from the list of service worker clients
+ 3. When a document is restored from page cache, add it nack to the list of service worker clients
+
+ Tests: http/tests/workers/service/client-added-to-clients-when-restored-from-page-cache.html
+ http/tests/workers/service/client-removed-from-clients-while-in-page-cache.html
+ http/tests/workers/service/no-page-cache-when-controlled.html
+ http/tests/workers/service/other_resources/test.html
+
+ * dom/Document.cpp:
+ (WebCore::Document::suspend):
+ (WebCore::Document::resume):
+ * history/PageCache.cpp:
+ (WebCore::canCacheFrame):
+ * page/DiagnosticLoggingKeys.cpp:
+ (WebCore::DiagnosticLoggingKeys::serviceWorkerKey):
+ * page/DiagnosticLoggingKeys.h:
+
+2018-01-09 Chris Dumez <[email protected]>
+
We should not return undefined for most properties of a detached Window
https://bugs.webkit.org/show_bug.cgi?id=181416
<rdar://problem/36162489>
Modified: trunk/Source/WebCore/dom/Document.cpp (226676 => 226677)
--- trunk/Source/WebCore/dom/Document.cpp 2018-01-10 03:31:28 UTC (rev 226676)
+++ trunk/Source/WebCore/dom/Document.cpp 2018-01-10 04:08:33 UTC (rev 226677)
@@ -4878,6 +4878,13 @@
view->compositor().cancelCompositingLayerUpdate();
}
+#if ENABLE(SERVICE_WORKER)
+ if (RuntimeEnabledFeatures::sharedFeatures().serviceWorkerEnabled() && reason == ActiveDOMObject::ReasonForSuspension::PageCache) {
+ ASSERT_WITH_MESSAGE(!activeServiceWorker(), "Documents with an active service worker should not go into PageCache in the first place");
+ setServiceWorkerConnection(nullptr);
+ }
+#endif
+
suspendScheduledTasks(reason);
ASSERT(m_frame);
@@ -4909,6 +4916,13 @@
resumeScheduledTasks(reason);
+#if ENABLE(SERVICE_WORKER)
+ if (RuntimeEnabledFeatures::sharedFeatures().serviceWorkerEnabled() && reason == ActiveDOMObject::ReasonForSuspension::PageCache) {
+ ASSERT_WITH_MESSAGE(!activeServiceWorker(), "Documents with an active service worker should not go into PageCache in the first place");
+ setServiceWorkerConnection(&ServiceWorkerProvider::singleton().serviceWorkerConnectionForSession(sessionID()));
+ }
+#endif
+
m_visualUpdatesAllowed = true;
m_isSuspended = false;
Modified: trunk/Source/WebCore/history/PageCache.cpp (226676 => 226677)
--- trunk/Source/WebCore/history/PageCache.cpp 2018-01-10 03:31:28 UTC (rev 226676)
+++ trunk/Source/WebCore/history/PageCache.cpp 2018-01-10 04:08:33 UTC (rev 226677)
@@ -156,6 +156,13 @@
logPageCacheFailureDiagnosticMessage(diagnosticLoggingClient, DiagnosticLoggingKeys::cannotSuspendActiveDOMObjectsKey());
isCacheable = false;
}
+#if ENABLE(SERVICE_WORKER)
+ if (frame.document() && frame.document()->activeServiceWorker()) {
+ PCLOG(" -The document has an active service worker");
+ logPageCacheFailureDiagnosticMessage(diagnosticLoggingClient, DiagnosticLoggingKeys::serviceWorkerKey());
+ isCacheable = false;
+ }
+#endif
// FIXME: We should investigating caching frames that have an associated
// application cache. <rdar://problem/5917899> tracks that work.
if (!documentLoader->applicationCacheHost().canCacheInPageCache()) {
Modified: trunk/Source/WebCore/page/DiagnosticLoggingKeys.cpp (226676 => 226677)
--- trunk/Source/WebCore/page/DiagnosticLoggingKeys.cpp 2018-01-10 03:31:28 UTC (rev 226676)
+++ trunk/Source/WebCore/page/DiagnosticLoggingKeys.cpp 2018-01-10 04:08:33 UTC (rev 226677)
@@ -475,11 +475,6 @@
return ASCIILiteral("diskCacheAfterValidation");
}
-String DiagnosticLoggingKeys::serviceWorkerKey()
-{
- return ASCIILiteral("serviceWorker");
-}
-
String DiagnosticLoggingKeys::reloadKey()
{
return ASCIILiteral("reload");
@@ -535,6 +530,11 @@
return ASCIILiteral("script");
}
+String DiagnosticLoggingKeys::serviceWorkerKey()
+{
+ return ASCIILiteral("serviceWorker");
+}
+
String DiagnosticLoggingKeys::streamingMedia()
{
return ASCIILiteral("streamingMedia");
Modified: trunk/Source/WebCore/page/DiagnosticLoggingKeys.h (226676 => 226677)
--- trunk/Source/WebCore/page/DiagnosticLoggingKeys.h 2018-01-10 03:31:28 UTC (rev 226676)
+++ trunk/Source/WebCore/page/DiagnosticLoggingKeys.h 2018-01-10 04:08:33 UTC (rev 226677)
@@ -50,7 +50,6 @@
static String deviceMotionKey();
static String deviceOrientationKey();
static String diskCacheKey();
- static String serviceWorkerKey();
static String diskCacheAfterValidationKey();
static String documentLoaderStoppingKey();
WEBCORE_EXPORT static String domainCausingCrashKey();
@@ -140,6 +139,7 @@
WEBCORE_EXPORT static String revalidatingKey();
static String sameLoadKey();
static String scriptKey();
+ static String serviceWorkerKey();
WEBCORE_EXPORT static String streamingMedia();
static String styleSheetKey();
WEBCORE_EXPORT static String successfulSpeculativeWarmupWithRevalidationKey();