Skip to content

Commit

Permalink
Text in TemplateResult (#104)
Browse files Browse the repository at this point in the history
* rust_2018_idioms

* Ccorrectly stringify self-closing tags in SSR

* Rename render to create

* Move render_* functions into sub-modules

* Naive hydration

* get_children utility

* Add mapped and indexed placeholder

* Allow effects to be FnMut (#103)

* Allow effects to be FnMut

* Only add -Dwarnings for clippy

* Set CARGO_TERM_COLOR to always

* map_indexed

* Implement map_keyed

* Add fast paths for map_keyed

* Make TemplateResult recursive

* Make map_* return closures

* Refactor TemplateResult

* Add a Lazy TemplateResult

* Allow create_memo and create_selector to take FnMut

* Fix unit tests

* Change TemplateResultInner::Lazy to be FnMut

* insert_expression node and lazy

* Make most of the tests pass

* Remove append_render

* Make Lazy work

* Fix reactivity

* Make fragment template work

* renconcile_fragments

* Support TemplateResult in interpolation syntax

* wip

* wip

* Push lazy TemplateResult to normalized

* wip

* wip

* NodeId

* Add renconcile tests

* Add reconcile do not clone node test

* Update wasm-bindgen to 0.2.74 in CI

* Interpolation nested reactivity test

* Remove Option from TemplateResultInner::Lazy type

* cargo clippy

* Append fragment nodes at the right location

* wip

* refactor

* refactor

* Fix map_keyed

* Fix clippy

* Remove unused NodeRef in TodoMVC example

* Remove fragment from GenericNode

* Remove Fragment from SsrNode

* Refactor SsrNode::try_remove_child

* Deprecate TemplateResult::flatten

* Change Render to IntoTemplate

* Refactor rendering of template fragments

* Rewrite impl ToTokens for Element

* Split up ToTokens in element.rs

* Visitor pattern for Html nodes

* TemplateVisitor

* Insert components and interpolated values before a marker

* Fix nested fragments

* Lazy in fragment test

* Fix DomNode::replace_child

* Fix Indexed and Keyed

* Fix iteration example

* Fix reconcile

* Pass the wasm test suite!!!

* Fix the ssr test
  • Loading branch information
lukechu10 authored Jun 7, 2021
1 parent 94ad7d3 commit 80371dc
Show file tree
Hide file tree
Showing 33 changed files with 1,935 additions and 807 deletions.
3 changes: 3 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ jobs:
env:
RUSTFLAGS: -Dwarnings

env:
RUSTFLAGS: -Dwarnings

steps:
- uses: actions/checkout@v2

Expand Down
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ members = [
"examples/components",
"examples/counter",
"examples/hello",
"examples/iteration",
"examples/ssr",
"examples/todomvc",
"examples/tweened",
Expand Down
4 changes: 0 additions & 4 deletions examples/hello/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,3 @@ console_log = "0.2.0"
log = "0.4.14"
maple-core = {path = "../../maple-core"}
wasm-bindgen = "0.2"

[dependencies.web-sys]
features = ["HtmlInputElement"]
version = "0.3"
15 changes: 15 additions & 0 deletions examples/iteration/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
[package]
authors = ["Luke Chu <37006668+lukechu10@users.noreply.github.com>"]
edition = "2018"
name = "iteration"
publish = false
version = "0.1.0"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
console_error_panic_hook = "0.1.6"
console_log = "0.2.0"
log = "0.4.14"
maple-core = {path = "../../maple-core"}
wasm-bindgen = "0.2"
15 changes: 15 additions & 0 deletions examples/iteration/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<title>Hello World!</title>

<style>
body {
font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
}
</style>
</head>
<body></body>
</html>
35 changes: 35 additions & 0 deletions examples/iteration/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
use maple_core::prelude::*;

#[component(App<G>)]
fn app() -> TemplateResult<G> {
let items = Signal::new(vec![
template! { "Hello!" },
template! { "I am an item in a fragment"},
]);

let add_item = cloned!((items) => move |_| {
items.set(
(*items.get())
.clone()
.into_iter()
.chain(Some(template! { "New item" }))
.collect(),
);
});

template! {
div {
button(on:click=add_item) { "Add item" }
div(class="items") {
(TemplateResult::new_fragment((*items.get()).clone()))
}
}
}
}

fn main() {
console_error_panic_hook::set_once();
console_log::init_with_level(log::Level::Debug).unwrap();

render(|| template! { App() });
}
2 changes: 1 addition & 1 deletion examples/todomvc/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use maple_core::prelude::*;
use serde::{Deserialize, Serialize};
use uuid::Uuid;

#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, Hash)]
pub struct Todo {
title: String,
completed: bool,
Expand Down
122 changes: 122 additions & 0 deletions maple-core-macro/src/template/attributes.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
use std::fmt;

use proc_macro2::TokenStream;
use quote::{quote, quote_spanned, ToTokens};
use syn::ext::IdentExt;
use syn::parse::{Parse, ParseStream};
use syn::punctuated::Punctuated;
use syn::spanned::Spanned;
use syn::token::Paren;
use syn::{parenthesized, Expr, Ident, Result, Token};

Expand Down Expand Up @@ -66,6 +69,125 @@ impl Parse for Attribute {
}
}

impl ToTokens for Attribute {
fn to_tokens(&self, tokens: &mut TokenStream) {
let expr = &self.expr;
let expr_span = expr.span();

match &self.ty {
AttributeType::DomAttribute { name } => {
let name = name.to_string();
tokens.extend(quote_spanned! { expr_span=>
::maple_core::reactive::create_effect({
let _el = ::std::clone::Clone::clone(&_el);
move || {
::maple_core::generic_node::GenericNode::set_attribute(
&_el,
#name,
&::std::format!("{}", #expr),
);
}
});
});
}
AttributeType::Event { event } => {
// TODO: Should events be reactive?
tokens.extend(quote_spanned! { expr_span=>
::maple_core::generic_node::GenericNode::event(
&_el,
#event,
::std::boxed::Box::new(#expr),
);
});
}
AttributeType::Bind { prop } => {
#[derive(Clone, Copy)]
enum JsPropertyType {
Bool,
String,
}

let (event_name, property_ty) = match prop.as_str() {
"value" => ("input", JsPropertyType::String),
"checked" => ("change", JsPropertyType::Bool),
_ => {
tokens.extend(
syn::Error::new(
prop.span(),
&format!("property `{}` is not supported with bind:", prop),
)
.to_compile_error(),
);
return;
}
};

let value_ty = match property_ty {
JsPropertyType::Bool => quote! { ::std::primitive::bool },
JsPropertyType::String => quote! { ::std::string::String },
};

let convert_into_jsvalue_fn = match property_ty {
JsPropertyType::Bool => {
quote! { ::maple_core::rt::JsValue::from_bool(*signal.get()) }
}
JsPropertyType::String => {
quote! { ::maple_core::rt::JsValue::from_str(&::std::format!("{}", signal.get())) }
}
};

let event_target_prop = quote! {
::maple_core::rt::Reflect::get(
&event.target().unwrap(),
&::std::convert::Into::<::maple_core::rt::JsValue>::into(#prop)
).unwrap()
};

let convert_from_jsvalue_fn = match property_ty {
JsPropertyType::Bool => quote! {
::maple_core::rt::JsValue::as_bool(&#event_target_prop).unwrap()
},
JsPropertyType::String => quote! {
::maple_core::rt::JsValue::as_string(&#event_target_prop).unwrap()
},
};

tokens.extend(quote_spanned! { expr_span=> {
let signal: ::maple_core::reactive::Signal<#value_ty> = #expr;

::maple_core::reactive::create_effect({
let signal = ::std::clone::Clone::clone(&signal);
let _el = ::std::clone::Clone::clone(&_el);
move || {
::maple_core::generic_node::GenericNode::set_property(
&_el,
#prop,
&#convert_into_jsvalue_fn,
);
}
});

::maple_core::generic_node::GenericNode::event(
&_el,
#event_name,
::std::boxed::Box::new(move |event: ::maple_core::rt::Event| {
signal.set(#convert_from_jsvalue_fn);
}),
)
}});
}
AttributeType::Ref => {
tokens.extend(quote_spanned! { expr_span=>{
::maple_core::noderef::NodeRef::set(
&#expr,
::std::clone::Clone::clone(&_el),
);
}});
}
}
}
}

pub struct AttributeList {
pub paren_token: Paren,
pub attributes: Punctuated<Attribute, Token![,]>,
Expand Down
Loading

0 comments on commit 80371dc

Please sign in to comment.