| <!DOCTYPE html> |
| <html> |
| <script> |
| |
| const fetchURL = new URL('sample.txt', window.location).href; |
| |
| const frameControllerText = |
| `<script> |
| let t = null; |
| try { |
| if (navigator.serviceWorker.controller) { |
| t = navigator.serviceWorker.controller.scriptURL; |
| } |
| } catch (e) { |
| t = e.message; |
| } finally { |
| parent.postMessage({ data: t }, '*'); |
| } |
| </` + `script>`; |
| |
| const frameFetchText = |
| `<script> |
| fetch('${fetchURL}', { mode: 'no-cors' }).then(response => { |
| return response.text(); |
| }).then(text => { |
| parent.postMessage({ data: text }, '*'); |
| }).catch(e => { |
| parent.postMessage({ data: e.message }, '*'); |
| }); |
| </` + `script>`; |
| |
| const workerControllerText = |
| `let t = navigator.serviceWorker.controller |
| ? navigator.serviceWorker.controller.scriptURL |
| : null; |
| self.postMessage(t);`; |
| |
| const workerFetchText = |
| `fetch('${fetchURL}', { mode: 'no-cors' }).then(response => { |
| return response.text(); |
| }).then(text => { |
| self.postMessage(text); |
| }).catch(e => { |
| self.postMessage(e.message); |
| });` |
| |
| function getChildText(opts) { |
| if (opts.child === 'iframe') { |
| if (opts.check === 'controller') { |
| return frameControllerText; |
| } |
| |
| if (opts.check === 'fetch') { |
| return frameFetchText; |
| } |
| |
| throw('unexpected feature to check: ' + opts.check); |
| } |
| |
| if (opts.child === 'worker') { |
| if (opts.check === 'controller') { |
| return workerControllerText; |
| } |
| |
| if (opts.check === 'fetch') { |
| return workerFetchText; |
| } |
| |
| throw('unexpected feature to check: ' + opts.check); |
| } |
| |
| throw('unexpected child type ' + opts.child); |
| } |
| |
| function makeURL(opts) { |
| let mimetype = opts.child === 'iframe' ? 'text/html' |
| : 'text/javascript'; |
| |
| if (opts.scheme === 'blob') { |
| let blob = new Blob([getChildText(opts)], { type: mimetype }); |
| return URL.createObjectURL(blob); |
| } |
| |
| if (opts.scheme === 'data') { |
| return `data:${mimetype},${getChildText(opts)}`; |
| } |
| |
| throw(`unexpected URL scheme ${opts.scheme}`); |
| } |
| |
| function testWorkerChild(url) { |
| let w = new Worker(url); |
| return new Promise((resolve, reject) => { |
| w.onmessage = resolve; |
| w.onerror = evt => { |
| reject(evt.message); |
| } |
| }); |
| } |
| |
| function testIframeChild(url) { |
| let frame = document.createElement('iframe'); |
| frame.src = url; |
| document.body.appendChild(frame); |
| |
| return new Promise(resolve => { |
| addEventListener('message', evt => { |
| resolve(evt.data); |
| }, { once: true }); |
| }); |
| } |
| |
| function testURL(opts, url) { |
| if (opts.child === 'worker') { |
| return testWorkerChild(url); |
| } |
| |
| if (opts.child === 'iframe') { |
| return testIframeChild(url); |
| } |
| |
| throw(`unexpected child type ${opts.child}`); |
| } |
| |
| function checkChildController(opts) { |
| let url = makeURL(opts); |
| return testURL(opts, url); |
| } |
| </script> |
| </html> |