123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111 |
- use dioxus_core::TemplateNode;
- use dioxus_core_types::HotReloadingContext;
- use dioxus_rsx::*;
- use internment::Intern;
- use std::hash::Hash;
- // interns a object into a static object, reusing the value if it already exists
- pub(crate) fn intern<T: Eq + Hash + Send + Sync + ?Sized + 'static>(
- s: impl Into<Intern<T>>,
- ) -> &'static T {
- s.into().as_ref()
- }
- pub(crate) fn html_tag_and_namespace<Ctx: HotReloadingContext>(
- attr: &Attribute,
- ) -> (&'static str, Option<&'static str>) {
- let attribute_name_rust = attr.name.to_string();
- let element_name = attr.el_name.as_ref().unwrap();
- let rust_name = match element_name {
- ElementName::Ident(i) => i.to_string(),
- // If this is a web component, just use the name of the elements instead of mapping the attribute
- // through the hot reloading context
- ElementName::Custom(_) => return (intern(attribute_name_rust.as_str()), None),
- };
- Ctx::map_attribute(&rust_name, &attribute_name_rust)
- .unwrap_or((intern(attribute_name_rust.as_str()), None))
- }
- pub fn to_template_attribute<Ctx: HotReloadingContext>(
- attr: &Attribute,
- ) -> dioxus_core::TemplateAttribute {
- use dioxus_core::TemplateAttribute;
- // If it's a dynamic node, just return it
- // For dynamic attributes, we need to check the mapping to see if that mapping exists
- // todo: one day we could generate new dynamic attributes on the fly if they're a literal,
- // or something sufficiently serializable
- // (ie `checked`` being a bool and bools being interpretable)
- //
- // For now, just give up if that attribute doesn't exist in the mapping
- if !attr.is_static_str_literal() {
- let id = attr.dyn_idx.get();
- return TemplateAttribute::Dynamic { id };
- }
- // Otherwise it's a static node and we can build it
- let (_, value) = attr.as_static_str_literal().unwrap();
- let (name, namespace) = html_tag_and_namespace::<Ctx>(attr);
- TemplateAttribute::Static {
- name,
- namespace,
- value: intern(value.to_static().unwrap().as_str()),
- }
- }
- /// Convert this BodyNode into a TemplateNode.
- ///
- /// dioxus-core uses this to understand templates at compiletime
- pub fn to_template_node<Ctx: HotReloadingContext>(node: &BodyNode) -> dioxus_core::TemplateNode {
- use dioxus_core::TemplateNode;
- match node {
- BodyNode::Element(el) => {
- let rust_name = el.name.to_string();
- let (tag, namespace) =
- Ctx::map_element(&rust_name).unwrap_or((intern(rust_name.as_str()), None));
- TemplateNode::Element {
- tag,
- namespace,
- children: intern(
- el.children
- .iter()
- .map(|c| to_template_node::<Ctx>(c))
- .collect::<Vec<_>>(),
- ),
- attrs: intern(
- el.merged_attributes
- .iter()
- .map(|attr| to_template_attribute::<Ctx>(attr))
- .collect::<Vec<_>>(),
- ),
- }
- }
- BodyNode::Text(text) => text_to_template_node(text),
- BodyNode::RawExpr(exp) => TemplateNode::Dynamic {
- id: exp.dyn_idx.get(),
- },
- BodyNode::Component(comp) => TemplateNode::Dynamic {
- id: comp.dyn_idx.get(),
- },
- BodyNode::ForLoop(floop) => TemplateNode::Dynamic {
- id: floop.dyn_idx.get(),
- },
- BodyNode::IfChain(chain) => TemplateNode::Dynamic {
- id: chain.dyn_idx.get(),
- },
- }
- }
- pub fn text_to_template_node(node: &TextNode) -> TemplateNode {
- match node.input.to_static() {
- Some(text) => TemplateNode::Text {
- text: intern(text.as_str()),
- },
- None => TemplateNode::Dynamic {
- id: node.dyn_idx.get(),
- },
- }
- }
|