Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions apps/mesh/src/web/components/deck/use-deck-editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,9 @@ export function useDeckEditor(args: {
};

const postToIframe = (msg: DeckHostMessage) => {
// Deck iframes are sandboxed (opaque origin) so we must use "*" here —
// a sandboxed iframe's origin is "null" and no targetOrigin string can
// match it. The iframe's own message listener validates e.source instead.
machine.iframe?.contentWindow?.postMessage(msg, "*");
};

Expand Down
18 changes: 14 additions & 4 deletions apps/mesh/src/web/components/sandbox/preview/preview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -378,34 +378,44 @@ export function PreviewContent() {
};
}, [sectionsOpen]);

const getPreviewOrigin = (): string => {
try {
return previewUrl
? new URL(previewUrl, window.location.href).origin
: window.location.origin;
} catch {
return window.location.origin;
}
};

const injectVisualEditor = () => {
const win = previewIframeRef.current?.contentWindow;
if (!win) return;
win.postMessage(
{ type: "visual-editor::activate", script: VISUAL_EDITOR_SCRIPT },
"*",
getPreviewOrigin(),
);
};

const deactivateVisualEditor = () => {
const win = previewIframeRef.current?.contentWindow;
if (!win) return;
win.postMessage({ type: "visual-editor::deactivate" }, "*");
win.postMessage({ type: "visual-editor::deactivate" }, getPreviewOrigin());
};

const injectCmsEditor = () => {
const win = previewIframeRef.current?.contentWindow;
if (!win) return;
win.postMessage(
{ type: "visual-editor::activate", script: CMS_EDITOR_SCRIPT },
"*",
getPreviewOrigin(),
);
};

const deactivateCmsEditor = () => {
const win = previewIframeRef.current?.contentWindow;
if (!win) return;
win.postMessage({ type: "cms-editor::deactivate" }, "*");
win.postMessage({ type: "cms-editor::deactivate" }, getPreviewOrigin());
};

const handleViewModeChange = (mode: PreviewViewMode) => {
Expand Down
2 changes: 1 addition & 1 deletion packages/sandbox/shared.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,4 @@ export {
* Must run before the framework builds its WS — spliced after `<head>` by
* `injectBootstrap` in image/daemon/proxy.mjs.
*/
export const IFRAME_BOOTSTRAP_SCRIPT = `<script>(function(){try{var W=window.WebSocket;if(W){var m=location.pathname.match(/^(\\/api\\/sandbox\\/[^\\/]+(?:\\/thread\\/[^\\/]+)?\\/preview(?:\\/\\d+)?)/);var p=m?m[1]:"";function r(u){try{var x=new URL(String(u),location.href);var lb=x.hostname==="localhost"||x.hostname==="127.0.0.1"||x.hostname==="0.0.0.0";var pm=x.hostname===location.hostname&&x.port!==location.port&&x.port!=="";if(!lb&&!pm)return String(u);x.protocol=location.protocol==="https:"?"wss:":"ws:";x.host=location.host;if(p&&!x.pathname.startsWith(p))x.pathname=p+x.pathname;return x.toString();}catch(_){return String(u);}}class P extends W{constructor(u,pr){super(r(u),pr);}}window.WebSocket=P;}}catch(_){}window.addEventListener("message",function(e){if(e.data&&e.data.type==="visual-editor::activate"&&e.data.script){try{new Function(e.data.script)();}catch(err){console.error("[visual-editor] injection failed",err);}}});})();</script>`;
export const IFRAME_BOOTSTRAP_SCRIPT = `<script>(function(){try{var W=window.WebSocket;if(W){var m=location.pathname.match(/^(\\/api\\/sandbox\\/[^\\/]+(?:\\/thread\\/[^\\/]+)?\\/preview(?:\\/\\d+)?)/);var p=m?m[1]:"";function r(u){try{var x=new URL(String(u),location.href);var lb=x.hostname==="localhost"||x.hostname==="127.0.0.1"||x.hostname==="0.0.0.0";var pm=x.hostname===location.hostname&&x.port!==location.port&&x.port!=="";if(!lb&&!pm)return String(u);x.protocol=location.protocol==="https:"?"wss:":"ws:";x.host=location.host;if(p&&!x.pathname.startsWith(p))x.pathname=p+x.pathname;return x.toString();}catch(_){return String(u);}}class P extends W{constructor(u,pr){super(r(u),pr);}}window.WebSocket=P;}}catch(_){}var _po;try{_po=document.referrer?new URL(document.referrer).origin:location.origin;}catch(_){_po=location.origin;}window.addEventListener("message",function(e){if(e.origin!==_po&&e.origin!==location.origin)return;if(e.data&&e.data.type==="visual-editor::activate"&&e.data.script){try{new Function(e.data.script)();}catch(err){console.error("[visual-editor] injection failed",err);}}});})();</script>`;
Loading