From 40e8444c0e9a7b27d6ebbf99b38d21ca3ccef68f Mon Sep 17 00:00:00 2001 From: iajhff <167518214+iajhff@users.noreply.github.com> Date: Sun, 7 Dec 2025 19:39:50 -0800 Subject: [PATCH] fix: Sync CodeMirror when loading examples --- Cargo.toml | 5 ++ src/components/program_window/program_tab.rs | 73 +++++++++++++++++++- 2 files changed, 75 insertions(+), 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 05963ec..e52601f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,10 +20,15 @@ leptos_router = { version = "0.6.15", features = ["csr"] } console_error_panic_hook = "0.1.7" hex-conservative = "0.2.1" js-sys = "0.3.70" +wasm-bindgen = "0.2.100" web-sys = { version = "0.3.70", features = [ "Navigator", "Clipboard", "Storage", + "Window", + "Document", + "Element", + "HtmlTextAreaElement", ] } wasm-bindgen-futures = "0.4.43" gloo-timers = { version = "0.3.0", features = ["futures"] } diff --git a/src/components/program_window/program_tab.rs b/src/components/program_window/program_tab.rs index d73bdbe..edbb1ea 100644 --- a/src/components/program_window/program_tab.rs +++ b/src/components/program_window/program_tab.rs @@ -2,14 +2,15 @@ use std::sync::Arc; use itertools::Itertools; use leptos::{ - component, create_node_ref, create_rw_signal, ev, event_target_value, html, spawn_local, - use_context, view, IntoView, RwSignal, Signal, SignalGetUntracked, SignalSet, SignalUpdate, - SignalWith, SignalWithUntracked, + component, create_effect, create_node_ref, create_rw_signal, ev, event_target_value, html, + spawn_local, use_context, view, IntoView, RwSignal, Signal, SignalGet, SignalGetUntracked, + SignalSet, SignalUpdate, SignalWith, SignalWithUntracked, }; use simplicityhl::parse::ParseFromStr; use simplicityhl::simplicity::jet::elements::ElementsEnv; use simplicityhl::{elements, simplicity}; use simplicityhl::{CompiledProgram, SatisfiedProgram, WitnessValues}; +use wasm_bindgen::JsCast; use crate::components::copy_to_clipboard::CopyToClipboard; use crate::function::Runner; @@ -175,6 +176,72 @@ pub fn ProgramTab() -> impl IntoView { let update_program_text = move |event: ev::Event| { program.text.set(event_target_value(&event)); }; + + // Initialize CodeMirror when textarea is mounted (optional enhancement) + create_effect(move |_prev_value| { + if let Some(textarea) = textarea_ref.get() { + // Only initialize once + spawn_local(async move { + // Small delay to ensure CodeMirror is loaded + gloo_timers::future::TimeoutFuture::new(50).await; + + if let Some(window) = web_sys::window() { + // Check if CodeMirror and our init function exist + let has_codemirror = + js_sys::Reflect::has(&window, &"CodeMirror".into()).unwrap_or(false); + + if has_codemirror { + if let Ok(simplicity_editor) = + js_sys::Reflect::get(&window, &"SimplicityEditor".into()) + { + // Call SimplicityEditor.init() if it exists + if let Ok(init_fn) = + js_sys::Reflect::get(&simplicity_editor, &"init".into()) + { + if let Some(init_fn) = init_fn.dyn_ref::() { + let textarea_id = "program-input"; + let initial_value = textarea.value(); + let _ = init_fn.call2( + &simplicity_editor, + &textarea_id.into(), + &initial_value.into(), + ); + } + } + } + } + } + }); + } + }); + + // Sync CodeMirror when program.text changes (e.g. loading examples) + create_effect(move |_| { + let text = program.text.get(); + // Skip update if textarea already has this value (to avoid loops) + if let Some(textarea) = textarea_ref.get() { + if textarea.value() == text { + return; + } + } + + spawn_local(async move { + if let Some(window) = web_sys::window() { + if let Ok(simplicity_editor) = + js_sys::Reflect::get(&window, &"SimplicityEditor".into()) + { + if let Ok(set_value_fn) = + js_sys::Reflect::get(&simplicity_editor, &"setValue".into()) + { + if let Some(set_value_fn) = set_value_fn.dyn_ref::() { + let _ = set_value_fn.call1(&simplicity_editor, &text.into()); + } + } + } + } + }); + }); + let insert_4_spaces = move || { let element = textarea_ref.get().expect("