From 7e0ee61c03114151abe76a8e321aa012b246259b Mon Sep 17 00:00:00 2001 From: Trish Ta Date: Fri, 6 Sep 2024 23:05:13 -0400 Subject: [PATCH] demo of iframe with contentWindow.postMessage --- examples/kitchen-sink/app/host.tsx | 10 +++++- examples/kitchen-sink/app/host/components.tsx | 31 ++++++++++++++++++- examples/kitchen-sink/app/remote/elements.ts | 24 +++++++++++++- .../app/remote/examples/vanilla.ts | 17 ++++++++++ examples/kitchen-sink/app/style.css | 1 - packages/core/source/connection.ts | 18 +++++++++++ .../core/source/elements/RemoteElement.ts | 6 ++++ .../source/elements/RemoteReceiverElement.ts | 1 + packages/core/source/elements/internals.ts | 15 +++++++++ packages/core/source/polyfill.ts | 5 +++ .../source/receivers/DOMRemoteReceiver.ts | 4 +++ .../core/source/receivers/RemoteReceiver.ts | 6 ++++ packages/core/source/types.ts | 6 ++++ packages/preact/source/host/component.tsx | 17 ++++++++-- .../signals/source/SignalRemoteReceiver.ts | 7 +++++ 15 files changed, 162 insertions(+), 6 deletions(-) diff --git a/examples/kitchen-sink/app/host.tsx b/examples/kitchen-sink/app/host.tsx index 5664b6d7..262da637 100644 --- a/examples/kitchen-sink/app/host.tsx +++ b/examples/kitchen-sink/app/host.tsx @@ -7,7 +7,14 @@ import { import {ThreadIframe, ThreadWebWorker} from '@quilted/threads'; import type {SandboxAPI} from './types.ts'; -import {Button, Modal, Stack, Text, ControlPanel} from './host/components.tsx'; +import { + Button, + Modal, + Stack, + Text, + ControlPanel, + Iframe, +} from './host/components.tsx'; import {createState} from './host/state.ts'; // We will put any remote elements we want to render in this root element. @@ -42,6 +49,7 @@ const components = new Map([ ['ui-button', createRemoteComponentRenderer(Button)], ['ui-stack', createRemoteComponentRenderer(Stack)], ['ui-modal', createRemoteComponentRenderer(Modal)], + ['ui-iframe', createRemoteComponentRenderer(Iframe)], // The `remote-fragment` element is a special element created by Remote DOM when // it needs an unstyled container for a list of elements. This is primarily used // to convert elements passed as a prop to React or Preact components into a slotted diff --git a/examples/kitchen-sink/app/host/components.tsx b/examples/kitchen-sink/app/host/components.tsx index b22f62f2..496c1e21 100644 --- a/examples/kitchen-sink/app/host/components.tsx +++ b/examples/kitchen-sink/app/host/components.tsx @@ -1,6 +1,6 @@ import {type ComponentChildren} from 'preact'; import {forwardRef} from 'preact/compat'; -import {useRef, useImperativeHandle} from 'preact/hooks'; +import {useRef, useImperativeHandle, useEffect} from 'preact/hooks'; import type {Signal} from '@preact/signals'; import type { @@ -233,3 +233,32 @@ function nanoId(size = 21) { } return id; } + +export function Iframe({src, onReady}: {src: string; onReady: any}) { + const iframe = useRef(null); + + useEffect(() => { + const iframeRef = iframe.current; + if (!iframeRef || !iframeRef.contentWindow) { + return; + } + iframeRef.addEventListener('message', (event) => { + const origin = new URL(src).origin; + iframeRef.contentWindow?.postMessage(event.data, origin); + }); + }, []); + + return ( +