summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/service-workers/service-worker/resources/about-blank-replacement-worker.js
diff options
context:
space:
mode:
Diffstat (limited to 'testing/web-platform/tests/service-workers/service-worker/resources/about-blank-replacement-worker.js')
-rw-r--r--testing/web-platform/tests/service-workers/service-worker/resources/about-blank-replacement-worker.js95
1 files changed, 95 insertions, 0 deletions
diff --git a/testing/web-platform/tests/service-workers/service-worker/resources/about-blank-replacement-worker.js b/testing/web-platform/tests/service-workers/service-worker/resources/about-blank-replacement-worker.js
new file mode 100644
index 0000000000..f43598e41c
--- /dev/null
+++ b/testing/web-platform/tests/service-workers/service-worker/resources/about-blank-replacement-worker.js
@@ -0,0 +1,95 @@
+// Helper routine to find a client that matches a particular URL. Note, we
+// require that Client to be controlled to avoid false matches with other
+// about:blank windows the browser might have. The initial about:blank should
+// inherit the controller from its parent.
+async function getClientByURL(url) {
+ let list = await clients.matchAll();
+ return list.find(client => client.url === url);
+}
+
+// Helper routine to perform a ping-pong with the given target client. We
+// expect the Client to respond with its location URL.
+async function pingPong(target) {
+ function waitForPong() {
+ return new Promise(resolve => {
+ self.addEventListener('message', function onMessage(evt) {
+ if (evt.data.type === 'PONG') {
+ resolve(evt.data.location);
+ }
+ });
+ });
+ }
+
+ target.postMessage({ type: 'PING' })
+ return await waitForPong(target);
+}
+
+addEventListener('fetch', async evt => {
+ let url = new URL(evt.request.url);
+ if (!url.searchParams.get('nested')) {
+ return;
+ }
+
+ evt.respondWith(async function() {
+ // Find the initial about:blank document.
+ const client = await getClientByURL('about:blank');
+ if (!client) {
+ return new Response('failure: could not find about:blank client');
+ }
+
+ // If the nested frame is configured to support a ping-pong, then
+ // ping it now to verify its message listener exists. We also
+ // verify the Client's idea of its own location URL while we are doing
+ // this.
+ if (url.searchParams.get('ping')) {
+ const loc = await pingPong(client);
+ if (loc !== 'about:blank') {
+ return new Response(`failure: got location {$loc}, expected about:blank`);
+ }
+ }
+
+ // Finally, allow the nested frame to complete loading. We place the
+ // Client ID we found for the initial about:blank in the body.
+ return new Response(client.id);
+ }());
+});
+
+addEventListener('message', evt => {
+ if (evt.data.type !== 'GET_CLIENT_ID') {
+ return;
+ }
+
+ evt.waitUntil(async function() {
+ let url = new URL(evt.data.url);
+
+ // Find the given Client by its URL.
+ let client = await getClientByURL(evt.data.url);
+ if (!client) {
+ evt.source.postMessage({
+ type: 'GET_CLIENT_ID',
+ result: `failure: could not find ${evt.data.url} client`
+ });
+ return;
+ }
+
+ // If the Client supports a ping-pong, then do it now to verify
+ // the message listener exists and its location matches the
+ // Client object.
+ if (url.searchParams.get('ping')) {
+ let loc = await pingPong(client);
+ if (loc !== evt.data.url) {
+ evt.source.postMessage({
+ type: 'GET_CLIENT_ID',
+ result: `failure: got location ${loc}, expected ${evt.data.url}`
+ });
+ return;
+ }
+ }
+
+ // Finally, send the client ID back.
+ evt.source.postMessage({
+ type: 'GET_CLIENT_ID',
+ result: client.id
+ });
+ }());
+});