Changeset 292459 in webkit
- Timestamp:
- Apr 6, 2022 4:17:25 AM (4 months ago)
- Location:
- trunk
- Files:
-
- 3 added
- 1 deleted
- 35 edited
-
LayoutTests/ChangeLog (modified) (1 diff)
-
LayoutTests/http/wpt/service-workers/navigate-iframes-window-client.https-expected.txt (added)
-
LayoutTests/http/wpt/service-workers/navigate-iframes-window-client.https.html (added)
-
LayoutTests/http/wpt/service-workers/navigate-window-client-worker.js (added)
-
LayoutTests/imported/w3c/ChangeLog (modified) (1 diff)
-
LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/windowclient-navigate.https-expected.txt (modified) (1 diff)
-
LayoutTests/platform/glib/TestExpectations (modified) (1 diff)
-
LayoutTests/platform/glib/imported/w3c/web-platform-tests/service-workers/service-worker/windowclient-navigate.https-expected.txt (deleted)
-
LayoutTests/platform/mac-wk2/TestExpectations (modified) (1 diff)
-
Source/WebCore/ChangeLog (modified) (1 diff)
-
Source/WebCore/dom/Document.cpp (modified) (2 diffs)
-
Source/WebCore/dom/Document.h (modified) (1 diff)
-
Source/WebCore/workers/service/ServiceWorkerClientData.cpp (modified) (2 diffs)
-
Source/WebCore/workers/service/ServiceWorkerClientData.h (modified) (5 diffs)
-
Source/WebCore/workers/service/ServiceWorkerWindowClient.cpp (modified) (1 diff)
-
Source/WebCore/workers/service/context/SWContextManager.h (modified) (1 diff)
-
Source/WebCore/workers/service/server/SWServer.cpp (modified) (1 diff)
-
Source/WebCore/workers/service/server/SWServer.h (modified) (2 diffs)
-
Source/WebCore/workers/service/server/SWServerWorker.cpp (modified) (1 diff)
-
Source/WebCore/workers/service/server/SWServerWorker.h (modified) (1 diff)
-
Source/WebKit/ChangeLog (modified) (1 diff)
-
Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerConnection.cpp (modified) (3 diffs)
-
Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerConnection.h (modified) (4 diffs)
-
Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerToContextConnection.cpp (modified) (1 diff)
-
Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerToContextConnection.h (modified) (1 diff)
-
Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerToContextConnection.messages.in (modified) (1 diff)
-
Source/WebKit/UIProcess/Network/NetworkProcessProxy.cpp (modified) (1 diff)
-
Source/WebKit/UIProcess/Network/NetworkProcessProxy.h (modified) (1 diff)
-
Source/WebKit/UIProcess/Network/NetworkProcessProxy.messages.in (modified) (1 diff)
-
Source/WebKit/UIProcess/ProvisionalPageProxy.cpp (modified) (1 diff)
-
Source/WebKit/UIProcess/WebFrameProxy.cpp (modified) (9 diffs)
-
Source/WebKit/UIProcess/WebFrameProxy.h (modified) (3 diffs)
-
Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.cpp (modified) (1 diff)
-
Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.h (modified) (1 diff)
-
Source/WebKit/WebProcess/WebPage/WebPage.cpp (modified) (1 diff)
-
Source/WebKit/WebProcess/WebPage/WebPage.h (modified) (1 diff)
-
Source/WebKit/WebProcess/WebPage/WebPage.messages.in (modified) (1 diff)
-
Tools/ChangeLog (modified) (1 diff)
-
Tools/TestWebKitAPI/Tests/WebKitCocoa/ServiceWorkerBasic.mm (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r292449 r292459 1 2022-04-06 Youenn Fablet <youenn@apple.com> 2 3 Implement ServiceWorkerWindowClient.navigate 4 https://bugs.webkit.org/show_bug.cgi?id=238738 5 6 Reviewed by Chris Dumez. 7 8 * http/wpt/service-workers/navigate-iframes-window-client.https-expected.txt: Added. 9 * http/wpt/service-workers/navigate-iframes-window-client.https.html: Added. 10 * http/wpt/service-workers/navigate-window-client-worker.js: Added. 11 * platform/glib/TestExpectations: 12 * platform/glib/imported/w3c/web-platform-tests/service-workers/service-worker/windowclient-navigate.https-expected.txt: Removed. 13 * platform/mac-wk2/TestExpectations: 14 1 15 2022-04-05 Ada Chan <adachan@apple.com> 2 16 -
trunk/LayoutTests/imported/w3c/ChangeLog
r292432 r292459 1 2022-04-06 Youenn Fablet <youenn@apple.com> 2 3 Implement ServiceWorkerWindowClient.navigate 4 https://bugs.webkit.org/show_bug.cgi?id=238738 5 6 Reviewed by Chris Dumez. 7 8 * web-platform-tests/service-workers/service-worker/windowclient-navigate.https-expected.txt: 9 1 10 2022-04-05 Matt Woodrow <mattwoodrow@apple.com> 2 11 -
trunk/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/windowclient-navigate.https-expected.txt
r289558 r292459 11 11 PASS invalid url (about:blank) 12 12 PASS navigate on a top-level window client 13 FAIL normal worker side promise_test: Unhandled rejection with value: object "NotSupportedError: windowClient.navigate() is not yet supported" 14 FAIL blank url worker side promise_test: Unhandled rejection with value: object "NotSupportedError: windowClient.navigate() is not yet supported" 15 FAIL in scope but not controlled test on installing worker worker side promise_rejects_js: function "function () { throw e }" threw object "NotSupportedError: windowClient.navigate() is not yet supported" ("NotSupportedError") expected instance of function "function TypeError() { 16 [native code] 17 }" ("TypeError") 18 FAIL in scope but not controlled test on active worker worker side promise_rejects_js: function "function () { throw e }" threw object "NotSupportedError: windowClient.navigate() is not yet supported" ("NotSupportedError") expected instance of function "function TypeError() { 19 [native code] 20 }" ("TypeError") 21 FAIL out of scope worker side promise_rejects_js: function "function () { throw e }" threw object "NotSupportedError: windowClient.navigate() is not yet supported" ("NotSupportedError") expected instance of function "function TypeError() { 22 [native code] 23 }" ("TypeError") 24 FAIL cross orgin url worker side promise_test: Unhandled rejection with value: object "NotSupportedError: windowClient.navigate() is not yet supported" 25 FAIL invalid url (http://[example.com]) worker side promise_rejects_js: function "function () { throw e }" threw object "NotSupportedError: windowClient.navigate() is not yet supported" ("NotSupportedError") expected instance of function "function TypeError() { 26 [native code] 27 }" ("TypeError") 28 FAIL invalid url (view-source://example.com) worker side promise_rejects_js: function "function () { throw e }" threw object "NotSupportedError: windowClient.navigate() is not yet supported" ("NotSupportedError") expected instance of function "function TypeError() { 29 [native code] 30 }" ("TypeError") 31 FAIL invalid url (file:///) worker side promise_rejects_js: function "function () { throw e }" threw object "NotSupportedError: windowClient.navigate() is not yet supported" ("NotSupportedError") expected instance of function "function TypeError() { 32 [native code] 33 }" ("TypeError") 34 FAIL invalid url (about:blank) worker side promise_rejects_js: function "function () { throw e }" threw object "NotSupportedError: windowClient.navigate() is not yet supported" ("NotSupportedError") expected instance of function "function TypeError() { 35 [native code] 36 }" ("TypeError") 13 PASS normal worker side 14 PASS blank url worker side 15 PASS in scope but not controlled test on installing worker worker side 16 PASS in scope but not controlled test on active worker worker side 17 PASS out of scope worker side 18 PASS cross orgin url worker side 19 PASS invalid url (http://[example.com]) worker side 20 PASS invalid url (view-source://example.com) worker side 21 FAIL invalid url (file:///) worker side assert_equals: expected (string) "TypeError" but got (object) null 22 PASS invalid url (about:blank) worker side 37 23 FAIL navigate on a top-level window client worker side assert_equals: expected "top-level" but got "auxiliary" 38 24 -
trunk/LayoutTests/platform/glib/TestExpectations
r292086 r292459 1194 1194 webkit.org/b/201981 http/wpt/service-workers/server-trust-evaluation.https.html [ Failure ] 1195 1195 webkit.org/b/201981 imported/w3c/web-platform-tests/service-workers/service-worker/fetch-canvas-tainting-image-cache.https.html [ Failure Pass ] 1196 1197 webkit.org/b/238738 http/wpt/service-workers/navigate-iframes-window-client.https.html [ Failure ] 1198 webkit.org/b/238738238738 imported/w3c/web-platform-tests/service-workers/service-worker/windowclient-navigate.https.html [ Failure ] 1196 1199 1197 1200 webkit.org/b/208369 http/tests/workers/service/basic-timeout.https.html [ Failure Timeout Pass ] -
trunk/LayoutTests/platform/mac-wk2/TestExpectations
r292274 r292459 925 925 webkit.org/b/230412 imported/w3c/web-platform-tests/service-workers/service-worker/clients-matchall-client-types.https.html [ Pass Failure ] 926 926 927 webkit.org/b/179352 imported/w3c/web-platform-tests/service-workers/service-worker/windowclient-navigate.https.html [ Pass FailureSlow ]927 webkit.org/b/179352 imported/w3c/web-platform-tests/service-workers/service-worker/windowclient-navigate.https.html [ Slow ] 928 928 929 929 webkit.org/b/183164 fast/dom/Window/window-focus-self.html [ Pass Failure ] -
trunk/Source/WebCore/ChangeLog
r292456 r292459 1 2022-04-06 Youenn Fablet <youenn@apple.com> 2 3 Implement ServiceWorkerWindowClient.navigate 4 https://bugs.webkit.org/show_bug.cgi?id=238738 5 6 Reviewed by Chris Dumez. 7 8 Introduce a routine to navigate a Document. 9 Send FrameIdentifier as part of ServiceWorkerClientData. 10 Implement ServiceWorkerWindowClient::navigate by sending IPC to network process. 11 12 Test: http/wpt/service-workers/navigate-iframes-window-client.https.html 13 14 * dom/Document.cpp: 15 * dom/Document.h: 16 * loader/FrameLoader.cpp: 17 * workers/service/ServiceWorkerClientData.cpp: 18 * workers/service/ServiceWorkerClientData.h: 19 * workers/service/ServiceWorkerWindowClient.cpp: 20 * workers/service/context/SWContextManager.h: 21 * workers/service/server/SWServer.cpp: 22 * workers/service/server/SWServer.h: 23 * workers/service/server/SWServerWorker.cpp: 24 * workers/service/server/SWServerWorker.h: 25 1 26 2022-04-06 Youenn Fablet <youenn@apple.com> 2 27 -
trunk/Source/WebCore/dom/Document.cpp
r292277 r292459 8415 8415 std::optional<FrameIdentifier> Document::frameID() const 8416 8416 { 8417 return m_frame ->loader().frameID();8417 return m_frame ? m_frame->loader().frameID() : std::nullopt; 8418 8418 } 8419 8419 … … 8781 8781 m_serviceWorkerConnection->registerServiceWorkerClient(topOrigin(), ServiceWorkerClientData::from(*this), controllingServiceWorkerRegistrationIdentifier, userAgent(url())); 8782 8782 } 8783 8784 void Document::navigateFromServiceWorker(const URL& url, CompletionHandler<void(bool)>&& callback) 8785 { 8786 if (activeDOMObjectsAreSuspended() || activeDOMObjectsAreStopped()) { 8787 callback(false); 8788 return; 8789 } 8790 eventLoop().queueTask(TaskSource::DOMManipulation, [weakThis = WeakPtr { *this }, url, callback = WTFMove(callback)]() mutable { 8791 auto* frame = weakThis ? weakThis->frame() : nullptr; 8792 if (!frame) { 8793 callback(false); 8794 return; 8795 } 8796 frame->navigationScheduler().scheduleLocationChange(*weakThis, weakThis->securityOrigin(), url, frame->loader().outgoingReferrer(), LockHistory::Yes, LockBackForwardList::No, [callback = WTFMove(callback)]() mutable { 8797 callback(true); 8798 }); 8799 }); 8800 } 8783 8801 #endif 8784 8802 -
trunk/Source/WebCore/dom/Document.h
r292400 r292459 1570 1570 void setServiceWorkerConnection(SWClientConnection*); 1571 1571 void updateServiceWorkerClientData(); 1572 WEBCORE_EXPORT void navigateFromServiceWorker(const URL&, CompletionHandler<void(bool)>&&); 1572 1573 #endif 1573 1574 -
trunk/Source/WebCore/workers/service/ServiceWorkerClientData.cpp
r292105 r292459 60 60 ServiceWorkerClientData ServiceWorkerClientData::isolatedCopy() const & 61 61 { 62 return { identifier, type, frameType, url.isolatedCopy(), pageIdentifier, lastNavigationWasAppInitiated, isVisible, isFocused, focusOrder, crossThreadCopy(ancestorOrigins) };62 return { identifier, type, frameType, url.isolatedCopy(), pageIdentifier, frameIdentifier, lastNavigationWasAppInitiated, isVisible, isFocused, focusOrder, crossThreadCopy(ancestorOrigins) }; 63 63 } 64 64 65 65 ServiceWorkerClientData ServiceWorkerClientData::isolatedCopy() && 66 66 { 67 return { identifier, type, frameType, WTFMove(url).isolatedCopy(), pageIdentifier, lastNavigationWasAppInitiated, isVisible, isFocused, focusOrder, crossThreadCopy(WTFMove(ancestorOrigins)) };67 return { identifier, type, frameType, WTFMove(url).isolatedCopy(), pageIdentifier, frameIdentifier, lastNavigationWasAppInitiated, isVisible, isFocused, focusOrder, crossThreadCopy(WTFMove(ancestorOrigins)) }; 68 68 } 69 69 … … 88 88 document.creationURL(), 89 89 document.pageID(), 90 document.frameID(), 90 91 lastNavigationWasAppInitiated, 91 92 !document.hidden(), -
trunk/Source/WebCore/workers/service/ServiceWorkerClientData.h
r292105 r292459 28 28 #if ENABLE(SERVICE_WORKER) 29 29 30 #include "FrameIdentifier.h" 30 31 #include "PageIdentifier.h" 31 32 #include "ProcessQualified.h" … … 50 51 URL url; 51 52 std::optional<PageIdentifier> pageIdentifier; 53 std::optional<FrameIdentifier> frameIdentifier; 52 54 LastNavigationWasAppInitiated lastNavigationWasAppInitiated; 53 55 bool isVisible { false }; … … 68 70 void ServiceWorkerClientData::encode(Encoder& encoder) const 69 71 { 70 encoder << identifier << type << frameType << url << pageIdentifier << lastNavigationWasAppInitiated << isVisible << isFocused << focusOrder << ancestorOrigins;72 encoder << identifier << type << frameType << url << pageIdentifier << frameIdentifier << lastNavigationWasAppInitiated << isVisible << isFocused << focusOrder << ancestorOrigins; 71 73 } 72 74 … … 99 101 return std::nullopt; 100 102 103 std::optional<std::optional<FrameIdentifier>> frameIdentifier; 104 decoder >> frameIdentifier; 105 if (!frameIdentifier) 106 return std::nullopt; 107 101 108 std::optional<LastNavigationWasAppInitiated> lastNavigationWasAppInitiated; 102 109 decoder >> lastNavigationWasAppInitiated; … … 124 131 return std::nullopt; 125 132 126 return { { WTFMove(*identifier), WTFMove(*type), WTFMove(*frameType), WTFMove(*url), WTFMove(*pageIdentifier), WTFMove(* lastNavigationWasAppInitiated), WTFMove(*isVisible), WTFMove(*isFocused), WTFMove(*focusOrder), WTFMove(*ancestorOrigins) } };133 return { { WTFMove(*identifier), WTFMove(*type), WTFMove(*frameType), WTFMove(*url), WTFMove(*pageIdentifier), WTFMove(*frameIdentifier), WTFMove(*lastNavigationWasAppInitiated), WTFMove(*isVisible), WTFMove(*isFocused), WTFMove(*focusOrder), WTFMove(*ancestorOrigins) } }; 127 134 } 128 135 -
trunk/Source/WebCore/workers/service/ServiceWorkerWindowClient.cpp
r291960 r292459 72 72 } 73 73 74 void ServiceWorkerWindowClient::navigate(ScriptExecutionContext& , const String& url, Ref<DeferredPromise>&& promise)74 void ServiceWorkerWindowClient::navigate(ScriptExecutionContext& context, const String& urlString, Ref<DeferredPromise>&& promise) 75 75 { 76 UNUSED_PARAM(url); 77 promise->reject(Exception { NotSupportedError, "windowClient.navigate() is not yet supported"_s }); 76 auto url = context.completeURL(urlString); 77 78 if (!url.isValid()) { 79 promise->reject(Exception { TypeError, makeString("URL string ", urlString, " cannot successfully be parsed") }); 80 return; 81 } 82 83 if (url.protocolIsAbout()) { 84 promise->reject(Exception { TypeError, makeString("ServiceWorkerClients.navigate() cannot be called with URL ", url.string()) }); 85 return; 86 } 87 88 // We implement step 4 (checking of client's active service worker) in network process as we cannot do it synchronously. 89 auto& serviceWorkerContext = downcast<ServiceWorkerGlobalScope>(context); 90 auto promiseIdentifier = serviceWorkerContext.clients().addPendingPromise(WTFMove(promise)); 91 callOnMainThread([clientIdentifier = identifier(), promiseIdentifier, serviceWorkerIdentifier = serviceWorkerContext.thread().identifier(), url = WTFMove(url).isolatedCopy()]() mutable { 92 SWContextManager::singleton().connection()->navigate(clientIdentifier, serviceWorkerIdentifier, url, [promiseIdentifier, serviceWorkerIdentifier](auto result) mutable { 93 SWContextManager::singleton().postTaskToServiceWorker(serviceWorkerIdentifier, [promiseIdentifier, result = crossThreadCopy(WTFMove(result))](auto& serviceWorkerContext) mutable { 94 auto promise = serviceWorkerContext.clients().takePendingPromise(promiseIdentifier); 95 if (!promise) 96 return; 97 98 if (result.hasException()) { 99 promise->reject(result.releaseException()); 100 return; 101 } 102 auto clientData = result.releaseReturnValue(); 103 if (!clientData) { 104 promise->resolveWithJSValue(JSC::jsNull()); 105 return; 106 } 107 #if ASSERT_ENABLED 108 auto originData = SecurityOriginData::fromURL(clientData->url); 109 ClientOrigin clientOrigin { originData, originData }; 110 #endif 111 ASSERT(serviceWorkerContext.clientOrigin() == clientOrigin); 112 promise->template resolve<IDLInterface<ServiceWorkerWindowClient>>(ServiceWorkerWindowClient::create(serviceWorkerContext, WTFMove(*clientData))); 113 }); 114 }); 115 }); 78 116 } 79 117 -
trunk/Source/WebCore/workers/service/context/SWContextManager.h
r292456 r292459 73 73 virtual void openWindow(ServiceWorkerIdentifier, const URL&, OpenWindowCallback&&) = 0; 74 74 75 using NavigateCallback = CompletionHandler<void(ExceptionOr<std::optional<WebCore::ServiceWorkerClientData>>&&)>; 76 virtual void navigate(ScriptExecutionContextIdentifier, ServiceWorkerIdentifier, const URL&, NavigateCallback&&) = 0; 77 75 78 virtual void didFailHeartBeatCheck(ServiceWorkerIdentifier) = 0; 76 79 virtual void setAsInspected(ServiceWorkerIdentifier, bool) = 0; -
trunk/Source/WebCore/workers/service/server/SWServer.cpp
r292456 r292459 1092 1092 } 1093 1093 1094 std::optional<ServiceWorkerRegistrationIdentifier> SWServer::clientIdentifierToControllingRegistration(ScriptExecutionContextIdentifier clientIdentifier) const 1095 { 1096 auto registrationIterator = m_clientToControllingRegistration.find(clientIdentifier); 1097 if (registrationIterator == m_clientToControllingRegistration.end()) 1098 return { }; 1099 return registrationIterator->value; 1100 } 1101 1094 1102 SWServer::ShouldDelayRemoval SWServer::removeContextConnectionIfPossible(const RegistrableDomain& domain) 1095 1103 { -
trunk/Source/WebCore/workers/service/server/SWServer.h
r292456 r292459 243 243 ShouldDelayRemoval removeContextConnectionIfPossible(const RegistrableDomain&); 244 244 245 std::optional<ServiceWorkerRegistrationIdentifier> clientIdentifierToControllingRegistration(ScriptExecutionContextIdentifier) const; 246 WEBCORE_EXPORT void forEachClientForOrigin(const ClientOrigin&, const Function<void(ServiceWorkerClientData&)>&); 247 245 248 private: 246 249 void validateRegistrationDomain(WebCore::RegistrableDomain, ServiceWorkerJobType, CompletionHandler<void(bool)>&&); … … 262 265 263 266 SWServerRegistration* registrationFromServiceWorkerIdentifier(ServiceWorkerIdentifier); 264 void forEachClientForOrigin(const ClientOrigin&, const Function<void(ServiceWorkerClientData&)>&);265 267 266 268 void performGetOriginsWithRegistrationsCallbacks(); -
trunk/Source/WebCore/workers/service/server/SWServerWorker.cpp
r292110 r292459 420 420 } 421 421 422 bool SWServerWorker::isClientActiveServiceWorker(ScriptExecutionContextIdentifier clientIdentifier) const 423 { 424 if (!m_server) 425 return false; 426 auto registrationIdentifier = m_server->clientIdentifierToControllingRegistration(clientIdentifier); 427 return registrationIdentifier == m_data.registrationIdentifier; 428 } 429 422 430 } // namespace WebCore 423 431 -
trunk/Source/WebCore/workers/service/server/SWServerWorker.h
r292110 r292459 142 142 bool shouldContinue() const { return !!m_functionalEventCounter || m_isInspected; } 143 143 144 WEBCORE_EXPORT bool isClientActiveServiceWorker(ScriptExecutionContextIdentifier) const; 145 144 146 private: 145 147 SWServerWorker(SWServer&, SWServerRegistration&, const URL&, const ScriptBuffer&, const CertificateInfo&, const ContentSecurityPolicyResponseHeaders&, const CrossOriginEmbedderPolicy&, String&& referrerPolicy, WorkerType, ServiceWorkerIdentifier, HashMap<URL, ServiceWorkerContextData::ImportedScript>&&); -
trunk/Source/WebKit/ChangeLog
r292458 r292459 1 2022-04-06 Youenn Fablet <youenn@apple.com> 2 3 Implement ServiceWorkerWindowClient.navigate 4 https://bugs.webkit.org/show_bug.cgi?id=238738 5 6 Reviewed by Chris Dumez. 7 8 When receiving a request to navigate a client, send message to UIProcess. 9 UIProcess locates the WebFrameProxy which will send an IPC message to the WebProcess to do navigation. 10 We keep track of the navigation within WebFrameProxy. 11 In case of process swapping, we make sure to transfer the WebFrameProxy callback. 12 In case of policy decision to stop loads, we resolve the promise with an empty client. 13 A follow-up patch may reject the promise once the expected behavior will be clarified. 14 15 * NetworkProcess/ServiceWorker/WebSWServerConnection.cpp: 16 * NetworkProcess/ServiceWorker/WebSWServerConnection.h: 17 * NetworkProcess/ServiceWorker/WebSWServerToContextConnection.cpp: 18 * NetworkProcess/ServiceWorker/WebSWServerToContextConnection.h: 19 * NetworkProcess/ServiceWorker/WebSWServerToContextConnection.messages.in: 20 * UIProcess/Network/NetworkProcessProxy.cpp: 21 * UIProcess/Network/NetworkProcessProxy.h: 22 * UIProcess/Network/NetworkProcessProxy.messages.in: 23 * UIProcess/ProvisionalPageProxy.cpp: 24 * UIProcess/WebFrameProxy.cpp: 25 * UIProcess/WebFrameProxy.h: 26 * UIProcess/WebPageProxy.cpp: 27 * WebProcess/Storage/WebSWContextManagerConnection.cpp: 28 * WebProcess/Storage/WebSWContextManagerConnection.h: 29 * WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp: 30 * WebProcess/WebPage/WebPage.cpp: 31 * WebProcess/WebPage/WebPage.h: 32 * WebProcess/WebPage/WebPage.messages.in: 33 1 34 2022-04-06 Zan Dobersek <zdobersek@igalia.com> 2 35 -
trunk/Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerConnection.cpp
r292105 r292459 165 165 } 166 166 167 void WebSWServerConnection::controlClient(const Vector<RefPtr<SecurityOrigin>>& frameAncestorOrigins, ScriptExecutionContextIdentifier clientIdentifier, SWServerRegistration& registration, const ResourceRequest& request) 168 { 167 void WebSWServerConnection::controlClient(const NetworkResourceLoadParameters& parameters, SWServerRegistration& registration, const ResourceRequest& request) 168 { 169 auto clientIdentifier = *parameters.options.clientIdentifier; 169 170 // As per step 12 of https://w3c.github.io/ServiceWorker/#on-fetch-request-algorithm, the active service worker should be controlling the document. 170 // We register a temporaryservice worker client using the identifier provided by DocumentLoader and notify DocumentLoader about it.171 // If notification is successful, DocumentLoader will unregister the temporary service worker client just after the document is created and registered as a client.171 // We register the service worker client using the identifier provided by DocumentLoader and notify DocumentLoader about it. 172 // If notification is successful, DocumentLoader is responsible to unregister the service worker client as needed. 172 173 sendWithAsyncReply(Messages::WebSWClientConnection::SetDocumentIsControlled { clientIdentifier, registration.data() }, [weakThis = WeakPtr { *this }, this, clientIdentifier](bool isSuccess) { 173 174 if (!weakThis || isSuccess) … … 176 177 }); 177 178 178 auto ancestorOrigins = map( frameAncestorOrigins, [](auto& origin) { return origin->toString(); });179 ServiceWorkerClientData data { clientIdentifier, ServiceWorkerClientType::Window, ServiceWorkerClientFrameType::None, request.url(), { }, request.isAppInitiated() ? WebCore::LastNavigationWasAppInitiated::Yes : WebCore::LastNavigationWasAppInitiated::No, false, false, 0, WTFMove(ancestorOrigins) };179 auto ancestorOrigins = map(parameters.frameAncestorOrigins, [](auto& origin) { return origin->toString(); }); 180 ServiceWorkerClientData data { clientIdentifier, ServiceWorkerClientType::Window, ServiceWorkerClientFrameType::None, request.url(), parameters.webPageID, parameters.webFrameID, request.isAppInitiated() ? WebCore::LastNavigationWasAppInitiated::Yes : WebCore::LastNavigationWasAppInitiated::No, false, false, 0, WTFMove(ancestorOrigins) }; 180 181 registerServiceWorkerClient(SecurityOriginData { registration.key().topOrigin() }, WTFMove(data), registration.identifier(), request.httpUserAgent()); 181 182 } … … 202 203 203 204 serviceWorkerRegistrationIdentifier = registration->identifier(); 204 controlClient(loader.parameters() .frameAncestorOrigins, *loader.parameters().options.clientIdentifier, *registration, request);205 controlClient(loader.parameters(), *registration, request); 205 206 loader.setResultingClientIdentifier(loader.parameters().options.clientIdentifier->toString()); 206 207 } else { -
trunk/Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerConnection.h
r292105 r292459 62 62 63 63 class NetworkProcess; 64 class NetworkResourceLoadParameters; 64 65 class NetworkResourceLoader; 65 66 class ServiceWorkerFetchTask; … … 84 85 void fetchTaskTimedOut(WebCore::ServiceWorkerIdentifier); 85 86 86 void focusServiceWorkerClient(WebCore::ScriptExecutionContextIdentifier, CompletionHandler<void(std::optional<WebCore::ServiceWorkerClientData>&&)>&&);87 88 87 private: 89 88 // Implement SWServer::Connection (Messages to the client WebProcess) … … 98 97 void setRegistrationUpdateViaCache(WebCore::ServiceWorkerRegistrationIdentifier, WebCore::ServiceWorkerUpdateViaCache) final; 99 98 void notifyClientsOfControllerChange(const HashSet<WebCore::ScriptExecutionContextIdentifier>& contextIdentifiers, const WebCore::ServiceWorkerData& newController); 99 void focusServiceWorkerClient(WebCore::ScriptExecutionContextIdentifier, CompletionHandler<void(std::optional<WebCore::ServiceWorkerClientData>&&)>&&) final; 100 100 101 101 void scheduleJobInServer(WebCore::ServiceWorkerJobData&&); … … 130 130 131 131 void postMessageToServiceWorker(WebCore::ServiceWorkerIdentifier destination, WebCore::MessageWithMessagePorts&&, const WebCore::ServiceWorkerOrClientIdentifier& source); 132 void controlClient(const Vector<RefPtr<WebCore::SecurityOrigin>>&, WebCore::ScriptExecutionContextIdentifier, WebCore::SWServerRegistration&, const WebCore::ResourceRequest&);132 void controlClient(const NetworkResourceLoadParameters&, WebCore::SWServerRegistration&, const WebCore::ResourceRequest&); 133 133 134 134 using ExceptionOrVoidCallback = CompletionHandler<void(std::optional<WebCore::ExceptionData>&&)>; -
trunk/Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerToContextConnection.cpp
r292456 r292459 274 274 } 275 275 276 void WebSWServerToContextConnection::navigate(ScriptExecutionContextIdentifier clientIdentifier, ServiceWorkerIdentifier serviceWorkerIdentifier, const URL& url, CompletionHandler<void(Expected<std::optional<ServiceWorkerClientData>, ExceptionData>&&)>&& callback) 277 { 278 auto* worker = SWServerWorker::existingWorkerForIdentifier(serviceWorkerIdentifier); 279 if (!worker) { 280 callback(makeUnexpected(ExceptionData { TypeError, "no service worker"_s })); 281 return; 282 } 283 284 if (!worker->isClientActiveServiceWorker(clientIdentifier)) { 285 callback(makeUnexpected(ExceptionData { TypeError, "service worker is not the client active service worker"_s })); 286 return; 287 } 288 289 auto data = worker->findClientByIdentifier(clientIdentifier); 290 if (!data || !data->pageIdentifier || !data->frameIdentifier) { 291 callback(makeUnexpected(ExceptionData { TypeError, "cannot navigate service worker client"_s })); 292 return; 293 } 294 295 auto frameIdentifier = *data->frameIdentifier; 296 m_connection.networkProcess().parentProcessConnection()->sendWithAsyncReply(Messages::NetworkProcessProxy::NavigateServiceWorkerClient { frameIdentifier, clientIdentifier, url }, [weakThis = WeakPtr { *this }, frameIdentifier, url, clientOrigin = worker->origin(), callback = WTFMove(callback)](auto pageIdentifier) mutable { 297 if (!weakThis || !weakThis->server()) { 298 callback(makeUnexpected(ExceptionData { TypeError, "service worker is gone"_s })); 299 return; 300 } 301 302 if (!pageIdentifier) { 303 callback(makeUnexpected(ExceptionData { TypeError, "navigate failed"_s })); 304 return; 305 } 306 307 std::optional<ServiceWorkerClientData> clientData; 308 weakThis->server()->forEachClientForOrigin(clientOrigin, [pageIdentifier, frameIdentifier, url, &clientData](auto& data) { 309 if (!clientData && data.pageIdentifier && *data.pageIdentifier == *pageIdentifier && data.frameIdentifier && *data.frameIdentifier == frameIdentifier && equalIgnoringFragmentIdentifier(data.url, url)) 310 clientData = data; 311 }); 312 callback(WTFMove(clientData)); 313 }, 0); 314 } 315 276 316 } // namespace WebKit 277 317 -
trunk/Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerToContextConnection.h
r292456 r292459 101 101 void close() final; 102 102 void focus(WebCore::ScriptExecutionContextIdentifier, CompletionHandler<void(std::optional<WebCore::ServiceWorkerClientData>&&)>&&); 103 void navigate(WebCore::ScriptExecutionContextIdentifier, WebCore::ServiceWorkerIdentifier, const URL&, CompletionHandler<void(Expected<std::optional<WebCore::ServiceWorkerClientData>, WebCore::ExceptionData>&&)>&&); 103 104 104 105 void connectionIsNoLongerNeeded() final; -
trunk/Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerToContextConnection.messages.in
r292456 r292459 37 37 Claim(WebCore::ServiceWorkerIdentifier serviceWorkerIdentifier) -> (std::optional<WebCore::ExceptionData> result) 38 38 Focus(WebCore::ScriptExecutionContextIdentifier serviceWorkerClientIdentifier) -> (std::optional<WebCore::ServiceWorkerClientData> result) 39 Navigate(WebCore::ScriptExecutionContextIdentifier clientIdentifier, WebCore::ServiceWorkerIdentifier serviceWorkerIdentifier, URL url) -> (Expected<std::optional<WebCore::ServiceWorkerClientData>, WebCore::ExceptionData> result) 39 40 SetScriptResource(WebCore::ServiceWorkerIdentifier identifier, URL scriptURL, WebCore::ServiceWorkerContextData::ImportedScript script) 40 41 PostMessageToServiceWorkerClient(WebCore::ScriptExecutionContextIdentifier destination, struct WebCore::MessageWithMessagePorts message, WebCore::ServiceWorkerIdentifier source, String sourceOrigin) -
trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.cpp
r292426 r292459 1806 1806 } 1807 1807 1808 void NetworkProcessProxy::navigateServiceWorkerClient(WebCore::FrameIdentifier frameIdentifier, WebCore::ScriptExecutionContextIdentifier documentIdentifier, const URL& url, CompletionHandler<void(std::optional<WebCore::PageIdentifier>)>&& callback) 1809 { 1810 auto* process = WebProcessProxy::processForIdentifier(documentIdentifier.processIdentifier()); 1811 auto* frame = process ? process->webFrame(frameIdentifier) : nullptr; 1812 if (!frame) { 1813 callback({ }); 1814 return; 1815 } 1816 frame->navigateServiceWorkerClient(documentIdentifier, url, WTFMove(callback)); 1817 } 1818 1808 1819 void NetworkProcessProxy::applicationDidEnterBackground() 1809 1820 { -
trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.h
r292110 r292459 305 305 void openWindowFromServiceWorker(PAL::SessionID, const String& urlString, const WebCore::SecurityOriginData& serviceWorkerOrigin, CompletionHandler<void(std::optional<WebCore::PageIdentifier>&&)>&&); 306 306 307 void navigateServiceWorkerClient(WebCore::FrameIdentifier, WebCore::ScriptExecutionContextIdentifier, const URL&, CompletionHandler<void(std::optional<WebCore::PageIdentifier>)>&&); 308 307 309 private: 308 310 explicit NetworkProcessProxy(); -
trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.messages.in
r291979 r292459 94 94 95 95 OpenWindowFromServiceWorker(PAL::SessionID sessionID, String urlString, struct WebCore::SecurityOriginData serviceWorkerOrigin) -> (std::optional<WebCore::PageIdentifier> newPage) 96 NavigateServiceWorkerClient(WebCore::FrameIdentifier frameIdentifier, WebCore::ScriptExecutionContextIdentifier documentIdentifier, URL url) -> (std::optional<WebCore::PageIdentifier> page) 96 97 } 97 98 -
trunk/Source/WebKit/UIProcess/ProvisionalPageProxy.cpp
r290563 r292459 239 239 // Restore the main frame's committed URL as some clients may rely on it until the next load is committed. 240 240 RefPtr previousMainFrame = m_page.mainFrame(); 241 if (previousMainFrame) 241 if (previousMainFrame) { 242 242 m_mainFrame->frameLoadState().setURL(previousMainFrame->url()); 243 previousMainFrame->transferNavigationCallbackToFrame(*m_mainFrame); 244 } 243 245 244 246 // Normally, notification of a server redirect comes from the WebContent process. -
trunk/Source/WebKit/UIProcess/WebFrameProxy.cpp
r284142 r292459 59 59 WebPasteboardProxy::singleton().didDestroyFrame(this); 60 60 #endif 61 62 if (m_navigateCallback) 63 m_navigateCallback({ }); 61 64 } 62 65 … … 69 72 m_activeListener = nullptr; 70 73 } 74 75 if (m_navigateCallback) 76 m_navigateCallback({ }); 71 77 } 72 78 … … 79 85 } 80 86 87 std::optional<PageIdentifier> WebFrameProxy::pageIdentifier() const 88 { 89 if (!m_page) 90 return { }; 91 return m_page->webPageID(); 92 } 93 94 void WebFrameProxy::navigateServiceWorkerClient(WebCore::ScriptExecutionContextIdentifier documentIdentifier, const URL& url, CompletionHandler<void(std::optional<PageIdentifier>)>&& callback) 95 { 96 if (!m_page) { 97 callback({ }); 98 return; 99 } 100 101 m_page->sendWithAsyncReply(Messages::WebPage::NavigateServiceWorkerClient { documentIdentifier, url }, [this, protectedThis = Ref { *this }, url, callback = WTFMove(callback)](bool result) mutable { 102 if (!result) { 103 callback({ }); 104 return; 105 } 106 107 if (!m_activeListener) { 108 callback(pageIdentifier()); 109 return; 110 } 111 112 if (m_navigateCallback) 113 m_navigateCallback({ }); 114 115 m_navigateCallback = WTFMove(callback); 116 }); 117 } 118 81 119 void WebFrameProxy::loadURL(const URL& url, const String& referrer) 82 120 { … … 96 134 } 97 135 98 void WebFrameProxy::stopLoading() const136 void WebFrameProxy::stopLoading() 99 137 { 100 138 if (!m_page) … … 105 143 106 144 m_page->send(Messages::WebPage::StopLoadingFrame(m_frameID)); 145 146 if (m_navigateCallback) 147 m_navigateCallback({ }); 107 148 } 108 149 … … 161 202 { 162 203 m_frameLoadState.didFailProvisionalLoad(); 204 205 if (m_navigateCallback) 206 m_navigateCallback({ }); 163 207 } 164 208 … … 176 220 { 177 221 m_frameLoadState.didFinishLoad(); 222 223 if (m_navigateCallback) 224 m_navigateCallback(pageIdentifier()); 178 225 } 179 226 … … 181 228 { 182 229 m_frameLoadState.didFailLoad(); 230 231 if (m_navigateCallback) 232 m_navigateCallback({ }); 183 233 } 184 234 … … 198 248 m_activeListener->ignore(); 199 249 m_activeListener = WebFramePolicyListenerProxy::create([this, protectedThis = Ref { *this }, completionHandler = WTFMove(completionHandler)] (PolicyAction action, API::WebsitePolicies* policies, ProcessSwapRequestedByClient processSwapRequestedByClient, RefPtr<SafeBrowsingWarning>&& safeBrowsingWarning, std::optional<NavigatingToAppBoundDomain> isNavigatingToAppBoundDomain) mutable { 250 if (action != PolicyAction::Use && m_navigateCallback) 251 m_navigateCallback(pageIdentifier()); 252 200 253 completionHandler(action, policies, processSwapRequestedByClient, WTFMove(safeBrowsingWarning), isNavigatingToAppBoundDomain); 201 254 m_activeListener = nullptr; -
trunk/Source/WebKit/UIProcess/WebFrameProxy.h
r282889 r292459 78 78 FrameLoadState& frameLoadState() { return m_frameLoadState; } 79 79 80 void navigateServiceWorkerClient(WebCore::ScriptExecutionContextIdentifier, const URL&, CompletionHandler<void(std::optional<WebCore::PageIdentifier>)>&&); 81 80 82 void loadURL(const URL&, const String& referrer = String()); 81 83 // Sub frames only. For main frames, use WebPageProxy::loadData. 82 84 void loadData(const IPC::DataReference&, const String& MIMEType, const String& encodingName, const URL& baseURL); 83 void stopLoading() const;85 void stopLoading(); 84 86 85 87 const URL& url() const { return m_frameLoadState.url(); } … … 129 131 #endif 130 132 133 void transferNavigationCallbackToFrame(WebFrameProxy& frame) { frame.m_navigateCallback = WTFMove(m_navigateCallback); } 134 131 135 private: 132 136 WebFrameProxy(WebPageProxy&, WebCore::FrameIdentifier); 137 138 std::optional<WebCore::PageIdentifier> pageIdentifier() const; 133 139 134 140 WeakPtr<WebPageProxy> m_page; … … 145 151 WebCore::ContentFilterUnblockHandler m_contentFilterUnblockHandler; 146 152 #endif 153 CompletionHandler<void(std::optional<WebCore::PageIdentifier>)> m_navigateCallback; 147 154 }; 148 155 -
trunk/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.cpp
r292456 r292459 356 356 } 357 357 358 void WebSWContextManagerConnection::navigate(ScriptExecutionContextIdentifier clientIdentifier, ServiceWorkerIdentifier serviceWorkerIdentifier, const URL& url, NavigateCallback&& callback) 359 { 360 m_connectionToNetworkProcess->sendWithAsyncReply(Messages::WebSWServerToContextConnection::Navigate { clientIdentifier, serviceWorkerIdentifier, url }, [callback = WTFMove(callback)](auto&& result) mutable { 361 if (!result.has_value()) { 362 callback(WTFMove(result).error().toException()); 363 return; 364 } 365 callback(WTFMove(result).value()); 366 }); 367 } 368 358 369 void WebSWContextManagerConnection::focus(ScriptExecutionContextIdentifier clientIdentifier, CompletionHandler<void(std::optional<WebCore::ServiceWorkerClientData>&&)>&& callback) 359 370 { -
trunk/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.h
r292456 r292459 83 83 void claim(WebCore::ServiceWorkerIdentifier, CompletionHandler<void(WebCore::ExceptionOr<void>&&)>&&) final; 84 84 void focus(WebCore::ScriptExecutionContextIdentifier, CompletionHandler<void(std::optional<WebCore::ServiceWorkerClientData>&&)>&&) final; 85 void navigate(WebCore::ScriptExecutionContextIdentifier, WebCore::ServiceWorkerIdentifier, const URL&, NavigateCallback&&) final; 85 86 void skipWaiting(WebCore::ServiceWorkerIdentifier, CompletionHandler<void()>&&) final; 86 87 void setScriptResource(WebCore::ServiceWorkerIdentifier, const URL&, const WebCore::ServiceWorkerContextData::ImportedScript&) final; -
trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp
r292408 r292459 6440 6440 } 6441 6441 6442 void WebPage::navigateServiceWorkerClient(ScriptExecutionContextIdentifier documentIdentifier, const URL& url, CompletionHandler<void(bool)>&& callback) 6443 { 6444 #if ENABLE(SERVICE_WORKER) 6445 RefPtr document = Document::allDocumentsMap().get(documentIdentifier); 6446 if (!document) { 6447 callback(false); 6448 return; 6449 } 6450 document->navigateFromServiceWorker(url, WTFMove(callback)); 6451 #else 6452 UNUSED_PARAM(documentIdentifier); 6453 UNUSED_PARAM(url); 6454 callback(false); 6455 #endif 6456 } 6457 6442 6458 void WebPage::setAlwaysShowsHorizontalScroller(bool alwaysShowsHorizontalScroller) 6443 6459 { -
trunk/Source/WebKit/WebProcess/WebPage/WebPage.h
r292458 r292459 946 946 947 947 void interactionRegions(WebCore::FloatRect rectInContentCoordinates, CompletionHandler<void(Vector<WebCore::InteractionRegion>)>&&); 948 void navigateServiceWorkerClient(WebCore::ScriptExecutionContextIdentifier, const URL&, CompletionHandler<void(bool)>&&); 948 949 949 950 #if PLATFORM(COCOA) -
trunk/Source/WebKit/WebProcess/WebPage/WebPage.messages.in
r292264 r292459 684 684 685 685 InteractionRegions(WebCore::FloatRect rectInContentCoordinates) -> (Vector<WebCore::InteractionRegion> regions) 686 687 NavigateServiceWorkerClient(WebCore::ScriptExecutionContextIdentifier documentIdentifier, URL url) -> (bool result) 686 688 } -
trunk/Tools/ChangeLog
r292456 r292459 1 2022-04-06 Youenn Fablet <youenn@apple.com> 2 3 Implement ServiceWorkerWindowClient.navigate 4 https://bugs.webkit.org/show_bug.cgi?id=238738 5 6 Reviewed by Chris Dumez. 7 8 * TestWebKitAPI/Tests/WebKitCocoa/ServiceWorkerBasic.mm: 9 1 10 2022-04-06 Youenn Fablet <youenn@apple.com> 2 11 -
trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ServiceWorkerBasic.mm
r292456 r292459 3048 3048 TestWebKitAPI::Util::run(&done); 3049 3049 } 3050 3051 static constexpr auto ServiceWorkerWindowClientNavigateMain = 3052 "<div>test page</div>" 3053 "<script>" 3054 "let worker;" 3055 "async function registerServiceWorker() {" 3056 " try {" 3057 " const registration = await navigator.serviceWorker.register('/sw.js');" 3058 " if (registration.active) {" 3059 " worker = registration.active;" 3060 " alert('already active');" 3061 " return;" 3062 " }" 3063 " worker = registration.installing;" 3064 " worker.addEventListener('statechange', () => {" 3065 " if (worker.state == 'activated')" 3066 " alert('successfully registered');" 3067 " });" 3068 " } catch(e) {" 3069 " alert('Exception: ' + e);" 3070 " }" 3071 "}" 3072 "window.onload = registerServiceWorker;" 3073 "" 3074 "function navigateOtherClientToURL(url) {" 3075 " worker.postMessage({navigateOtherClientToURL: url});" 3076 " navigator.serviceWorker.onmessage = (event) => {" 3077 " alert(event.data);" 3078 " };" 3079 "}" 3080 "</script>"_s; 3081 3082 static constexpr auto ServiceWorkerWindowClientNavigateJS = 3083 "self.addEventListener('message', async (event) => {" 3084 " if (event.data && event.data.navigateOtherClientToURL) {" 3085 " let otherClient;" 3086 " let currentClients = await self.clients.matchAll();" 3087 " for (let client of currentClients) {" 3088 " if (client.id !== event.source.id)" 3089 " otherClient = client;" 3090 " }" 3091 " if (!otherClient) {" 3092 " event.source.postMessage('failed, no other client, client number = ' + currentClients.length);" 3093 " return;" 3094 " }" 3095 " await otherClient.navigate(event.data.navigateOtherClientToURL).then((client) => {" 3096 " event.source.postMessage(client ? 'client' : 'none');" 3097 " }, (e) => {" 3098 " event.source.postMessage('failed');" 3099 " });" 3100 " return;" 3101 " }" 3102 "});"_s; 3103 3104 3105 @interface ServiceWorkerPSONNavigationDelegate : NSObject <WKNavigationDelegatePrivate> { 3106 @public void (^decidePolicyForNavigationAction)(WKNavigationAction *, void (^)(WKNavigationActionPolicy)); 3107 @public void (^didStartProvisionalNavigationHandler)(); 3108 @public void (^didCommitNavigationHandler)(); 3109 } 3110 @end 3111 3112 @implementation ServiceWorkerPSONNavigationDelegate 3113 3114 - (instancetype) init 3115 { 3116 self = [super init]; 3117 return self; 3118 } 3119 3120 - (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler 3121 { 3122 decisionHandler(WKNavigationActionPolicyAllow); 3123 } 3124 3125 - (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler 3126 { 3127 decisionHandler(WKNavigationResponsePolicyAllow); 3128 } 3129 3130 @end 3131 3132 TEST(ServiceWorker, WindowClientNavigate) 3133 { 3134 [WKWebsiteDataStore _allowWebsiteDataRecordsForAllOrigins]; 3135 3136 // Start with a clean slate data store 3137 [[WKWebsiteDataStore defaultDataStore] removeDataOfTypes:[WKWebsiteDataStore allWebsiteDataTypes] modifiedSince:[NSDate distantPast] completionHandler:^() { 3138 done = true; 3139 }]; 3140 TestWebKitAPI::Util::run(&done); 3141 done = false; 3142 3143 auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]); 3144 for (_WKExperimentalFeature *feature in [WKPreferences _experimentalFeatures]) { 3145 if ([feature.key isEqualToString:@"CrossOriginOpenerPolicyEnabled"]) 3146 [[configuration preferences] _setEnabled:YES forExperimentalFeature:feature]; 3147 else if ([feature.key isEqualToString:@"CrossOriginEmbedderPolicyEnabled"]) 3148 [[configuration preferences] _setEnabled:YES forExperimentalFeature:feature]; 3149 } 3150 3151 auto webView1 = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 300, 300) configuration:configuration.get() addToWindow:YES]); 3152 auto webView2 = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 300, 300) configuration:configuration.get() addToWindow:YES]); 3153 3154 TestWebKitAPI::HTTPServer server({ 3155 { "/"_s, { ServiceWorkerWindowClientNavigateMain } }, 3156 { "/?test"_s, { ServiceWorkerWindowClientNavigateMain } }, 3157 { "/?swap"_s, { {{ "Content-Type"_s, "application/html"_s }, { "Cross-Origin-Opener-Policy"_s, "same-origin"_s } }, ServiceWorkerWindowClientNavigateMain } }, 3158 { "/sw.js"_s, { {{ "Content-Type"_s, "application/javascript"_s }}, ServiceWorkerWindowClientNavigateJS } } 3159 }, TestWebKitAPI::HTTPServer::Protocol::Http, nullptr, nullptr, 8091); 3160 3161 [webView1 loadRequest:server.request()]; 3162 EXPECT_WK_STREQ([webView1 _test_waitForAlert], "successfully registered"); 3163 [webView2 loadRequest:server.request()]; 3164 EXPECT_WK_STREQ([webView2 _test_waitForAlert], "already active"); 3165 3166 auto navigationDelegate = adoptNS([[ServiceWorkerPSONNavigationDelegate alloc] init]); 3167 [webView2 setNavigationDelegate:navigationDelegate.get()]; 3168 3169 auto *baseURL = [[server.request() URL] absoluteString]; 3170 3171 [webView1 evaluateJavaScript:[NSString stringWithFormat:@"navigateOtherClientToURL('%@')", baseURL] completionHandler: nil]; 3172 EXPECT_WK_STREQ([webView1 _test_waitForAlert], "client"); 3173 3174 [webView1 evaluateJavaScript:[NSString stringWithFormat:@"navigateOtherClientToURL('%@#test')", baseURL] completionHandler: nil]; 3175 EXPECT_WK_STREQ([webView1 _test_waitForAlert], "client"); 3176 3177 [webView1 evaluateJavaScript:[NSString stringWithFormat:@"navigateOtherClientToURL('%@?test')", baseURL] completionHandler: nil]; 3178 EXPECT_WK_STREQ([webView1 _test_waitForAlert], "client"); 3179 3180 [webView1 evaluateJavaScript:[NSString stringWithFormat:@"navigateOtherClientToURL('%@?swap')", baseURL] completionHandler: nil]; 3181 EXPECT_WK_STREQ([webView1 _test_waitForAlert], "client"); 3182 } 3183 3184 TEST(ServiceWorker, WindowClientNavigateCrossOrigin) 3185 { 3186 [WKWebsiteDataStore _allowWebsiteDataRecordsForAllOrigins]; 3187 3188 // Start with a clean slate data store 3189 [[WKWebsiteDataStore defaultDataStore] removeDataOfTypes:[WKWebsiteDataStore allWebsiteDataTypes] modifiedSince:[NSDate distantPast] completionHandler:^() { 3190 done = true; 3191 }]; 3192 TestWebKitAPI::Util::run(&done); 3193 done = false; 3194 3195 auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]); 3196 3197 auto webView1 = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 300, 300) configuration:configuration.get() addToWindow:YES]); 3198 auto webView2 = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 300, 300) configuration:configuration.get() addToWindow:YES]); 3199 3200 TestWebKitAPI::HTTPServer server1({ 3201 { "/"_s, { ServiceWorkerWindowClientNavigateMain } }, 3202 { "/?test"_s, { ServiceWorkerWindowClientNavigateMain } }, 3203 { "/?swap"_s, { {{ "Content-Type"_s, "application/html"_s }, { "Cross-Origin-Opener-Policy"_s, "same-origin"_s } }, ServiceWorkerWindowClientNavigateMain } }, 3204 { "/sw.js"_s, { {{ "Content-Type"_s, "application/javascript"_s }}, ServiceWorkerWindowClientNavigateJS } } 3205 }, TestWebKitAPI::HTTPServer::Protocol::Http, nullptr, nullptr, 8091); 3206 3207 TestWebKitAPI::HTTPServer server2({ 3208 { "/"_s, { ServiceWorkerWindowClientNavigateMain } }, 3209 { "/sw.js"_s, { {{ "Content-Type"_s, "application/javascript"_s }}, ServiceWorkerWindowClientNavigateJS } } 3210 }, TestWebKitAPI::HTTPServer::Protocol::Http, nullptr, nullptr, 9091); 3211 3212 [webView1 loadRequest:server1.request()]; 3213 EXPECT_WK_STREQ([webView1 _test_waitForAlert], "successfully registered"); 3214 [webView2 loadRequest:server1.request()]; 3215 EXPECT_WK_STREQ([webView2 _test_waitForAlert], "already active"); 3216 [webView1 evaluateJavaScript:[NSString stringWithFormat:@"navigateOtherClientToURL('%@')", [[server2.request() URL] absoluteString]] completionHandler: nil]; 3217 EXPECT_WK_STREQ([webView1 _test_waitForAlert], "none"); 3218 }
Note: See TracChangeset
for help on using the changeset viewer.