Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 14 additions & 52 deletions packages/yew-macro/src/html_tree/html_element.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
use proc_macro2::{Delimiter, Span, TokenStream};
use proc_macro2::{Delimiter, Group, Span, TokenStream};
use proc_macro_error::emit_warning;
use quote::{quote, quote_spanned, ToTokens};
use syn::buffer::Cursor;
use syn::parse::{Parse, ParseStream};
use syn::spanned::Spanned;
use syn::{Block, Expr, Ident, Lit, LitStr, Token};
use syn::{Expr, Ident, Lit, LitStr, Token};

use super::{HtmlChildrenTree, HtmlDashedName, TagTokens};
use crate::props::{ClassesForm, ElementProps, Prop, PropDirective};
use crate::props::{ElementProps, Prop, PropDirective};
use crate::stringify::{Stringify, Value};
use crate::{is_ide_completion, non_capitalized_ascii, Peek, PeekValue};

Expand Down Expand Up @@ -190,39 +190,11 @@ impl ToTokens for HtmlElement {
))
},
);
let class_attr = classes.as_ref().and_then(|classes| match classes {
ClassesForm::Tuple(classes) => {
let span = classes.span();
let classes: Vec<_> = classes.elems.iter().collect();
let n = classes.len();

let deprecation_warning = quote_spanned! {span=>
#[deprecated(
note = "the use of `(...)` with the attribute `class` is deprecated and will be removed in version 0.19. Use the `classes!` macro instead."
)]
fn deprecated_use_of_class() {}

if false {
deprecated_use_of_class();
};
};

Some((
LitStr::new("class", span),
Value::Dynamic(quote! {
{
#deprecation_warning

let mut __yew_classes = ::yew::html::Classes::with_capacity(#n);
#(__yew_classes.push(#classes);)*
__yew_classes
}
}),
None,
))
}
ClassesForm::Single(classes) => {
match classes.try_into_lit() {
let class_attr =
classes
.as_ref()
.and_then(|classes| match classes.value.try_into_lit() {
Some(lit) => {
if lit.value().is_empty() {
None
Expand All @@ -235,17 +207,16 @@ impl ToTokens for HtmlElement {
}
}
None => {
let expr = &classes.value;
Some((
LitStr::new("class", classes.span()),
LitStr::new("class", classes.label.span()),
Value::Dynamic(quote! {
::std::convert::Into::<::yew::html::Classes>::into(#classes)
::std::convert::Into::<::yew::html::Classes>::into(#expr)
}),
None,
))
}
}
}
});
});

fn apply_as(directive: Option<&PropDirective>) -> TokenStream {
match directive {
Expand Down Expand Up @@ -383,7 +354,7 @@ impl ToTokens for HtmlElement {
}
TagName::Expr(name) => {
let vtag = Ident::new("__yew_vtag", name.span());
let expr = &name.expr;
let expr = name.expr.as_ref().map(Group::stream);
let vtag_name = Ident::new("__yew_vtag_name", expr.span());

let void_children = Ident::new("__yew_void_children", Span::mixed_site());
Expand Down Expand Up @@ -411,10 +382,6 @@ impl ToTokens for HtmlElement {
// this way we get a nice error message (with the correct span) when the expression
// doesn't return a valid value
quote_spanned! {expr.span()=> {
#[allow(unused_braces)]
// e.g. html!{<@{"div"}/>} will set `#expr` to `{"div"}`
// (note the extra braces). Hence the need for the `allow`.
// Anyways to remove the braces?
let mut #vtag_name = ::std::convert::Into::<
::yew::virtual_dom::AttrValue
>::into(#expr);
Expand Down Expand Up @@ -500,7 +467,7 @@ fn wrap_attr_value<T: ToTokens>(value: T) -> TokenStream {

pub struct DynamicName {
at: Token![@],
expr: Option<Block>,
expr: Option<Group>,
}

impl Peek<'_, ()> for DynamicName {
Expand All @@ -524,12 +491,7 @@ impl Parse for DynamicName {
fn parse(input: ParseStream) -> syn::Result<Self> {
let at = input.parse()?;
// the expression block is optional, closing tags don't have it.
let expr = if input.cursor().group(Delimiter::Brace).is_some() {
Some(input.parse()?)
} else {
None
};

let expr = input.parse().ok();
Ok(Self { at, expr })
}
}
Expand Down
20 changes: 2 additions & 18 deletions packages/yew-macro/src/props/element.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,13 @@ use std::collections::HashSet;

use once_cell::sync::Lazy;
use syn::parse::{Parse, ParseStream};
use syn::{Expr, ExprTuple};

use super::{Prop, Props, SpecialProps};

pub enum ClassesForm {
Tuple(ExprTuple),
Single(Box<Expr>),
}
impl ClassesForm {
fn from_expr(expr: Expr) -> Self {
match expr {
Expr::Tuple(expr_tuple) => ClassesForm::Tuple(expr_tuple),
expr => ClassesForm::Single(Box::new(expr)),
}
}
}

pub struct ElementProps {
pub attributes: Vec<Prop>,
pub listeners: Vec<Prop>,
pub classes: Option<ClassesForm>,
pub classes: Option<Prop>,
pub booleans: Vec<Prop>,
pub value: Option<Prop>,
pub checked: Option<Prop>,
Expand All @@ -42,9 +28,7 @@ impl Parse for ElementProps {
let booleans =
props.drain_filter(|prop| BOOLEAN_SET.contains(prop.label.to_string().as_str()));

let classes = props
.pop("class")
.map(|prop| ClassesForm::from_expr(prop.value));
let classes = props.pop("class");
let value = props.pop("value");
let checked = props.pop("checked");
let special = props.special;
Expand Down
16 changes: 8 additions & 8 deletions packages/yew-macro/tests/html_macro/block-pass.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,27 +37,27 @@ pub struct u8;
pub struct usize;

fn main() {
::yew::html! { <>{ "Hi" }</> };
::yew::html! { <>{ ::std::format!("Hello") }</> };
::yew::html! { <>{ ::std::string::ToString::to_string("Hello") }</> };
_ = ::yew::html! { <>{ "Hi" }</> };
_ = ::yew::html! { <>{ ::std::format!("Hello") }</> };
_ = ::yew::html! { <>{ ::std::string::ToString::to_string("Hello") }</> };

let msg = "Hello";
::yew::html! { <div>{ msg }</div> };
_ = ::yew::html! { <div>{ msg }</div> };

let subview = ::yew::html! { "subview!" };
::yew::html! { <div>{ subview }</div> };
_ = ::yew::html! { <div>{ subview }</div> };

let subview = || ::yew::html! { "subview!" };
::yew::html! { <div>{ subview() }</div> };
_ = ::yew::html! { <div>{ subview() }</div> };

::yew::html! {
_ = ::yew::html! {
<ul>
{ for ::std::iter::Iterator::map(0..3, |num| { ::yew::html! { <span>{ num }</span> }}) }
</ul>
};

let item = |num| ::yew::html! { <li>{ ::std::format!("item {}!", num) }</li> };
::yew::html! {
_ = ::yew::html! {
<ul>
{ for ::std::iter::Iterator::map(0..3, item) }
</ul>
Expand Down
28 changes: 14 additions & 14 deletions packages/yew-macro/tests/html_macro/component-any-children-pass.rs
Original file line number Diff line number Diff line change
Expand Up @@ -159,10 +159,10 @@ pub fn RenderPropComp(_props: &RenderPropProps) -> ::yew::Html {
}

fn compile_pass() {
::yew::html! { <Child int=1 /> };
::yew::html! { <Child int=1 r#fn=1 /> };
_ = ::yew::html! { <Child int=1 /> };
_ = ::yew::html! { <Child int=1 r#fn=1 /> };

::yew::html! {
_ = ::yew::html! {
<>
<Child int=1 />
<scoped::Child int=1 />
Expand All @@ -171,7 +171,7 @@ fn compile_pass() {

let props = <<Child as ::yew::Component>::Properties as ::std::default::Default>::default();
let node_ref = <::yew::NodeRef as ::std::default::Default>::default();
::yew::html! {
_ = ::yew::html! {
<>
<Child ..::std::clone::Clone::clone(&props) />
<Child int={1} ..props />
Expand All @@ -183,7 +183,7 @@ fn compile_pass() {
</>
};

::yew::html! {
_ = ::yew::html! {
<>
<Child int=1 string="child" />
<Child int=1 />
Expand All @@ -199,17 +199,17 @@ fn compile_pass() {
};

let name_expr = "child";
::yew::html! {
_ = ::yew::html! {
<Child int=1 string={name_expr} />
};

let string = "child";
let int = 1;
::yew::html! {
_ = ::yew::html! {
<Child {int} {string} />
};

::yew::html! {
_ = ::yew::html! {
<>
<Child int=1 />
<Child int=1 optional_callback={::std::option::Option::Some(<::yew::Callback<()> as ::std::convert::From<_>>::from(|_| ()))} />
Expand All @@ -219,15 +219,15 @@ fn compile_pass() {
};

let node_ref = <::yew::NodeRef as ::std::default::Default>::default();
::yew::html! {
_ = ::yew::html! {
<>
<Child int=1 r#ref={node_ref} />
</>
};

let int = 1;
let node_ref = <::yew::NodeRef as ::std::default::Default>::default();
::yew::html! {
_ = ::yew::html! {
<>
<Child {int} r#ref={node_ref} />
</>
Expand All @@ -236,7 +236,7 @@ fn compile_pass() {
let props = <<Container as ::yew::Component>::Properties as ::std::default::Default>::default();
let child_props =
<<Child as ::yew::Component>::Properties as ::std::default::Default>::default();
::yew::html! {
_ = ::yew::html! {
<>
<Container int=1 />
<Container int=1></Container>
Expand Down Expand Up @@ -292,7 +292,7 @@ fn compile_pass() {
]
};

::yew::html! {
_ = ::yew::html! {
<>
{
::std::iter::Iterator::collect::<::yew::virtual_dom::VNode>(
Expand Down Expand Up @@ -321,9 +321,9 @@ fn compile_pass() {
</>
};

::yew::html_nested! { 1 };
_ = ::yew::html_nested! { 1 };

::yew::html! {
_ = ::yew::html! {
<RenderPropComp>
{|_arg| {}}
</RenderPropComp>
Expand Down
Loading