test-helper-iframe.js (1798B)
1 // Handle errors around fetching, parsing and registering import maps. 2 window.onScriptError = event => { 3 window.registrationResult = {type: 'FetchError', error: event.error}; 4 return false; 5 }; 6 window.windowErrorHandler = event => { 7 window.registrationResult = {type: 'ParseError', error: event.error}; 8 return false; 9 }; 10 window.addEventListener('error', window.windowErrorHandler); 11 12 // Handle specifier resolution requests from the parent frame. 13 // For failures, we post error names and messages instead of error 14 // objects themselves and re-create error objects later, to avoid 15 // issues around serializing error objects which is a quite new feature. 16 window.addEventListener('message', event => { 17 if (event.data.action !== 'resolve') { 18 parent.postMessage({ 19 type: 'Failure', 20 result: 'Error', 21 message: 'Invalid Action: ' + event.data.action}, '*'); 22 return; 23 } 24 25 // To respond to a resolution request, we: 26 // 1. Save the specifier to resolve into a global. 27 // 2. Update the document's base URL to the requested base URL. 28 // 3. Create a new inline script, parsed with that base URL, which 29 // resolves the saved specifier using import.meta.resolve(), and 30 // sents the result to the parent window. 31 window.specifierToResolve = event.data.specifier; 32 document.querySelector('base').href = event.data.baseURL; 33 34 const inlineScript = document.createElement('script'); 35 inlineScript.type = 'module'; 36 inlineScript.textContent = ` 37 try { 38 const result = import.meta.resolve(window.specifierToResolve); 39 parent.postMessage({type: 'ResolutionSuccess', result}, '*'); 40 } catch (e) { 41 parent.postMessage( 42 {type: 'Failure', result: e.name, message: e.message}, '*'); 43 } 44 `; 45 document.body.append(inlineScript); 46 });