UNPKG

@lynx-js/web-core

Version:

This is an internal experimental package, do not use

68 lines 3 kB
/* * Copyright (C) 2025 The Lynx Authors. All rights reserved. * Licensed under the Apache License Version 2.0 that can be found in the * LICENSE file in the root directory of this source tree. */ const existingScript = document.querySelector('script[nonce]'); const nonce = existingScript?.nonce || existingScript?.getAttribute('nonce'); /** * Creates a isolated JavaScript context for executing mts code. * This context has its own global variables and functions. */ export async function createIFrameRealm(parent) { const iframe = document.createElement('iframe'); const iframeReadyPromise = new Promise((resolve) => { const listener = (event) => { if (event.data === 'lynx:mtsready' && event.source === iframe.contentWindow) { resolve(); globalThis.removeEventListener('message', listener); } }; globalThis.addEventListener('message', listener); }); iframe.style.display = 'none'; iframe.srcdoc = '<!DOCTYPE html><html><head><script nonce="' + nonce + '">parent.postMessage("lynx:mtsready","*")</script></head><body style="display:none"></body></html>'; iframe.sandbox = 'allow-same-origin allow-scripts'; // Restrict capabilities for security iframe.loading = 'eager'; parent.appendChild(iframe); await iframeReadyPromise; const iframeWindow = iframe.contentWindow; const loadScript = async (url) => { const script = iframe.contentDocument.createElement('script'); script.fetchPriority = 'high'; script.defer = true; script.async = false; script.nonce = nonce || ''; iframe.contentDocument.head.appendChild(script); return new Promise(async (resolve, reject) => { script.onload = () => { const ret = iframeWindow?.module?.exports; iframeWindow.module = { exports: undefined }; resolve(ret); }; script.onerror = (err) => reject(new Error(`Failed to load script: ${url}`, { cause: err })); iframeWindow.module = { exports: undefined }; script.src = url; }); }; const loadScriptSync = (url) => { const xhr = new XMLHttpRequest(); xhr.open('GET', url, false); // Synchronous request xhr.send(null); if (xhr.status === 200) { const script = iframe.contentDocument.createElement('script'); script.textContent = xhr.responseText; iframeWindow.module = { exports: undefined }; iframe.contentDocument.head.appendChild(script); const ret = iframeWindow?.module?.exports; iframeWindow.module = { exports: undefined }; return ret; } else { throw new Error(`Failed to load script: ${url}`, { cause: xhr }); } }; return { globalWindow: iframeWindow, loadScript, loadScriptSync }; } //# sourceMappingURL=createIFrameRealm.js.map