diff --git a/packages/web/src/components/editor.tsx b/packages/web/src/components/editor.tsx index 7e5f82a5..8b67ed46 100644 --- a/packages/web/src/components/editor.tsx +++ b/packages/web/src/components/editor.tsx @@ -7,11 +7,12 @@ import { } from "@/settings.json"; import { javascript } from "@codemirror/lang-javascript"; import { python } from "@codemirror/lang-python"; -import { EditorState, Prec, Compartment, Extension } from "@codemirror/state"; +import { Compartment, EditorState, Extension, Prec } from "@codemirror/state"; import { EditorView, keymap, lineNumbers } from "@codemirror/view"; import { evalKeymap, flashField, remoteEvalFlash } from "@flok-editor/cm-eval"; import { tidal } from "@flok-editor/lang-tidal"; import type { Document } from "@flok-editor/session"; +import { highlightExtension } from "@strudel/codemirror"; import CodeMirror, { ReactCodeMirrorProps, ReactCodeMirrorRef, @@ -19,7 +20,6 @@ import CodeMirror, { import React, { useEffect, useState } from "react"; import { yCollab } from "y-codemirror.next"; import { UndoManager } from "yjs"; -import { highlightExtension } from '@strudel/codemirror'; const defaultLanguage = "javascript"; const langByTarget = langByTargetUntyped as { [lang: string]: string }; @@ -121,28 +121,25 @@ const flokSetup = ( ]; }; -export interface EditorProps extends ReactCodeMirrorProps { - document?: Document; -} - // Code example from: // https://codemirror.net/examples/config/#dynamic-configuration // Allows toggling of extensions based on string shortkey -// +// const toggleWith = (key: string, extension: Extension) => { - let comp = new Compartment; + let comp = new Compartment(); function toggle(view: EditorView) { let on = comp.get(view.state) == extension; view.dispatch({ - effects: comp.reconfigure(on ? [] : extension) - }) + effects: comp.reconfigure(on ? [] : extension), + }); return true; } - return [ - comp.of([]), - keymap.of([{key, run: toggle}]) - ] + return [comp.of([]), keymap.of([{ key, run: toggle }])]; +}; + +export interface EditorProps extends ReactCodeMirrorProps { + document?: Document; } export const Editor = React.forwardRef( @@ -175,10 +172,8 @@ export const Editor = React.forwardRef( languageExtension(), highlightExtension, readOnly ? EditorState.readOnly.of(true) : [], - // toggle linenumbers on/off - toggleWith('shift-ctrl-l', lineNumbers()), - // toggle linewrapping on/off - toggleWith('shift-ctrl-w', EditorView.lineWrapping) + toggleWith("shift-ctrl-l", lineNumbers()), // toggle linenumbers on/off + toggleWith("shift-ctrl-w", EditorView.lineWrapping), // toggle linewrapping on/off ]; // If it's read-only, put a div in front of the editor so that the user diff --git a/packages/web/src/components/web-target-iframe.tsx b/packages/web/src/components/web-target-iframe.tsx new file mode 100644 index 00000000..2341c25b --- /dev/null +++ b/packages/web/src/components/web-target-iframe.tsx @@ -0,0 +1,47 @@ +import { useQuery } from "@/hooks/use-query"; +import { EvalMessage, Session } from "@flok-editor/session"; +import { useEffect, useRef } from "react"; + +export interface WebTargetIframeProps { + target: string; + session: Session | null; +} + +export const WebTargetIframe = ({ target, session }: WebTargetIframeProps) => { + const ref = useRef(null); + + const query = useQuery(); + const noWebEval = query.get("noWebEval")?.split(",") || []; + + // Check if we should load the target + if (noWebEval.includes(target) || noWebEval.includes("*")) { + return null; + } + + // Handle evaluation messages from session + useEffect(() => { + if (!session || !ref.current) return; + + const handler = (msg: EvalMessage) => { + const payload = { + type: "eval", + body: msg, + }; + ref.current?.contentWindow?.postMessage(payload, "*"); + }; + + session.on(`eval:${target}`, handler); + + return () => { + session.off(`eval:${target}`, handler); + }; + }, [session, ref]); + + return ( +