mirror of
https://github.com/DioxusLabs/dioxus
synced 2024-11-23 12:43:08 +00:00
combine style and class attributes when there are multiple
This commit is contained in:
parent
1a17ca988c
commit
9f1c735cf1
3 changed files with 76 additions and 7 deletions
|
@ -13,14 +13,14 @@ pub struct ElementAttrNamed {
|
|||
}
|
||||
|
||||
impl ElementAttrNamed {
|
||||
pub(crate) fn try_combine(&self, other: Self) -> Option<Self> {
|
||||
pub(crate) fn try_combine(&self, other: &Self) -> Option<Self> {
|
||||
if self.el_name == other.el_name && self.attr.name == other.attr.name {
|
||||
if let Some(separator) = todo!() {
|
||||
if let Some(separator) = self.attr.name.multi_attribute_separator() {
|
||||
return Some(ElementAttrNamed {
|
||||
el_name: self.el_name.clone(),
|
||||
attr: ElementAttr {
|
||||
name: self.attr.name.clone(),
|
||||
value: self.attr.value.combine(separator, other.attr.value),
|
||||
value: self.attr.value.combine(separator, &other.attr.value),
|
||||
},
|
||||
});
|
||||
}
|
||||
|
@ -109,8 +109,33 @@ pub enum ElementAttrValue {
|
|||
}
|
||||
|
||||
impl ElementAttrValue {
|
||||
fn combine(&self, separator: &str, other: Self) -> Self {
|
||||
todo!()
|
||||
fn combine(&self, separator: &str, other: &Self) -> Self {
|
||||
match (self, other) {
|
||||
(Self::AttrLiteral(lit1), Self::AttrLiteral(lit2)) => {
|
||||
let fmt = lit1.clone().join(lit2.clone(), separator);
|
||||
Self::AttrLiteral(fmt)
|
||||
}
|
||||
(Self::AttrLiteral(expr1), Self::AttrExpr(expr2)) => {
|
||||
let mut ifmt = expr1.clone();
|
||||
ifmt.push_str(separator);
|
||||
ifmt.push_expr(expr2.clone());
|
||||
Self::AttrLiteral(ifmt)
|
||||
}
|
||||
(Self::AttrExpr(expr1), Self::AttrLiteral(expr2)) => {
|
||||
let mut ifmt = expr2.clone();
|
||||
ifmt.push_str(separator);
|
||||
ifmt.push_expr(expr1.clone());
|
||||
Self::AttrLiteral(ifmt)
|
||||
}
|
||||
(Self::AttrExpr(expr1), Self::AttrExpr(expr2)) => {
|
||||
let mut ifmt = IfmtInput::default();
|
||||
ifmt.push_expr(expr1.clone());
|
||||
ifmt.push_str(separator);
|
||||
ifmt.push_expr(expr2.clone());
|
||||
Self::AttrLiteral(ifmt)
|
||||
}
|
||||
_ => todo!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -121,6 +146,17 @@ pub enum ElementAttrName {
|
|||
}
|
||||
|
||||
impl ElementAttrName {
|
||||
fn multi_attribute_separator(&self) -> Option<&'static str> {
|
||||
match self {
|
||||
ElementAttrName::BuiltIn(i) => match i.to_string().as_str() {
|
||||
"class" => Some(" "),
|
||||
"style" => Some(";"),
|
||||
_ => None,
|
||||
},
|
||||
ElementAttrName::Custom(_) => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn start(&self) -> Span {
|
||||
match self {
|
||||
ElementAttrName::BuiltIn(i) => i.span(),
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
use std::fmt::{Display, Formatter};
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
fmt::{Display, Formatter},
|
||||
};
|
||||
|
||||
use super::*;
|
||||
|
||||
|
@ -134,6 +137,17 @@ impl Parse for Element {
|
|||
|
||||
// Deduplicate any attributes that can be combined
|
||||
// For example, if there are two `class` attributes, combine them into one
|
||||
let mut combined_attrs: HashMap<ElementAttrName, ElementAttrNamed> = HashMap::new();
|
||||
for attr in attributes {
|
||||
if let Some(old_attr) = combined_attrs.get_mut(&attr.attr.name) {
|
||||
if let Some(combined) = old_attr.try_combine(&attr) {
|
||||
*old_attr = combined;
|
||||
}
|
||||
} else {
|
||||
combined_attrs.insert(attr.attr.name.clone(), attr);
|
||||
}
|
||||
}
|
||||
let attributes: Vec<_> = combined_attrs.into_iter().map(|(_, v)| v).collect();
|
||||
|
||||
while !content.is_empty() {
|
||||
if (content.peek(LitStr) && content.peek2(Token![:])) && !content.peek3(Token![:]) {
|
||||
|
|
|
@ -13,7 +13,7 @@ pub fn format_args_f_impl(input: IfmtInput) -> Result<TokenStream> {
|
|||
}
|
||||
|
||||
#[allow(dead_code)] // dumb compiler does not see the struct being used...
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Hash)]
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Hash, Default)]
|
||||
pub struct IfmtInput {
|
||||
pub source: Option<LitStr>,
|
||||
pub segments: Vec<Segment>,
|
||||
|
@ -27,6 +27,25 @@ impl IfmtInput {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn join(mut self, other: Self, separator: &str) -> Self {
|
||||
if !self.segments.is_empty() {
|
||||
self.segments.push(Segment::Literal(separator.to_string()));
|
||||
}
|
||||
self.segments.extend(other.segments);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn push_expr(&mut self, expr: Expr) {
|
||||
self.segments.push(Segment::Formatted(FormattedSegment {
|
||||
format_args: String::new(),
|
||||
segment: FormattedSegmentType::Expr(Box::new(expr)),
|
||||
}));
|
||||
}
|
||||
|
||||
pub fn push_str(&mut self, s: &str) {
|
||||
self.segments.push(Segment::Literal(s.to_string()));
|
||||
}
|
||||
|
||||
pub fn is_static(&self) -> bool {
|
||||
matches!(self.segments.as_slice(), &[Segment::Literal(_)] | &[])
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue