mirror of
https://github.com/leptos-rs/leptos
synced 2024-11-10 14:54:16 +00:00
Merge pull request #219 from jquesada2016/leptos_dom_stable
Stable support for `leptos_dom`
This commit is contained in:
commit
60187961a0
8 changed files with 115 additions and 79 deletions
|
@ -9,6 +9,7 @@ description = "DOM operations for the Leptos web framework."
|
|||
|
||||
[dependencies]
|
||||
cfg-if = "1"
|
||||
drain_filter_polyfill = "0.1"
|
||||
educe = "0.4"
|
||||
futures = "0.3"
|
||||
gloo = "0.8"
|
||||
|
@ -17,6 +18,7 @@ indexmap = "1.9"
|
|||
itertools = "0.10"
|
||||
js-sys = "0.3"
|
||||
leptos_reactive = { path = "../leptos_reactive", default-features = false, version = "0.1.0-alpha" }
|
||||
once_cell = "1"
|
||||
pad-adapter = "0.1"
|
||||
paste = "1"
|
||||
rustc-hash = "1.1.0"
|
||||
|
|
|
@ -13,9 +13,11 @@ pub use dyn_child::*;
|
|||
pub use each::*;
|
||||
pub use fragment::*;
|
||||
use leptos_reactive::Scope;
|
||||
use std::{borrow::Cow, fmt};
|
||||
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
||||
use std::{cell::OnceCell, rc::Rc};
|
||||
use once_cell::unsync::OnceCell;
|
||||
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
||||
use std::rc::Rc;
|
||||
use std::{borrow::Cow, fmt};
|
||||
pub use unit::*;
|
||||
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
||||
use wasm_bindgen::JsCast;
|
||||
|
|
|
@ -3,11 +3,12 @@ use cfg_if::cfg_if;
|
|||
cfg_if! {
|
||||
if #[cfg(all(target_arch = "wasm32", feature = "web"))] {
|
||||
use crate::{mount_child, prepare_to_move, MountKind, Mountable, RANGE};
|
||||
use std::cell::OnceCell;
|
||||
use once_cell::unsync::OnceCell;
|
||||
use leptos_reactive::create_effect;
|
||||
use rustc_hash::FxHasher;
|
||||
use std::hash::BuildHasherDefault;
|
||||
use wasm_bindgen::JsCast;
|
||||
use drain_filter_polyfill::VecExt as VecDrainFilterExt;
|
||||
|
||||
type FxIndexSet<T> = indexmap::IndexSet<T, BuildHasherDefault<FxHasher>>;
|
||||
|
||||
|
@ -573,7 +574,7 @@ fn apply_cmds<T, EF, N>(
|
|||
EF: Fn(T) -> N,
|
||||
N: IntoView,
|
||||
{
|
||||
let range = &RANGE;
|
||||
let range = RANGE.with(|range| (*range).clone());
|
||||
|
||||
// Resize children if needed
|
||||
if cmds.added.len().checked_sub(cmds.removed.len()).is_some() {
|
||||
|
|
|
@ -12,7 +12,7 @@ cfg_if! {
|
|||
};
|
||||
use crate::{mount_child, MountKind};
|
||||
use leptos_reactive::create_render_effect;
|
||||
use std::cell::LazyCell;
|
||||
use once_cell::unsync::Lazy as LazyCell;
|
||||
use wasm_bindgen::JsCast;
|
||||
|
||||
/// Trait alias for the trait bounts on [`ElementDescriptor`].
|
||||
|
@ -671,13 +671,14 @@ macro_rules! generate_html_tags {
|
|||
paste::paste! {
|
||||
$(
|
||||
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
||||
#[thread_local]
|
||||
static [<$tag:upper>]: LazyCell<web_sys::HtmlElement> = LazyCell::new(|| {
|
||||
crate::document()
|
||||
.create_element(stringify!($tag))
|
||||
.unwrap()
|
||||
.unchecked_into()
|
||||
});
|
||||
thread_local! {
|
||||
static [<$tag:upper>]: LazyCell<web_sys::HtmlElement> = LazyCell::new(|| {
|
||||
crate::document()
|
||||
.create_element(stringify!($tag))
|
||||
.unwrap()
|
||||
.unchecked_into()
|
||||
});
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
#[$meta]
|
||||
|
@ -735,10 +736,20 @@ macro_rules! generate_html_tags {
|
|||
"not found, ignoring it for hydration"
|
||||
);
|
||||
|
||||
[<$tag:upper>].clone_node().unwrap().unchecked_into()
|
||||
[<$tag:upper>]
|
||||
.with(|el|
|
||||
el.clone_node()
|
||||
.unwrap()
|
||||
.unchecked_into()
|
||||
)
|
||||
}
|
||||
} else {
|
||||
[<$tag:upper>].clone_node().unwrap().unchecked_into()
|
||||
[<$tag:upper>]
|
||||
.with(|el|
|
||||
el.clone_node()
|
||||
.unwrap()
|
||||
.unchecked_into()
|
||||
)
|
||||
};
|
||||
|
||||
Self {
|
||||
|
|
|
@ -7,7 +7,7 @@ use leptos_reactive::Scope;
|
|||
use std::borrow::Cow;
|
||||
cfg_if! {
|
||||
if #[cfg(all(target_arch = "wasm32", feature = "web"))] {
|
||||
use std::cell::LazyCell;
|
||||
use once_cell::unsync::Lazy as LazyCell;
|
||||
use wasm_bindgen::JsCast;
|
||||
} else {
|
||||
use super::{HydrationKey, HTML_ELEMENT_DEREF_UNIMPLEMENTED_MSG};
|
||||
|
@ -25,24 +25,25 @@ macro_rules! generate_math_tags {
|
|||
paste::paste! {
|
||||
$(
|
||||
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
||||
#[thread_local]
|
||||
static [<$tag:upper $(_ $second:upper $(_ $third:upper)?)?>]: LazyCell<web_sys::HtmlElement> = LazyCell::new(|| {
|
||||
crate::document()
|
||||
.create_element_ns(
|
||||
Some(wasm_bindgen::intern("http://www.w3.org/1998/Math/MathML")),
|
||||
concat![
|
||||
stringify!($tag),
|
||||
$(
|
||||
"-", stringify!($second),
|
||||
thread_local! {
|
||||
static [<$tag:upper $(_ $second:upper $(_ $third:upper)?)?>]: LazyCell<web_sys::HtmlElement> = LazyCell::new(|| {
|
||||
crate::document()
|
||||
.create_element_ns(
|
||||
Some(wasm_bindgen::intern("http://www.w3.org/1998/Math/MathML")),
|
||||
concat![
|
||||
stringify!($tag),
|
||||
$(
|
||||
"-", stringify!($third)
|
||||
"-", stringify!($second),
|
||||
$(
|
||||
"-", stringify!($third)
|
||||
)?
|
||||
)?
|
||||
)?
|
||||
],
|
||||
)
|
||||
.unwrap()
|
||||
.unchecked_into()
|
||||
});
|
||||
],
|
||||
)
|
||||
.unwrap()
|
||||
.unchecked_into()
|
||||
});
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
#[$meta]
|
||||
|
@ -100,10 +101,20 @@ macro_rules! generate_math_tags {
|
|||
"not found, ignoring it for hydration"
|
||||
);
|
||||
|
||||
[<$tag:upper $(_ $second:upper $(_ $third:upper)?)?>].clone_node().unwrap().unchecked_into()
|
||||
[<$tag:upper $(_ $second:upper $(_ $third:upper)?)?>]
|
||||
.with(|el|
|
||||
el.clone_node()
|
||||
.unwrap()
|
||||
.unchecked_into()
|
||||
)
|
||||
}
|
||||
} else {
|
||||
[<$tag:upper $(_ $second:upper $(_ $third:upper)?)?>].clone_node().unwrap().unchecked_into()
|
||||
[<$tag:upper $(_ $second:upper $(_ $third:upper)?)?>]
|
||||
.with(|el|
|
||||
el.clone_node()
|
||||
.unwrap()
|
||||
.unchecked_into()
|
||||
)
|
||||
};
|
||||
|
||||
Self {
|
||||
|
|
|
@ -5,9 +5,9 @@ use super::{ElementDescriptor, HtmlElement};
|
|||
use super::{HydrationKey, HTML_ELEMENT_DEREF_UNIMPLEMENTED_MSG};
|
||||
use crate::HydrationCtx;
|
||||
use leptos_reactive::Scope;
|
||||
use std::borrow::Cow;
|
||||
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
||||
use std::cell::LazyCell;
|
||||
use once_cell::unsync::Lazy as LazyCell;
|
||||
use std::borrow::Cow;
|
||||
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
||||
use wasm_bindgen::JsCast;
|
||||
|
||||
|
@ -22,24 +22,25 @@ macro_rules! generate_svg_tags {
|
|||
paste::paste! {
|
||||
$(
|
||||
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
||||
#[thread_local]
|
||||
static [<$tag:upper $(_ $second:upper $(_ $third:upper)?)?>]: LazyCell<web_sys::HtmlElement> = LazyCell::new(|| {
|
||||
crate::document()
|
||||
.create_element_ns(
|
||||
Some(wasm_bindgen::intern("http://www.w3.org/2000/svg")),
|
||||
concat![
|
||||
stringify!($tag),
|
||||
$(
|
||||
"-", stringify!($second),
|
||||
thread_local! {
|
||||
static [<$tag:upper $(_ $second:upper $(_ $third:upper)?)?>]: LazyCell<web_sys::HtmlElement> = LazyCell::new(|| {
|
||||
crate::document()
|
||||
.create_element_ns(
|
||||
Some(wasm_bindgen::intern("http://www.w3.org/2000/svg")),
|
||||
concat![
|
||||
stringify!($tag),
|
||||
$(
|
||||
"-", stringify!($third)
|
||||
"-", stringify!($second),
|
||||
$(
|
||||
"-", stringify!($third)
|
||||
)?
|
||||
)?
|
||||
)?
|
||||
],
|
||||
)
|
||||
.unwrap()
|
||||
.unchecked_into()
|
||||
});
|
||||
],
|
||||
)
|
||||
.unwrap()
|
||||
.unchecked_into()
|
||||
});
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
#[$meta]
|
||||
|
@ -97,10 +98,20 @@ macro_rules! generate_svg_tags {
|
|||
"not found, ignoring it for hydration"
|
||||
);
|
||||
|
||||
[<$tag:upper $(_ $second:upper $(_ $third:upper)?)?>].clone_node().unwrap().unchecked_into()
|
||||
[<$tag:upper $(_ $second:upper $(_ $third:upper)?)?>]
|
||||
.with(|el|
|
||||
el.clone_node()
|
||||
.unwrap()
|
||||
.unchecked_into()
|
||||
)
|
||||
}
|
||||
} else {
|
||||
[<$tag:upper $(_ $second:upper $(_ $third:upper)?)?>].clone_node().unwrap().unchecked_into()
|
||||
[<$tag:upper $(_ $second:upper $(_ $third:upper)?)?>]
|
||||
.with(|el|
|
||||
el.clone_node()
|
||||
.unwrap()
|
||||
.unchecked_into()
|
||||
)
|
||||
};
|
||||
|
||||
Self {
|
||||
|
|
|
@ -1,21 +1,22 @@
|
|||
use std::{cell::RefCell, fmt::Display};
|
||||
|
||||
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
||||
use std::cell::LazyCell;
|
||||
use once_cell::unsync::Lazy as LazyCell;
|
||||
|
||||
/// We can tell if we start in hydration mode by checking to see if the
|
||||
/// id "_0" is present in the DOM. If it is, we know we are hydrating from
|
||||
/// the server, if not, we are starting off in CSR
|
||||
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
||||
#[thread_local]
|
||||
static mut IS_HYDRATING: LazyCell<bool> = LazyCell::new(|| {
|
||||
#[cfg(debug_assertions)]
|
||||
return crate::document().get_element_by_id("_0-0-0").is_some()
|
||||
|| crate::document().get_element_by_id("_0-0-0o").is_some();
|
||||
thread_local! {
|
||||
static IS_HYDRATING: RefCell<LazyCell<bool>> = RefCell::new(LazyCell::new(|| {
|
||||
#[cfg(debug_assertions)]
|
||||
return crate::document().get_element_by_id("_0-0-0").is_some()
|
||||
|| crate::document().get_element_by_id("_0-0-0o").is_some();
|
||||
|
||||
#[cfg(not(debug_assertions))]
|
||||
return crate::document().get_element_by_id("_0-0-0").is_some();
|
||||
});
|
||||
#[cfg(not(debug_assertions))]
|
||||
return crate::document().get_element_by_id("_0-0-0").is_some();
|
||||
}));
|
||||
}
|
||||
|
||||
/// A stable identifer within the server-rendering or hydration process.
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
|
@ -86,14 +87,14 @@ impl HydrationCtx {
|
|||
|
||||
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
||||
pub(crate) fn stop_hydrating() {
|
||||
unsafe {
|
||||
std::mem::take(&mut IS_HYDRATING);
|
||||
}
|
||||
IS_HYDRATING.with(|is_hydrating| {
|
||||
std::mem::take(&mut *is_hydrating.borrow_mut());
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
||||
pub(crate) fn is_hydrating() -> bool {
|
||||
unsafe { *IS_HYDRATING }
|
||||
IS_HYDRATING.with(|is_hydrating| **is_hydrating.borrow())
|
||||
}
|
||||
|
||||
pub(crate) fn to_string(id: &HydrationKey, closing: bool) -> String {
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#![deny(missing_docs)]
|
||||
#![feature(once_cell, iter_intersperse, drain_filter, thread_local)]
|
||||
#![cfg_attr(not(feature = "stable"), feature(fn_traits))]
|
||||
#![cfg_attr(not(feature = "stable"), feature(unboxed_closures))]
|
||||
|
||||
|
@ -32,16 +31,15 @@ use leptos_reactive::Scope;
|
|||
pub use logging::*;
|
||||
pub use macro_helpers::{IntoAttribute, IntoClass, IntoProperty};
|
||||
pub use node_ref::*;
|
||||
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
||||
use once_cell::unsync::Lazy as LazyCell;
|
||||
#[cfg(not(all(target_arch = "wasm32", feature = "web")))]
|
||||
use smallvec::SmallVec;
|
||||
#[cfg(not(all(target_arch = "wasm32", feature = "web")))]
|
||||
pub use ssr::*;
|
||||
use std::{borrow::Cow, fmt};
|
||||
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
||||
use std::{
|
||||
cell::{LazyCell, RefCell},
|
||||
rc::Rc,
|
||||
};
|
||||
use std::{cell::RefCell, rc::Rc};
|
||||
pub use transparent::*;
|
||||
pub use wasm_bindgen;
|
||||
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
||||
|
@ -50,13 +48,12 @@ use wasm_bindgen::UnwrapThrowExt;
|
|||
pub use web_sys;
|
||||
|
||||
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
||||
#[thread_local]
|
||||
static COMMENT: LazyCell<web_sys::Node> =
|
||||
LazyCell::new(|| document().create_comment("").unchecked_into());
|
||||
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
||||
#[thread_local]
|
||||
static RANGE: LazyCell<web_sys::Range> =
|
||||
LazyCell::new(|| web_sys::Range::new().unwrap());
|
||||
thread_local! {
|
||||
static COMMENT: LazyCell<web_sys::Node> =
|
||||
LazyCell::new(|| document().create_comment("").unchecked_into());
|
||||
static RANGE: LazyCell<web_sys::Range> =
|
||||
LazyCell::new(|| web_sys::Range::new().unwrap());
|
||||
}
|
||||
|
||||
/// Converts the value into a [`View`].
|
||||
pub trait IntoView {
|
||||
|
@ -289,7 +286,7 @@ impl Comment {
|
|||
}
|
||||
|
||||
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
||||
let node = COMMENT.clone_node().unwrap();
|
||||
let node = COMMENT.with(|comment| comment.clone_node().unwrap());
|
||||
|
||||
#[cfg(all(debug_assertions, target_arch = "wasm32", feature = "web"))]
|
||||
node.set_text_content(Some(&format!(" {content} ")));
|
||||
|
|
Loading…
Reference in a new issue