✨ (macros): Permite (expr) como atributo en html!
Introduce `Attribute::Splice` en el AST de Maud, de modo que `(expr)` en posición de atributo renderiza la expresión directamente sobre el buffer de salida del elemento.
This commit is contained in:
parent
47b6553fe4
commit
35a5221c92
2 changed files with 24 additions and 2 deletions
|
|
@ -212,6 +212,7 @@ impl DiagnosticParse for Element {
|
|||
|| input.peek(Lit)
|
||||
|| input.peek(Dot)
|
||||
|| input.peek(Pound)
|
||||
|| input.peek(Paren)
|
||||
{
|
||||
let attr = input.diagnostic_parse(diagnostics)?;
|
||||
|
||||
|
|
@ -346,6 +347,10 @@ pub enum Attribute {
|
|||
name: HtmlName,
|
||||
attr_type: AttributeType,
|
||||
},
|
||||
Splice {
|
||||
paren_token: Paren,
|
||||
expr: Expr,
|
||||
},
|
||||
}
|
||||
|
||||
impl DiagnosticParse for Attribute {
|
||||
|
|
@ -374,6 +379,12 @@ impl DiagnosticParse for Attribute {
|
|||
pound_token: input.parse()?,
|
||||
name: input.diagnostic_parse(diagnostics)?,
|
||||
})
|
||||
} else if lookahead.peek(Paren) {
|
||||
let content;
|
||||
Ok(Self::Splice {
|
||||
paren_token: parenthesized!(content in input),
|
||||
expr: content.parse()?,
|
||||
})
|
||||
} else {
|
||||
let name = input.diagnostic_parse::<HtmlName>(diagnostics)?;
|
||||
|
||||
|
|
@ -424,6 +435,11 @@ impl ToTokens for Attribute {
|
|||
name.to_tokens(tokens);
|
||||
attr_type.to_tokens(tokens);
|
||||
}
|
||||
Self::Splice { paren_token, expr } => {
|
||||
paren_token.surround(tokens, |tokens| {
|
||||
expr.to_tokens(tokens);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -139,7 +139,7 @@ impl Generator {
|
|||
}
|
||||
|
||||
fn attrs(&self, attrs: Vec<Attribute>, build: &mut Builder) {
|
||||
let (classes, id, named_attrs) = split_attrs(attrs);
|
||||
let (classes, id, named_attrs, spliced) = split_attrs(attrs);
|
||||
|
||||
if !classes.is_empty() {
|
||||
let mut toggle_class_exprs = vec![];
|
||||
|
|
@ -184,6 +184,9 @@ impl Generator {
|
|||
for (name, attr_type) in named_attrs {
|
||||
self.attr(name, attr_type, build);
|
||||
}
|
||||
for expr in spliced {
|
||||
self.splice(expr, build);
|
||||
}
|
||||
}
|
||||
|
||||
fn control_flow<E: Into<Element>>(&self, control_flow: ControlFlow<E>, build: &mut Builder) {
|
||||
|
|
@ -316,10 +319,12 @@ fn split_attrs(
|
|||
Vec<(HtmlNameOrMarkup, Option<Expr>)>,
|
||||
Option<HtmlNameOrMarkup>,
|
||||
Vec<(HtmlName, AttributeType)>,
|
||||
Vec<Expr>,
|
||||
) {
|
||||
let mut classes = vec![];
|
||||
let mut id = None;
|
||||
let mut named_attrs = vec![];
|
||||
let mut spliced = vec![];
|
||||
|
||||
for attr in attrs {
|
||||
match attr {
|
||||
|
|
@ -328,10 +333,11 @@ fn split_attrs(
|
|||
}
|
||||
Attribute::Id { name, .. } => id = Some(name),
|
||||
Attribute::Named { name, attr_type } => named_attrs.push((name, attr_type)),
|
||||
Attribute::Splice { expr, .. } => spliced.push(expr),
|
||||
}
|
||||
}
|
||||
|
||||
(classes, id, named_attrs)
|
||||
(classes, id, named_attrs, spliced)
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue