Merge pull request #473 from Demonthos/fix_hot_reloading_svg_attributes

Fix hot reloading svg attributes
This commit is contained in:
Jon Kelley authored and GitHub committed 2022-07-02 22:58:07 -04:00
commit faf1103597
4 files changed
+45 -29

No files matched your search

+28 -14
View File
@@ -1,7 +1,17 @@
use crate::elements::*; use crate::elements::*;
// map the rsx name of the attribute to the html name of the attribute and the namespace that contains it // map the rsx name of the attribute to the html name of the attribute and the namespace that contains it
pub fn attrbute_to_static_str(attr: &str) -> Option<(&'static str, Option<&'static str>)> { pub fn attrbute_to_static_str(
attr: &str,
element: &'static str,
namespace: Option<&'static str>,
) -> Option<(&'static str, Option<&'static str>)> {
if namespace == Some("http://www.w3.org/2000/svg") {
svg::MAPPED_ATTRIBUTES
.iter()
.find(|(a, _)| *a == attr)
.map(|(_, b)| (*b, None))
} else {
NO_NAMESPACE_ATTRIBUTES NO_NAMESPACE_ATTRIBUTES
.iter() .iter()
.find(|&a| *a == attr) .find(|&a| *a == attr)
@@ -18,31 +28,34 @@ pub fn attrbute_to_static_str(attr: &str) -> Option<(&'static str, Option<&'stat
.find(|(a, _)| *a == attr) .find(|(a, _)| *a == attr)
.map(|(_, b)| (*b, None)) .map(|(_, b)| (*b, None))
}) })
.or_else(|| { }
svg::MAPPED_ATTRIBUTES
.iter()
.find(|(a, _)| *a == attr)
.map(|(_, b)| (*b, None))
})
.or_else(|| { .or_else(|| {
ELEMENTS_WITH_MAPPED_ATTRIBUTES ELEMENTS_WITH_MAPPED_ATTRIBUTES
.iter() .iter()
.find_map(|(_, attrs)| { .find_map(|(el, attrs)| {
(element == *el)
.then(|| {
attrs attrs
.iter() .iter()
.find(|(a, _)| *a == attr) .find(|(a, _)| *a == attr)
.map(|(_, b)| (*b, None)) .map(|(_, b)| (*b, None))
}) })
.flatten()
})
}) })
.or_else(|| { .or_else(|| {
ELEMENTS_WITH_NAMESPACE ELEMENTS_WITH_NAMESPACE.iter().find_map(|(el, ns, attrs)| {
.iter() (element == *el && namespace == Some(*ns))
.find_map(|(_, _, attrs)| attrs.iter().find(|a| **a == attr).map(|a| (*a, None))) .then(|| attrs.iter().find(|a| **a == attr).map(|a| (*a, None)))
.flatten()
})
}) })
.or_else(|| { .or_else(|| {
ELEMENTS_WITHOUT_NAMESPACE ELEMENTS_WITHOUT_NAMESPACE.iter().find_map(|(el, attrs)| {
.iter() (element == *el)
.find_map(|(_, attrs)| attrs.iter().find(|a| **a == attr).map(|a| (*a, None))) .then(|| attrs.iter().find(|a| **a == attr).map(|a| (*a, None)))
.flatten()
})
}) })
} }
@@ -615,6 +628,7 @@ mapped_trait_methods! {
} }
pub mod svg { pub mod svg {
mapped_trait_methods! { mapped_trait_methods! {
accent_height: "accent-height", accent_height: "accent-height",
accumulate: "accumulate", accumulate: "accumulate",
@@ -182,9 +182,11 @@ impl<'a> CapturedContext<'a> {
pub fn attrbute_to_static_str( pub fn attrbute_to_static_str(
&self, &self,
attr: &str, attr: &str,
tag: &'static str,
ns: Option<&'static str>,
literal: bool, literal: bool,
) -> Option<(&'static str, Option<&'static str>)> { ) -> Option<(&'static str, Option<&'static str>)> {
if let Some(attr) = attrbute_to_static_str(attr) { if let Some(attr) = attrbute_to_static_str(attr, tag, ns) {
Some(attr) Some(attr)
} else if literal { } else if literal {
self.custom_attributes self.custom_attributes
+1 -1
View File
@@ -54,7 +54,7 @@ macro_rules! builder_constructors {
$( $(
( (
stringify!($name), stringify!($name),
stringify!($namespace), $namespace,
&[ &[
$( $(
stringify!($fil), stringify!($fil),
+13 -13
View File
@@ -76,6 +76,8 @@ fn build_node<'a>(
} }
BodyNode::Element(el) => { BodyNode::Element(el) => {
let attributes: &mut Vec<Attribute> = bump.alloc(Vec::new()); let attributes: &mut Vec<Attribute> = bump.alloc(Vec::new());
let tag = &el.name.to_string();
if let Some((tag, ns)) = element_to_static_str(tag) {
for attr in &el.attributes { for attr in &el.attributes {
match &attr.attr { match &attr.attr {
ElementAttr::AttrText { .. } | ElementAttr::CustomAttrText { .. } => { ElementAttr::AttrText { .. } | ElementAttr::CustomAttrText { .. } => {
@@ -106,7 +108,8 @@ fn build_node<'a>(
_ => unreachable!(), _ => unreachable!(),
}; };
if let Some((name, namespace)) = ctx.attrbute_to_static_str(&name, literal) if let Some((name, namespace)) =
ctx.attrbute_to_static_str(&name, tag, ns, literal)
{ {
let value = bump.alloc(resolve_ifmt(&value, &ctx.captured)?); let value = bump.alloc(resolve_ifmt(&value, &ctx.captured)?);
attributes.push(Attribute { attributes.push(Attribute {
@@ -124,7 +127,10 @@ fn build_node<'a>(
)); ));
} else { } else {
return Err(Error::ParseError(ParseError::new( return Err(Error::ParseError(ParseError::new(
syn::Error::new(span, format!("unknown attribute: {}", name)), syn::Error::new(
span,
format!("unknown attribute: {}", name),
),
ctx.location.clone(), ctx.location.clone(),
))); )));
} }
@@ -148,7 +154,7 @@ fn build_node<'a>(
.find(|(n, _)| parse_str::<Expr>(*n).unwrap() == *value) .find(|(n, _)| parse_str::<Expr>(*n).unwrap() == *value)
{ {
if let Some((name, namespace)) = if let Some((name, namespace)) =
ctx.attrbute_to_static_str(&name, literal) ctx.attrbute_to_static_str(&name, tag, ns, literal)
{ {
let value = bump.alloc(resulting_value.clone()); let value = bump.alloc(resulting_value.clone());
attributes.push(Attribute { attributes.push(Attribute {
@@ -174,16 +180,10 @@ fn build_node<'a>(
))); )));
} }
} }
} else {
return Err(Error::RecompileRequiredError(
RecompileReason::CapturedExpression(
value.into_token_stream().to_string(),
),
));
} }
} }
_ => (), _ => (),
}; }
} }
let children = bump.alloc(Vec::new()); let children = bump.alloc(Vec::new());
for child in el.children { for child in el.children {
@@ -207,13 +207,13 @@ fn build_node<'a>(
listeners.push(listener) listeners.push(listener)
} else { } else {
return Err(Error::RecompileRequiredError( return Err(Error::RecompileRequiredError(
RecompileReason::CapturedListener(expr.to_token_stream().to_string()), RecompileReason::CapturedListener(
expr.to_token_stream().to_string(),
),
)); ));
} }
} }
} }
let tag = bump.alloc(el.name.to_string());
if let Some((tag, ns)) = element_to_static_str(tag) {
match el.key { match el.key {
None => Ok(factory.raw_element( None => Ok(factory.raw_element(
tag, tag,