mirror of
https://github.com/leptos-rs/leptos
synced 2024-11-10 06:44:17 +00:00
fix: do not sort class and style that are after spread marker
This commit is contained in:
parent
f3dcdc057d
commit
8dc600ca02
1 changed files with 43 additions and 20 deletions
|
@ -279,10 +279,25 @@ pub(crate) fn element_to_tokens(
|
||||||
global_class: Option<&TokenTree>,
|
global_class: Option<&TokenTree>,
|
||||||
view_marker: Option<&str>,
|
view_marker: Option<&str>,
|
||||||
) -> Option<TokenStream> {
|
) -> Option<TokenStream> {
|
||||||
|
// attribute sorting:
|
||||||
|
//
|
||||||
// the `class` and `style` attributes overwrite individual `class:` and `style:` attributes
|
// the `class` and `style` attributes overwrite individual `class:` and `style:` attributes
|
||||||
// when they are set. as a result, we're going to sort the attributes so that `class` and
|
// when they are set. as a result, we're going to sort the attributes so that `class` and
|
||||||
// `style` always come before all other attributes.
|
// `style` always come before all other attributes.
|
||||||
node.attributes_mut().sort_by(|a, b| {
|
|
||||||
|
// if there's a spread marker, we don't want to move `class` or `style` before it
|
||||||
|
// so let's only sort attributes that come *before* a spread marker
|
||||||
|
let spread_position = node
|
||||||
|
.attributes()
|
||||||
|
.iter()
|
||||||
|
.position(|n| match n {
|
||||||
|
NodeAttribute::Block(node) => as_spread_attr(node).is_some(),
|
||||||
|
_ => false,
|
||||||
|
})
|
||||||
|
.unwrap_or_else(|| node.attributes().len());
|
||||||
|
|
||||||
|
// now, sort the attributes
|
||||||
|
node.attributes_mut()[0..spread_position].sort_by(|a, b| {
|
||||||
let key_a = match a {
|
let key_a = match a {
|
||||||
NodeAttribute::Attribute(attr) => match &attr.key {
|
NodeAttribute::Attribute(attr) => match &attr.key {
|
||||||
NodeName::Path(attr) => {
|
NodeName::Path(attr) => {
|
||||||
|
@ -496,6 +511,25 @@ fn is_spread_marker(node: &NodeElement<impl CustomNode>) -> bool {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn as_spread_attr(node: &NodeBlock) -> Option<Option<&Expr>> {
|
||||||
|
if let NodeBlock::ValidBlock(block) = node {
|
||||||
|
match block.stmts.first() {
|
||||||
|
Some(Stmt::Expr(
|
||||||
|
Expr::Range(ExprRange {
|
||||||
|
start: None,
|
||||||
|
limits: RangeLimits::HalfOpen(_),
|
||||||
|
end,
|
||||||
|
..
|
||||||
|
}),
|
||||||
|
_,
|
||||||
|
)) => Some(end.as_deref()),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn attribute_to_tokens(
|
fn attribute_to_tokens(
|
||||||
tag_type: TagType,
|
tag_type: TagType,
|
||||||
node: &NodeAttribute,
|
node: &NodeAttribute,
|
||||||
|
@ -503,29 +537,18 @@ fn attribute_to_tokens(
|
||||||
is_custom: bool,
|
is_custom: bool,
|
||||||
) -> TokenStream {
|
) -> TokenStream {
|
||||||
match node {
|
match node {
|
||||||
NodeAttribute::Block(node) => {
|
NodeAttribute::Block(node) => as_spread_attr(node)
|
||||||
let dotted = if let NodeBlock::ValidBlock(block) = node {
|
.flatten()
|
||||||
match block.stmts.first() {
|
.map(|end| {
|
||||||
Some(Stmt::Expr(
|
quote! {
|
||||||
Expr::Range(ExprRange {
|
.add_any_attr(#end)
|
||||||
start: None,
|
|
||||||
limits: RangeLimits::HalfOpen(_),
|
|
||||||
end: Some(end),
|
|
||||||
..
|
|
||||||
}),
|
|
||||||
_,
|
|
||||||
)) => Some(quote! { .add_any_attr(#end) }),
|
|
||||||
_ => None,
|
|
||||||
}
|
}
|
||||||
} else {
|
})
|
||||||
None
|
.unwrap_or_else(|| {
|
||||||
};
|
|
||||||
dotted.unwrap_or_else(|| {
|
|
||||||
quote! {
|
quote! {
|
||||||
.add_any_attr(#[allow(unused_braces)] { #node })
|
.add_any_attr(#[allow(unused_braces)] { #node })
|
||||||
}
|
}
|
||||||
})
|
}),
|
||||||
}
|
|
||||||
NodeAttribute::Attribute(node) => {
|
NodeAttribute::Attribute(node) => {
|
||||||
let name = node.key.to_string();
|
let name = node.key.to_string();
|
||||||
if name == "node_ref" {
|
if name == "node_ref" {
|
||||||
|
|
Loading…
Reference in a new issue