Skip to content

Commit

Permalink
fixes on events and diffing; alpha tag 0.0.11-a1
Browse files Browse the repository at this point in the history
  • Loading branch information
tiye committed Jun 6, 2022
1 parent 338bed4 commit 7e5cd5b
Show file tree
Hide file tree
Showing 8 changed files with 193 additions and 63 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "respo"
version = "0.0.10"
version = "0.0.11-a1"
edition = "2021"
description = "a tiny virtual DOM library migrated from ClojureScript"
license = "Apache-2.0"
Expand Down
4 changes: 3 additions & 1 deletion src/respo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,9 @@ where
element.set_attribute(key, value)?;
}
}
element.set_attribute("style", &style.to_string())?;
if !style.is_empty() {
element.set_attribute("style", &style.to_string())?;
}
for (k, child) in children {
let mut next_coord = coord.to_owned();
next_coord.push(RespoCoord::Key(k.to_owned()));
Expand Down
2 changes: 2 additions & 0 deletions src/respo/alias.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ declare_tag!(h2, "`<h2/>`");
declare_tag!(h3, "`<h3/>`");
declare_tag!(h4, "`<h4/>`");
declare_tag!(blockquote, "`<blockquote/>`");
declare_tag!(ul, "`<ul/>`");
declare_tag!(li, "`<li/>`");

/// special function to return `<div/>` with width/height that can be used as a space
pub fn space<T>(w: Option<i32>, h: Option<i32>) -> RespoNode<T>
Expand Down
8 changes: 8 additions & 0 deletions src/respo/css.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,14 @@ impl RespoStyle {
}
result
}

pub fn len(&self) -> usize {
self.0.len()
}

pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
}

