var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; import { LitElement } from "lit"; import { customElement, property } from "lit/decorators.js"; import { ConsoleRuntimeProvider } from "./sandbox/ConsoleRuntimeProvider.js"; import { RuntimeMessageBridge } from "./sandbox/RuntimeMessageBridge.js"; import { RUNTIME_MESSAGE_ROUTER } from "./sandbox/RuntimeMessageRouter.js"; /** * Escape HTML special sequences in code to prevent premature tag closure * @param code Code that will be injected into in user code to prevent premature tag closure const escapedUserCode = escapeScriptContent(userCode); return `
${runtime} `; } } /** * Generate runtime script from providers * @param sandboxId Unique sandbox ID * @param providers Runtime providers * @param isStandalone If true, skip runtime bridge and navigation interceptor (for standalone downloads) */ getRuntimeScript(sandboxId, providers = [], isStandalone = false) { // Collect all data from providers const allData = {}; for (const provider of providers) { Object.assign(allData, provider.getData()); } // Generate bridge code (skip if standalone) const bridgeCode = isStandalone ? "" : RuntimeMessageBridge.generateBridgeCode({ context: "sandbox-iframe", sandboxId, }); // Collect all runtime functions - pass sandboxId as string literal const runtimeFunctions = []; for (const provider of providers) { runtimeFunctions.push(`(${provider.getRuntime().toString()})(${JSON.stringify(sandboxId)});`); } // Build script with HTML escaping // Escape to prevent premature tag closure in HTML parser const dataInjection = Object.entries(allData) .map(([key, value]) => { const jsonStr = JSON.stringify(value).replace(/<\/script/gi, "<\\/script"); return `window.${key} = ${jsonStr};`; }) .join("\n"); // TODO the font-size is needed, as chrome seems to inject a stylesheet into iframes // found in an extension context like sidepanel, settin body { font-size: 75% }. It's // definitely not our code doing that. // See https://stackoverflow.com/questions/71480433/chrome-is-injecting-some-stylesheet-in-popup-ui-which-reduces-the-font-size-to-7 // Navigation interceptor (only if NOT standalone) const navigationInterceptor = isStandalone ? "" : ` // Navigation interceptor: prevent all navigation and open externally (function() { // Intercept link clicks document.addEventListener('click', function(e) { const link = e.target.closest('a'); if (link && link.href) { // Check if it's an external link (not javascript: or #hash) if (link.href.startsWith('http://') || link.href.startsWith('https://')) { e.preventDefault(); e.stopPropagation(); window.parent.postMessage({ type: 'open-external-url', url: link.href }, '*'); } } }, true); // Intercept form submissions document.addEventListener('submit', function(e) { const form = e.target; if (form && form.action) { e.preventDefault(); e.stopPropagation(); window.parent.postMessage({ type: 'open-external-url', url: form.action }, '*'); } }, true); // Prevent window.location changes (only if not already redefined) try { const originalLocation = window.location; Object.defineProperty(window, 'location', { get: function() { return originalLocation; }, set: function(url) { window.parent.postMessage({ type: 'open-external-url', url: url.toString() }, '*'); } }); } catch (e) { // Already defined, skip } })(); `; return ` `; } }; __decorate([ property({ attribute: false }) ], SandboxIframe.prototype, "sandboxUrlProvider", void 0); SandboxIframe = __decorate([ customElement("sandbox-iframe") ], SandboxIframe); export { SandboxIframe }; //# sourceMappingURL=SandboxedIframe.js.map