| // This worker attempts to call respondWith() asynchronously after the |
| // fetch event handler finished. It reports back to the test whether |
| // an exception was thrown. |
| |
| // These get reset at the start of a test case. |
| let reportResult; |
| |
| // The test page sends a message to tell us that a new test case is starting. |
| // We expect a fetch event after this. |
| self.addEventListener('message', (event) => { |
| // Ensure tests run mutually exclusive. |
| if (reportResult) { |
| event.source.postMessage('testAlreadyRunning'); |
| return; |
| } |
| |
| const resultPromise = new Promise((resolve) => { |
| reportResult = resolve; |
| // Tell the client that everything is initialized and that it's safe to |
| // proceed with the test without relying on the order of events (which some |
| // browsers like Chrome may not guarantee). |
| event.source.postMessage('messageHandlerInitialized'); |
| }); |
| |
| // Keep the worker alive until the test case finishes, and report |
| // back the result to the test page. |
| event.waitUntil(resultPromise.then(result => { |
| reportResult = null; |
| event.source.postMessage(result); |
| })); |
| }); |
| |
| // Calls respondWith() and reports back whether an exception occurred. |
| function tryRespondWith(event) { |
| try { |
| event.respondWith(new Response()); |
| reportResult({didThrow: false}); |
| } catch (error) { |
| reportResult({didThrow: true, error: error.name}); |
| } |
| } |
| |
| function respondWithInTask(event) { |
| setTimeout(() => { |
| tryRespondWith(event); |
| }, 0); |
| } |
| |
| function respondWithInMicrotask(event) { |
| Promise.resolve().then(() => { |
| tryRespondWith(event); |
| }); |
| } |
| |
| self.addEventListener('fetch', function(event) { |
| const path = new URL(event.request.url).pathname; |
| const test = path.substring(path.lastIndexOf('/') + 1); |
| |
| // If this is a test case, try respondWith() and report back to the test page |
| // the result. |
| if (test == 'respondWith-in-task') { |
| respondWithInTask(event); |
| } else if (test == 'respondWith-in-microtask') { |
| respondWithInMicrotask(event); |
| } |
| }); |