✨ (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(Lit)
|
||||||
|| input.peek(Dot)
|
|| input.peek(Dot)
|
||||||
|| input.peek(Pound)
|
|| input.peek(Pound)
|
||||||
|
|| input.peek(Paren)
|
||||||
{
|
{
|
||||||
let attr = input.diagnostic_parse(diagnostics)?;
|
let attr = input.diagnostic_parse(diagnostics)?;
|
||||||
|
|
||||||
|
|
@ -346,6 +347,10 @@ pub enum Attribute {
|
||||||
name: HtmlName,
|
name: HtmlName,
|
||||||
attr_type: AttributeType,
|
attr_type: AttributeType,
|
||||||
},
|
},
|
||||||
|
Splice {
|
||||||
|
paren_token: Paren,
|
||||||
|
expr: Expr,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DiagnosticParse for Attribute {
|
impl DiagnosticParse for Attribute {
|
||||||
|
|
@ -374,6 +379,12 @@ impl DiagnosticParse for Attribute {
|
||||||
pound_token: input.parse()?,
|
pound_token: input.parse()?,
|
||||||
name: input.diagnostic_parse(diagnostics)?,
|
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 {
|
} else {
|
||||||
let name = input.diagnostic_parse::<HtmlName>(diagnostics)?;
|
let name = input.diagnostic_parse::<HtmlName>(diagnostics)?;
|
||||||
|
|
||||||
|
|
@ -424,6 +435,11 @@ impl ToTokens for Attribute {
|
||||||
name.to_tokens(tokens);
|
name.to_tokens(tokens);
|
||||||
attr_type.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) {
|
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() {
|
if !classes.is_empty() {
|
||||||
let mut toggle_class_exprs = vec![];
|
let mut toggle_class_exprs = vec![];
|
||||||
|
|
@ -184,6 +184,9 @@ impl Generator {
|
||||||
for (name, attr_type) in named_attrs {
|
for (name, attr_type) in named_attrs {
|
||||||
self.attr(name, attr_type, build);
|
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) {
|
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>)>,
|
Vec<(HtmlNameOrMarkup, Option<Expr>)>,
|
||||||
Option<HtmlNameOrMarkup>,
|
Option<HtmlNameOrMarkup>,
|
||||||
Vec<(HtmlName, AttributeType)>,
|
Vec<(HtmlName, AttributeType)>,
|
||||||
|
Vec<Expr>,
|
||||||
) {
|
) {
|
||||||
let mut classes = vec![];
|
let mut classes = vec![];
|
||||||
let mut id = None;
|
let mut id = None;
|
||||||
let mut named_attrs = vec![];
|
let mut named_attrs = vec![];
|
||||||
|
let mut spliced = vec![];
|
||||||
|
|
||||||
for attr in attrs {
|
for attr in attrs {
|
||||||
match attr {
|
match attr {
|
||||||
|
|
@ -328,10 +333,11 @@ fn split_attrs(
|
||||||
}
|
}
|
||||||
Attribute::Id { name, .. } => id = Some(name),
|
Attribute::Id { name, .. } => id = Some(name),
|
||||||
Attribute::Named { name, attr_type } => named_attrs.push((name, attr_type)),
|
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