1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158
#![deny(missing_docs)]
#![cfg_attr(not(feature = "stable"), feature(fn_traits))]
#![cfg_attr(not(feature = "stable"), feature(unboxed_closures))]
//! DOM operations and rendering for Leptos.
//!
//! This crate mostly includes utilities and types used by the templating system, and utility
//! functions to make it easier for you to interact with the DOM, including with events.
//!
//! It also includes functions to support rendering HTML to strings, which is the server-side
//! equivalent of DOM operations.
//!
//! Note that the types [Element] and [Node] are type aliases, handled differently depending on the
//! target:
//! - Browser (features `csr` and `hydrate`): they alias [web_sys::Element] and [web_sys::Node],
//! since the renderer works directly with actual DOM nodes.
//! - Server: they both alias [String], since the templating system directly generates HTML strings.
use cfg_if::cfg_if;
mod attribute;
mod child;
mod class;
mod event_delegation;
mod logging;
mod mount;
mod node_ref;
mod operations;
mod property;
cfg_if! {
// can only include this if we're *only* enabling SSR, as it's the lowest-priority feature
// if either `csr` or `hydrate` is enabled, `Element` is a `web_sys::Element` and can't be rendered
if #[cfg(doc)] {
/// The type of an HTML or DOM element. When server rendering, this is a `String`. When rendering in a browser,
/// this is a DOM `Element`.
pub type Element = web_sys::Element;
/// The type of an HTML or DOM node. When server rendering, this is a `String`. When rendering in a browser,
/// this is a DOM `Node`.
pub type Node = web_sys::Node;
mod render_to_string;
pub use render_to_string::*;
mod reconcile;
mod render;
pub use reconcile::*;
pub use render::*;
} else if #[cfg(not(any(feature = "hydrate", feature = "csr")))] {
/// The type of an HTML or DOM element. When server rendering, this is a `String`. When rendering in a browser,
/// this is a DOM `Element`.
pub type Element = String;
/// The type of an HTML or DOM node. When server rendering, this is a `String`. When rendering in a browser,
/// this is a DOM `Node`.
pub type Node = String;
mod render_to_string;
pub use render_to_string::*;
#[doc(hidden)]
pub struct Marker { }
} else {
/// The type of an HTML or DOM element. When server rendering, this is a `String`. When rendering in a browser,
/// this is a DOM `Element`.
pub type Element = web_sys::Element;
/// The type of an HTML or DOM node. When server rendering, this is a `String`. When rendering in a browser,
/// this is a DOM `Node`.
pub type Node = web_sys::Node;
mod reconcile;
mod render;
pub use reconcile::*;
pub use render::*;
}
}
pub use attribute::*;
pub use child::*;
pub use class::*;
pub use logging::*;
pub use mount::*;
pub use node_ref::*;
pub use operations::*;
pub use property::*;
pub use js_sys;
pub use wasm_bindgen;
pub use web_sys;
use leptos_reactive::Scope;
pub use wasm_bindgen::UnwrapThrowExt;
// Hidden because this is primarily used by the `view` macro, not by library users.
#[doc(hidden)]
pub fn create_component<F, T>(cx: Scope, f: F) -> T
where
F: FnOnce() -> T,
{
cfg_if! {
if #[cfg(feature = "csr")] {
cx.untrack(f)
} else {
cx.with_next_context(f)
}
}
}
/// Shorthand to test for whether an `ssr` feature is enabled.
///
/// In the past, this was implemented by checking whether `not(target_arch = "wasm32")`.
/// Now that some cloud platforms are moving to run Wasm on the edge, we really can't
/// guarantee that compiling to Wasm means browser APIs are available, or that not compiling
/// to Wasm means we're running on the server.
///
/// ```
/// # use leptos_dom::is_server;
/// let todos = if is_server!() {
/// // if on the server, load from DB
/// } else {
/// // if on the browser, do something else
/// };
/// ```
#[macro_export]
macro_rules! is_server {
() => {
cfg!(feature = "ssr")
};
}
/// A shorthand macro to test whether this is a debug build.
/// ```
/// # use leptos_dom::is_dev;
/// if is_dev!() {
/// // log something or whatever
/// }
/// ```
#[macro_export]
macro_rules! is_dev {
() => {
cfg!(debug_assertions)
};
}
#[doc(hidden)]
pub fn __leptos_renderer_error(expected: &'static str, location: &'static str) -> web_sys::Node {
cfg_if! {
if #[cfg(debug_assertions)] {
panic!("Yikes! Something went wrong while Leptos was trying to traverse the DOM to set up the reactive system.\n\nThe renderer expected {expected:?} as {location} and couldn't get it.\n\nThis is almost certainly a bug in the framework, not your application. Please open an issue on GitHub and provide example code if possible.\n\nIn the meantime, these bugs are often related to <Component/>s or {{block}}s when they are siblings of each other. Try wrapping those in a <span> or <div> for now. Sorry for the pain!")
} else {
_ = expected;
panic!("Renderer error. You can find a more detailed error message if you compile in debug mode.")
}
}
}