impl Display for RespoStyle {
Expand Down
81 changes: 45 additions & 36 deletions src/respo/diff.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,41 +46,42 @@ where
}
} else {
collect_effects_inside_out_as(old_tree, coord, dom_path, RespoEffectType::BeforeUnmount, changes)?;
// crate::util::log!("compare elements: {:?} {:?}", new_child, old_child);
changes.push(DomChange::ReplaceElement {
coord: coord.to_owned(),
dom_path: dom_path.to_owned(),
node: *old_child.to_owned(),
node: *new_child.to_owned(),
});
collect_effects_outside_in_as(new_tree, coord, dom_path, RespoEffectType::Mounted, changes)?;
}
}
(RespoNode::Component(..), b) => {
(a @ RespoNode::Component(..), _b) => {
collect_effects_inside_out_as(old_tree, coord, dom_path, RespoEffectType::BeforeUnmount, changes)?;
changes.push(DomChange::ReplaceElement {
coord: coord.to_owned(),
dom_path: dom_path.to_owned(),
node: b.to_owned(),
node: a.to_owned(),
});
collect_effects_outside_in_as(new_tree, coord, dom_path, RespoEffectType::Mounted, changes)?;
}
(_, b @ RespoNode::Component(..)) => {
(a, RespoNode::Component(..)) => {
collect_effects_inside_out_as(old_tree, coord, dom_path, RespoEffectType::BeforeUnmount, changes)?;
changes.push(DomChange::ReplaceElement {
coord: coord.to_owned(),
dom_path: dom_path.to_owned(),
node: b.to_owned(),
node: a.to_owned(),
});
collect_effects_outside_in_as(new_tree, coord, dom_path, RespoEffectType::Mounted, changes)?;
}
(
RespoNode::Element {
a @ RespoNode::Element {
name,
attrs,
style,
event,
children,
},
b @ RespoNode::Element {
RespoNode::Element {
name: old_name,
attrs: old_attrs,
style: old_style,
Expand All @@ -93,7 +94,7 @@ where
changes.push(DomChange::ReplaceElement {
coord: coord.to_owned(),
dom_path: dom_path.to_owned(),
node: b.to_owned(),
node: a.to_owned(),
});
collect_effects_outside_in_as(new_tree, coord, dom_path, RespoEffectType::Mounted, changes)?;
} else {
Expand Down Expand Up @@ -373,13 +374,15 @@ where
T: Debug + Clone,
{
match tree {
RespoNode::Component(name, _, tree) => {
changes.push(DomChange::Effect {
coord: coord.to_owned(),
dom_path: dom_path.to_owned(),
effect_type,
skip_indexes: HashSet::new(),
});
RespoNode::Component(name, effects, tree) => {
if !effects.is_empty() {
changes.push(DomChange::Effect {
coord: coord.to_owned(),
dom_path: dom_path.to_owned(),
effect_type,
skip_indexes: HashSet::new(),
});
}
let mut next_coord = coord.to_owned();
next_coord.push(RespoCoord::Comp(name.to_owned()));
collect_effects_outside_in_as(tree, &next_coord, dom_path, effect_type, changes)?;
Expand Down Expand Up @@ -412,16 +415,18 @@ where
T: Debug + Clone,
{
match tree {
RespoNode::Component(name, _, tree) => {
RespoNode::Component(name, effects, tree) => {
let mut next_coord = coord.to_owned();
next_coord.push(RespoCoord::Comp(name.to_owned()));
collect_effects_inside_out_as(tree, &next_coord, dom_path, effect_type, changes)?;
changes.push(DomChange::Effect {
coord: coord.to_owned(),
dom_path: dom_path.to_owned(),
effect_type,
skip_indexes: HashSet::new(),
});
if !effects.is_empty() {
changes.push(DomChange::Effect {
coord: coord.to_owned(),
dom_path: dom_path.to_owned(),
effect_type,
skip_indexes: HashSet::new(),
});
}
Ok(())
}
RespoNode::Element { children, .. } => {
Expand Down Expand Up @@ -452,13 +457,15 @@ where
T: Debug + Clone,
{
match tree {
RespoNode::Component(name, _, tree) => {
operations.push(ChildDomOp::NestedEffect {
nested_coord: coord.to_owned(),
nested_dom_path: dom_path.to_owned(),
effect_type,
skip_indexes: HashSet::new(),
});
RespoNode::Component(name, effects, tree) => {
if !effects.is_empty() {
operations.push(ChildDomOp::NestedEffect {
nested_coord: coord.to_owned(),
nested_dom_path: dom_path.to_owned(),
effect_type,
skip_indexes: HashSet::new(),
});
}
let mut next_coord = coord.to_owned();
next_coord.push(RespoCoord::Comp(name.to_owned()));
nested_effects_outside_in_as(tree, &next_coord, dom_path, effect_type, operations)?;
Expand Down Expand Up @@ -491,16 +498,18 @@ where
T: Debug + Clone,
{
match tree {
RespoNode::Component(name, _, tree) => {
RespoNode::Component(name, effects, tree) => {
let mut next_coord = coord.to_owned();
next_coord.push(RespoCoord::Comp(name.to_owned()));
nested_effects_inside_out_as(tree, &next_coord, dom_path, effect_type, operations)?;
operations.push(ChildDomOp::NestedEffect {
nested_coord: coord.to_owned(),
nested_dom_path: dom_path.to_owned(),
effect_type,
skip_indexes: HashSet::new(),
});
if !effects.is_empty() {
operations.push(ChildDomOp::NestedEffect {
nested_coord: coord.to_owned(),
nested_dom_path: dom_path.to_owned(),
effect_type,
skip_indexes: HashSet::new(),
});
}
Ok(())
}
RespoNode::Element { children, .. } => {
Expand Down
147 changes: 123 additions & 24 deletions src/respo/patch.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::fmt::Debug;

use wasm_bindgen::prelude::Closure;
use web_sys::{Element, HtmlElement, HtmlInputElement, InputEvent, MouseEvent, Node};
use web_sys::{Element, HtmlElement, HtmlInputElement, InputEvent, KeyboardEvent, MouseEvent, Node};

use wasm_bindgen::JsCast;
use web_sys::console::warn_1;
Expand Down Expand Up @@ -104,7 +104,7 @@ where
parent
.dyn_ref::<Node>()
.expect("to node")
.insert_before(&target, Some(&new_element))
.insert_before(&new_element, Some(&target))
.expect("element inserted");
target.dyn_ref::<Element>().expect("get node").remove();
}
Expand Down Expand Up @@ -231,16 +231,13 @@ pub fn attach_event(element: &Element, key: &str, coord: &[RespoCoord], handle_e
match key {
"click" => {
let handler = Closure::wrap(Box::new(move |e: MouseEvent| {
let wrap_event = RespoEvent::Click {
client_x: e.client_x() as f64,
client_y: e.client_y() as f64,
original_event: e,
};
handle_event
.run(RespoEventMark {
name: "click".to_owned(),
coord: coord.to_owned(),
event_info: RespoEvent::Click {
client_x: e.client_x() as f64,
client_y: e.client_y() as f64,
original_event: e,
},
})
.run(RespoEventMark::new("click", &coord, wrap_event))
.expect("handle click event");
}) as Box<dyn FnMut(MouseEvent)>);
element
Expand All @@ -249,22 +246,37 @@ pub fn attach_event(element: &Element, key: &str, coord: &[RespoCoord], handle_e
.set_onclick(Some(handler.as_ref().unchecked_ref()));
handler.forget();
}

"dblclick" => {
let handler = Closure::wrap(Box::new(move |e: MouseEvent| {
let wrap_event = RespoEvent::Click {
client_x: e.client_x() as f64,
client_y: e.client_y() as f64,
original_event: e,
};
handle_event
.run(RespoEventMark::new("dblclick", &coord, wrap_event))
.expect("handle dblclick event");
}) as Box<dyn FnMut(MouseEvent)>);
element
.dyn_ref::<HtmlElement>()
.expect("convert to html element")
.set_ondblclick(Some(handler.as_ref().unchecked_ref()));
handler.forget();
}
"input" => {
let handler = Closure::wrap(Box::new(move |e: InputEvent| {
let wrap_event = RespoEvent::Input {
value: e
.target()
.expect("to reach event target")
.dyn_ref::<HtmlInputElement>()
.expect("to convert to html input element")
.value(),
original_event: e,
};
handle_event
.run(RespoEventMark {
coord: coord.to_owned(),
name: "input".to_owned(),
event_info: RespoEvent::Input {
value: e
.target()
.expect("to reach event target")
.dyn_ref::<HtmlInputElement>()
.expect("to convert to html input element")
.value(),
original_event: e,
},
})
.run(RespoEventMark::new("input", &coord, wrap_event))
.expect("handle input event");
}) as Box<dyn FnMut(InputEvent)>);
element
Expand All @@ -273,6 +285,93 @@ pub fn attach_event(element: &Element, key: &str, coord: &[RespoCoord], handle_e
.set_oninput(Some(handler.as_ref().unchecked_ref()));
handler.forget();
}
"change" => {
let handler = Closure::wrap(Box::new(move |e: InputEvent| {
let wrap_event = RespoEvent::Input {
value: e
.target()
.expect("to reach event target")
.dyn_ref::<HtmlInputElement>()
.expect("to convert to html input element")
.value(),
original_event: e,
};
handle_event
.run(RespoEventMark::new("change", &coord, wrap_event))
.expect("handle change event");
}) as Box<dyn FnMut(InputEvent)>);
element
.dyn_ref::<HtmlInputElement>()
.expect("convert to html input element")
.set_onchange(Some(handler.as_ref().unchecked_ref()));
handler.forget();
}
"keydown" => {
let handler = Closure::wrap(Box::new(move |e: KeyboardEvent| {
let wrap_event = RespoEvent::Keyboard {
key: e.key(),
key_code: e.key_code(),
shift_key: e.shift_key(),
ctrl_key: e.ctrl_key(),
alt_key: e.alt_key(),
meta_key: e.meta_key(),
repeat: e.repeat(),
original_event: e,
};
handle_event
.run(RespoEventMark::new("keydown", &coord, wrap_event))
.expect("handle keydown event");
}) as Box<dyn FnMut(KeyboardEvent)>);
element
.dyn_ref::<HtmlInputElement>()
.expect("convert to html input element")
.set_onkeydown(Some(handler.as_ref().unchecked_ref()));
handler.forget();
}
"keyup" => {
let handler = Closure::wrap(Box::new(move |e: KeyboardEvent| {
let wrap_event = RespoEvent::Keyboard {
key: e.key(),
key_code: e.key_code(),
shift_key: e.shift_key(),
ctrl_key: e.ctrl_key(),
alt_key: e.alt_key(),
meta_key: e.meta_key(),
repeat: e.repeat(),
original_event: e,
};
handle_event
.run(RespoEventMark::new("keyup", &coord, wrap_event))
.expect("handle keyup event");
}) as Box<dyn FnMut(KeyboardEvent)>);
element
.dyn_ref::<HtmlInputElement>()
.expect("convert to html input element")
.set_onkeyup(Some(handler.as_ref().unchecked_ref()));
handler.forget();
}
"keypress" => {
let handler = Closure::wrap(Box::new(move |e: KeyboardEvent| {
let wrap_event = RespoEvent::Keyboard {
key: e.key(),
key_code: e.key_code(),
shift_key: e.shift_key(),
ctrl_key: e.ctrl_key(),
alt_key: e.alt_key(),
meta_key: e.meta_key(),
repeat: e.repeat(),
original_event: e,
};
handle_event
.run(RespoEventMark::new("keypress", &coord, wrap_event))
.expect("handle keypress event");
}) as Box<dyn FnMut(KeyboardEvent)>);
element
.dyn_ref::<HtmlInputElement>()
.expect("convert to html input element")
.set_onkeypress(Some(handler.as_ref().unchecked_ref()));
handler.forget();
}
_ => {
warn_1(&format!("unhandled event: {}", key).into());
}
Expand Down
Loading

0 comments on commit 7e5cd5b

Please sign in to comment.