1#![forbid(unsafe_code)]
51#![allow(
52 clippy::use_self,
53 clippy::single_match_else,
54 clippy::must_use_candidate,
55 clippy::wildcard_imports,
56 clippy::used_underscore_binding,
57 clippy::future_not_send
58)]
59#![allow(deprecated)]
60
61macro_rules! map_callback_return_to_option_ms {
67 ($cb_type:ty, $callback:expr, $panic_text:literal, $output_type:tt) => {{
68 let t_type = std::any::TypeId::of::<MsU>();
69 if t_type == std::any::TypeId::of::<Ms>() {
70 $output_type::new(move |value| {
71 (&mut Some($callback(value)) as &mut dyn std::any::Any)
72 .downcast_mut::<Option<Ms>>()
73 .and_then(Option::take)
74 })
75 } else if t_type == std::any::TypeId::of::<Option<Ms>>() {
76 $output_type::new(move |value| {
77 (&mut $callback(value) as &mut dyn std::any::Any)
78 .downcast_mut::<Option<Ms>>()
79 .and_then(Option::take)
80 })
81 } else if t_type == std::any::TypeId::of::<()>() {
82 $output_type::new(move |value| {
83 $callback(value);
84 None
85 }) as $output_type<$cb_type>
86 } else {
87 panic!($panic_text);
88 }
89 }};
90}
91pub use crate::{
93 app::App,
94 browser::dom::cast::{
95 to_drag_event, to_html_el, to_input, to_keyboard_event, to_mouse_event, to_select,
96 to_textarea, to_touch_event, to_wheel_event,
97 },
98 browser::url::Url,
99 browser::util::{
100 self, body, canvas, canvas_context_2d, document, error, history, html_document, log, window,
101 },
102 virtual_dom::{Attrs, EventHandler, Style},
103};
104
105pub use futures::{
106 self,
107 future::{self, FutureExt, TryFutureExt},
108};
109use wasm_bindgen::{closure::Closure, JsCast};
110pub use wasm_bindgen_futures::{self, spawn_local, JsFuture};
111
112#[macro_use]
113pub mod shortcuts;
114pub mod app;
115pub mod browser;
116pub mod dom_entity_names;
117pub mod helpers;
118pub mod virtual_dom;
119
120pub const fn empty<Ms>() -> virtual_dom::Node<Ms> {
123 virtual_dom::Node::Empty
124}
125
126#[deprecated(
127 since = "0.8.0",
128 note = "use [`Orders::stream`](app/orders/trait.Orders.html#method.stream) instead"
129)]
130pub fn set_interval(handler: Box<dyn Fn()>, timeout: i32) {
137 let callback = Closure::wrap(handler as Box<dyn Fn()>);
138 util::window()
139 .set_interval_with_callback_and_timeout_and_arguments_0(
140 callback.as_ref().unchecked_ref(),
141 timeout,
142 )
143 .expect("Problem setting interval");
144 callback.forget();
145}
146
147#[deprecated(
148 since = "0.8.0",
149 note = "use [`Orders::stream`](app/orders/trait.Orders.html#method.stream) instead"
150)]
151pub fn set_timeout(handler: Box<dyn Fn()>, timeout: i32) {
157 let callback = Closure::wrap(handler as Box<dyn Fn()>);
158 util::window()
159 .set_timeout_with_callback_and_timeout_and_arguments_0(
160 callback.as_ref().unchecked_ref(),
161 timeout,
162 )
163 .expect("Problem setting timeout");
164 callback.forget();
165}
166
167pub mod prelude {
172 #[cfg(feature = "routing")]
173 pub use crate::app::subs;
174 pub use crate::{
175 app::{
176 cmds, streams, App, CmdHandle, GetElement, MessageMapper, Orders, RenderInfo,
177 StreamHandle, SubHandle,
178 },
179 browser::dom::css_units::*,
180 browser::dom::event_handler::{
181 drag_ev, ev, input_ev, keyboard_ev, mouse_ev, pointer_ev, raw_ev, simple_ev, touch_ev,
182 wheel_ev,
183 },
184 browser::dom::Namespace,
185 browser::util::{
186 request_animation_frame, RequestAnimationFrameHandle, RequestAnimationFrameTime,
187 },
188 browser::{Url, UrlSearch},
189 helpers::not,
190 shortcuts::*,
193 virtual_dom::{
194 el_key, el_ref::el_ref, on_insert, AsAtValue, At, AtValue, CSSValue, El, ElRef, Ev,
195 EventHandler, InsertEventHandler, IntoNodes, Node, St, Tag, ToClasses, UpdateEl,
196 UpdateElForIterator, UpdateElForOptionIterator, View,
197 },
198 };
199 pub use indexmap::IndexMap; pub use js_sys;
201 pub use wasm_bindgen::{self, prelude::*, JsCast};
202 pub use web_sys;
203}
204
205#[cfg(test)]
206pub mod tests {
207 use wasm_bindgen_test::wasm_bindgen_test_configure;
208 wasm_bindgen_test_configure!(run_in_browser);
209
210 use wasm_bindgen_test::*;
211
212 #[wasm_bindgen_test]
215 #[allow(dead_code)]
216 pub(crate) fn app_builds() {
217 use crate as seed; use crate::app::Orders;
219 use crate::browser::dom::event_handler::mouse_ev;
220 use crate::prelude::*;
221 use crate::virtual_dom::{EventHandler, Node};
222
223 #[derive(Default)]
224 struct Model {
225 pub val: i32,
226 }
227
228 #[derive(Clone)]
229 enum Msg {
230 Increment,
231 }
232
233 fn update(msg: Msg, model: &mut Model, _: &mut impl Orders<Msg>) {
234 match msg {
235 Msg::Increment => model.val += 1,
236 }
237 }
238
239 fn view(_model: &Model) -> Vec<Node<Msg>> {
240 vec![div!["Hello world"]]
241 }
242
243 fn window_events(_model: &Model) -> Vec<EventHandler<Msg>> {
244 vec![mouse_ev("mousemove", |_| Msg::Increment)]
245 }
246
247 fn routes(_url: &seed::Url) -> Msg {
248 Msg::Increment
249 }
250
251 #[wasm_bindgen]
252 pub fn render() {
253 seed::App::start("render test app", |_, _| Model::default(), update, view);
254 }
255 }
256}