mirror of
https://github.com/leptos-rs/leptos
synced 2024-11-10 14:54:16 +00:00
Handle custom elements correctly
This commit is contained in:
parent
1f39299303
commit
e17afd4559
2 changed files with 61 additions and 1 deletions
|
@ -165,6 +165,66 @@ pub struct Custom {
|
|||
id: HydrationKey,
|
||||
}
|
||||
|
||||
impl Custom {
|
||||
pub fn new(name: impl Into<Cow<'static, str>>) -> Self {
|
||||
let name = name.into();
|
||||
let id = HydrationCtx::id();
|
||||
|
||||
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
||||
let element = if HydrationCtx::is_hydrating() {
|
||||
if let Some(el) = crate::document().get_element_by_id(&format!("_{id}")) {
|
||||
#[cfg(debug_assertions)]
|
||||
assert_eq!(
|
||||
el.node_name().to_ascii_uppercase(),
|
||||
name.to_ascii_uppercase(),
|
||||
"SSR and CSR elements have the same `TopoId` but different node \
|
||||
kinds. This is either a discrepancy between SSR and CSR rendering
|
||||
logic, which is considered a bug, or it can also be a \
|
||||
leptos hydration issue."
|
||||
);
|
||||
|
||||
el.remove_attribute("id").unwrap();
|
||||
|
||||
el.unchecked_into()
|
||||
} else if let Ok(Some(el)) =
|
||||
crate::document().query_selector(&format!("[leptos-hk=_{id}]"))
|
||||
{
|
||||
#[cfg(debug_assertions)]
|
||||
assert_eq!(
|
||||
el.node_name().to_ascii_uppercase(),
|
||||
name.to_ascii_uppercase(),
|
||||
"SSR and CSR elements have the same `TopoId` but different node \
|
||||
kinds. This is either a discrepancy between SSR and CSR rendering
|
||||
logic, which is considered a bug, or it can also be a \
|
||||
leptos hydration issue."
|
||||
);
|
||||
|
||||
el.remove_attribute("leptos-hk").unwrap();
|
||||
|
||||
el.unchecked_into()
|
||||
} else {
|
||||
gloo::console::warn!(
|
||||
"element with id",
|
||||
format!("_{id}"),
|
||||
"not found, ignoring it for hydration"
|
||||
);
|
||||
|
||||
crate::document().create_element(&name).unwrap()
|
||||
}
|
||||
} else {
|
||||
crate::document().create_element(&name).unwrap()
|
||||
};
|
||||
|
||||
Self {
|
||||
name,
|
||||
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
||||
element: element.unchecked_into(),
|
||||
#[cfg(not(all(target_arch = "wasm32", feature = "web")))]
|
||||
id,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
||||
impl std::ops::Deref for Custom {
|
||||
type Target = web_sys::HtmlElement;
|
||||
|
|
|
@ -554,7 +554,7 @@ fn element_to_tokens(cx: &Ident, node: &NodeElement, mut parent_type: TagType) -
|
|||
let tag = node.name.to_string();
|
||||
let name = if is_custom_element(&tag) {
|
||||
let name = node.name.to_string();
|
||||
quote! { leptos::leptos_dom::custom(#cx, #name) }
|
||||
quote! { leptos::leptos_dom::custom(#cx, leptos::leptos_dom::Custom::new(#name)) }
|
||||
} else if is_svg_element(&tag) {
|
||||
let name = &node.name;
|
||||
parent_type = TagType::Svg;
|
||||
|
|
Loading…
Reference in a new issue