mirror of
https://github.com/leptos-rs/leptos
synced 2024-11-10 23:04:24 +00:00
Improvements to the view
macro to handle a wider variety of positions/relationships between child nodes
This commit is contained in:
parent
796764493b
commit
780c6d2e64
2 changed files with 99 additions and 9 deletions
|
@ -3,7 +3,76 @@ use leptos::*;
|
|||
pub fn main() {
|
||||
_ = console_log::init_with_level(log::Level::Debug);
|
||||
console_error_panic_hook::set_once();
|
||||
mount_to_body(|cx| view! { cx, <TemplateConsumer/> })
|
||||
mount_to_body(|cx| view! { cx, <Tests/> })
|
||||
}
|
||||
|
||||
#[component]
|
||||
fn Tests(cx: Scope) -> Element {
|
||||
view! {
|
||||
cx,
|
||||
<div>
|
||||
<div><BlockOrders/></div>
|
||||
//<div><TemplateConsumer/></div>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
||||
#[component]
|
||||
fn BlockOrders(cx: Scope) -> Element {
|
||||
let a = "A";
|
||||
let b = "B";
|
||||
let c = "C";
|
||||
|
||||
view! {
|
||||
cx,
|
||||
<div>
|
||||
<div>"A"</div>
|
||||
<div>{a}</div>
|
||||
<div><span>"A"</span></div>
|
||||
<div><span>{a}</span></div>
|
||||
<hr/>
|
||||
<div>"A" {b}</div>
|
||||
<div>{a} "B"</div>
|
||||
<div>{a} {b}</div>
|
||||
<div><span style="color: red">{a}</span> "B"</div>
|
||||
<div><span style="color: red">{a}</span> {b}</div>
|
||||
<hr/>
|
||||
<div>{a} "B" {c}</div>
|
||||
<div>"A" {b} "C"</div>
|
||||
<div>{a} {b} "C"</div>
|
||||
<div>{a} {b} {c}</div>
|
||||
<div>"A" {b} {c}</div>
|
||||
<hr/>
|
||||
<div>"A" {b} <span style="color: red">"C"</span></div>
|
||||
<div>"A" {b} <span style="color: red">{c}</span></div>
|
||||
<div>"A" <span style="color: red">"B"</span> "C"</div>
|
||||
<div>"A" <span style="color: red">"B"</span> {c}</div>
|
||||
<div>{a} <span style="color: red">{b}</span> {c}</div>
|
||||
<div>"A" {b} <span style="color: red">{c}</span></div>
|
||||
<div><span style="color: red">"A"</span> {b} {c}</div>
|
||||
<div><span style="color: red">{a}</span> "B" {c}</div>
|
||||
<div><span style="color: red">"A"</span> {b} "C"</div>
|
||||
<hr/>
|
||||
<div><span style="color: red">"A"</span> <span style="color: blue">{b}</span> {c}</div>
|
||||
<div><span style="color: red">{a}</span> "B" <span style="color: blue">{c}</span></div>
|
||||
//<div><span style="color: red">"A"</span> {b} <span style="color: blue">"C"</span></div>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
||||
#[component]
|
||||
fn A(cx: Scope) -> Element {
|
||||
view! { cx, <span style="color: red">"A"</span> }
|
||||
}
|
||||
|
||||
#[component]
|
||||
fn B(cx: Scope) -> Element {
|
||||
view! { cx, <span style="color: red">"B"</span> }
|
||||
}
|
||||
|
||||
#[component]
|
||||
fn C(cx: Scope) -> Element {
|
||||
view! { cx, <span style="color: red">"C"</span> }
|
||||
}
|
||||
|
||||
#[component]
|
||||
|
|
|
@ -351,6 +351,17 @@ fn element_to_tokens(
|
|||
// set next sib (for any insertions)
|
||||
let next_sib = next_sibling_node(&node.children, idx + 1, next_el_id);
|
||||
|
||||
let next_is_element = match node.children.get(idx + 1) {
|
||||
Some(Node::Element(_)) => true,
|
||||
_ => false
|
||||
};
|
||||
|
||||
let next_is_block = match node.children.get(idx + 1) {
|
||||
Some(Node::Text(_)) => true,
|
||||
Some(Node::Block(_)) => true,
|
||||
_ => false
|
||||
};
|
||||
|
||||
let curr_id = child_to_tokens(
|
||||
cx,
|
||||
child,
|
||||
|
@ -365,7 +376,9 @@ fn element_to_tokens(
|
|||
multi,
|
||||
mode,
|
||||
idx == 0,
|
||||
is_template
|
||||
is_template,
|
||||
next_is_element,
|
||||
next_is_block
|
||||
);
|
||||
|
||||
prev_sib = match curr_id {
|
||||
|
@ -395,21 +408,24 @@ fn next_sibling_node(children: &[Node], idx: usize, next_el_id: &mut usize) -> O
|
|||
if children.len() <= idx {
|
||||
None
|
||||
} else {
|
||||
let this = if idx > 0 { children.get(idx - 1) } else { None };
|
||||
let sibling = &children[idx];
|
||||
match sibling {
|
||||
Node::Element(sibling) => {
|
||||
if is_component_node(sibling) {
|
||||
next_sibling_node(children, idx + 1, next_el_id)
|
||||
} else {
|
||||
} else if idx > 1 {
|
||||
Some(child_ident(*next_el_id + 2, sibling.name.span()))
|
||||
} else {
|
||||
Some(child_ident(*next_el_id + 1, sibling.name.span()))
|
||||
}
|
||||
},
|
||||
Node::Block(sibling) => if idx > 0 {
|
||||
Node::Block(sibling) => if idx > 1 {
|
||||
Some(child_ident(*next_el_id + 2, sibling.value.span()))
|
||||
} else {
|
||||
Some(child_ident(*next_el_id + 1, sibling.value.span()))
|
||||
}
|
||||
Node::Text(sibling) => if idx > 0 {
|
||||
Node::Text(sibling) => if idx > 1 {
|
||||
Some(child_ident(*next_el_id + 2, sibling.value.span()))
|
||||
} else {
|
||||
Some(child_ident(*next_el_id + 1, sibling.value.span()))
|
||||
|
@ -619,6 +635,8 @@ fn child_to_tokens(
|
|||
mode: Mode,
|
||||
is_first_child: bool,
|
||||
parent_is_template: bool,
|
||||
next_is_element: bool,
|
||||
next_is_block: bool
|
||||
) -> PrevSibChange {
|
||||
match node {
|
||||
Node::Element(node) => {
|
||||
|
@ -656,10 +674,10 @@ fn child_to_tokens(
|
|||
}
|
||||
}
|
||||
Node::Text(node) => {
|
||||
block_to_tokens(cx, &node.value, node.value.span(), parent, prev_sib, next_sib, next_el_id, next_co_id, template, expressions, navigations, mode, is_first_child)
|
||||
block_to_tokens(cx, &node.value, node.value.span(), parent, prev_sib, next_sib, next_el_id, next_co_id, template, expressions, navigations, mode, is_first_child, false, next_is_element, next_is_block)
|
||||
}
|
||||
Node::Block(node) => {
|
||||
block_to_tokens(cx, &node.value, node.value.span(), parent, prev_sib, next_sib, next_el_id, next_co_id, template, expressions, navigations, mode, is_first_child)
|
||||
block_to_tokens(cx, &node.value, node.value.span(), parent, prev_sib, next_sib, next_el_id, next_co_id, template, expressions, navigations, mode, is_first_child, true, next_is_element, next_is_block)
|
||||
}
|
||||
_ => panic!("unexpected child node type"),
|
||||
}
|
||||
|
@ -679,7 +697,10 @@ fn block_to_tokens(
|
|||
expressions: &mut Vec<TokenStream>,
|
||||
navigations: &mut Vec<TokenStream>,
|
||||
mode: Mode,
|
||||
is_first_child: bool
|
||||
is_first_child: bool,
|
||||
is_block: bool,
|
||||
next_is_element: bool,
|
||||
next_is_block: bool
|
||||
) -> PrevSibChange {
|
||||
let value = value.as_ref();
|
||||
let str_value = match value {
|
||||
|
@ -750,7 +771,7 @@ fn block_to_tokens(
|
|||
match mode {
|
||||
// in CSR, simply insert a comment node: it will be picked up and replaced with the value
|
||||
Mode::Client => {
|
||||
if !is_first_child {
|
||||
if (!is_first_child && is_block && !next_is_element) || next_is_block {
|
||||
template.push_str("<!>");
|
||||
}
|
||||
navigations.push(location);
|
||||
|
|
Loading…
Reference in a new issue