Skip to content
This repository was archived by the owner on Jul 5, 2025. It is now read-only.

Commit f3cc6e4

Browse files
committed
wip: events
1 parent d4618cc commit f3cc6e4

File tree

4 files changed

+55
-30
lines changed

4 files changed

+55
-30
lines changed

crates/sweet_core/src/html/html_node.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -225,16 +225,16 @@ pub struct HtmlConstants {
225225
/// the global event handler for all events
226226
pub event_handler: &'static str,
227227
/// the global vec that stores prehydrated events
228-
pub prehydrate_events: &'static str,
228+
pub event_store: &'static str,
229229
}
230230

231231
impl Default for HtmlConstants {
232232
fn default() -> Self {
233233
Self {
234234
id_key: "data-sweet-id",
235235
cx_map_key: "data-sweet-cx-map",
236-
event_handler: "_sweet_event",
237-
prehydrate_events: "_sweet_prehydrate_events",
236+
event_handler: "_sweet_event_handler",
237+
event_store: "_sweet_event_store",
238238
}
239239
}
240240
}

crates/sweet_core/src/html/rsx_to_resumable_html.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ impl RsxToResumableHtml {
8080
globalThis.{prehydrate_events} = []
8181
globalThis.{event_handler} = (id,event) => globalThis.{prehydrate_events}.push([id, event])
8282
"#,
83-
prehydrate_events = self.html_constants.prehydrate_events,
83+
prehydrate_events = self.html_constants.event_store,
8484
event_handler = self.html_constants.event_handler,
8585
);
8686
let el = HtmlElementNode::inline_script(script, Default::default());
@@ -114,6 +114,8 @@ mod test {
114114
expect(RsxToResumableHtml::render(
115115
&rsx! { <main onclick=on_click></main> },
116116
))
117-
.to_start_with("<main onclick=\"_sweet_event(0, event)\"></main>");
117+
.to_start_with(
118+
"<main onclick=\"_sweet_event_handler(0, event)\"></main>",
119+
);
118120
}
119121
}

crates/sweet_core/src/hydration/dom_event_registry.rs

Lines changed: 47 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
use crate::prelude::*;
22
use std::cell::RefCell;
33
use std::collections::HashMap;
4+
use wasm_bindgen::prelude::Closure;
45
use wasm_bindgen::JsCast;
56
use wasm_bindgen::JsValue;
7+
use web_sys::window;
68
use web_sys::Event;
79

810
pub struct EventRegistry;
@@ -42,18 +44,24 @@ impl EventRegistry {
4244
) {
4345
Self::register(key, cx, value);
4446
}
47+
48+
pub fn initialize() -> ParseResult<()> {
49+
let constants = CurrentHydrator::with(|h| h.html_constants().clone());
50+
playback_prehydrate_events(&constants)?;
51+
hook_up_event_listeners(&constants)?;
52+
Ok(())
53+
}
4554
}
4655

47-
pub fn playback_prehydrate_events() -> ParseResult<()> {
56+
fn playback_prehydrate_events(constants: &HtmlConstants) -> ParseResult<()> {
4857
sweet_loader_extern::GLOBAL.with(|global| {
49-
let constants = CurrentHydrator::with(|h| h.html_constants().clone());
5058
// let event_handler =
5159
// js_sys::Reflect::get(&global, &constants.event_handler.into())
5260
// .map_err(|_| {
5361
// ParseError::Hydration("could not find event handler".into())
5462
// })?;
5563
let prehydrate_events =
56-
js_sys::Reflect::get(&global, &constants.prehydrate_events.into())
64+
js_sys::Reflect::get(&global, &constants.event_store.into())
5765
.map_err(|_| {
5866
ParseError::Hydration("could not find event handler".into())
5967
})?;
@@ -68,31 +76,47 @@ pub fn playback_prehydrate_events() -> ParseResult<()> {
6876
EventRegistry::trigger(&event_type, id, event.unchecked_into());
6977
}
7078
}
71-
// } else {
72-
// return Err(ParseError::Hydration("bad event".into()));
73-
// }
74-
// }
79+
js_sys::Reflect::delete_property(
80+
&global.unchecked_ref(),
81+
&constants.event_store.into(),
82+
)
83+
.unwrap();
84+
js_sys::Reflect::delete_property(
85+
&global.unchecked_ref(),
86+
&constants.event_handler.into(),
87+
)
88+
.unwrap();
89+
7590
Ok(())
7691
})
7792
}
7893

79-
// let event = event_arr.get(1);
80-
// Self::trigger
81-
// js_sys::Reflect::delete_property(
82-
// &sweet.unchecked_ref(),
83-
// &"uncanny".into(),
84-
// )
85-
// .unwrap_or_default();
86-
// }
87-
// let closure =
88-
// Closure::wrap(Box::new(move |id: usize, evt: web_sys::Event| {
89-
// func(id, evt);
90-
// }) as Box<dyn FnMut(usize, web_sys::Event)>);
91-
92-
// js_sys::Reflect::set(&sweet, &"event".into(), &closure.as_ref())
93-
// .unwrap_or_default();
94+
fn hook_up_event_listeners(constants: &HtmlConstants) -> ParseResult<()> {
95+
REGISTERED_EVENTS.with(|current| -> ParseResult<()> {
96+
let mut current = current.borrow_mut();
97+
let document = window().unwrap().document().unwrap();
98+
for ((el_id, key), func) in current.drain() {
99+
let el = document
100+
.query_selector(&format!("[{}='{}']", constants.id_key, el_id))
101+
.ok()
102+
.flatten()
103+
.ok_or_else(|| {
104+
ParseError::Hydration("could not find element".into())
105+
})?;
106+
el.remove_attribute(&key).unwrap();
94107

95-
// closure.forget();
108+
let closure = Closure::wrap(Box::new(move |e: JsValue| {
109+
func(e);
110+
}) as Box<dyn Fn(JsValue)>);
111+
el.add_event_listener_with_callback(
112+
&key,
113+
closure.as_ref().unchecked_ref(),
114+
)
115+
.unwrap();
116+
}
117+
Ok(())
118+
})
119+
}
96120

97121
pub mod sweet_loader_extern {
98122
use wasm_bindgen::prelude::*;

crates/sweet_core/src/hydration/dom_hydrator.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
use super::dom_event_registry::playback_prehydrate_events;
21
use super::rsx_context_map::RsxContextMap;
32
use crate::prelude::*;
43
use wasm_bindgen::JsCast;
@@ -113,7 +112,7 @@ impl DomHydrator {
113112

114113

115114
impl Hydrator for DomHydrator {
116-
fn initialize(&mut self) { playback_prehydrate_events().unwrap(); }
115+
fn initialize(&mut self) { EventRegistry::initialize().unwrap(); }
117116
fn html_constants(&self) -> &HtmlConstants { &self.constants }
118117

119118
/// returns body inner html

0 commit comments

Comments
 (0)