Merge branch 'master' into jk/debugging-diff

This commit is contained in:
Jonathan Kelley committed 2022-01-31 16:19:48 -05:00
commit 1978f195b3
2 files changed
+60 -63

No files matched your search

+13 -10
View File
@@ -39,16 +39,17 @@ pub fn use_state<'a, T: 'static>(
let setter = Rc::new({ let setter = Rc::new({
crate::to_owned![update_callback, slot]; crate::to_owned![update_callback, slot];
move |new| { move |new| {
let mut slot = slot.borrow_mut(); {
let mut slot = slot.borrow_mut();
// if there's only one reference (weak or otherwise), we can just swap the values // if there's only one reference (weak or otherwise), we can just swap the values
// Typically happens when the state is set multiple times - we don't want to create a new Rc for each new value // Typically happens when the state is set multiple times - we don't want to create a new Rc for each new value
if let Some(val) = Rc::get_mut(&mut slot) { if let Some(val) = Rc::get_mut(&mut slot) {
*val = new; *val = new;
} else { } else {
*slot = Rc::new(new); *slot = Rc::new(new);
}
} }
update_callback(); update_callback();
} }
}); });
@@ -153,8 +154,10 @@ impl<T: 'static> UseState<T> {
/// } /// }
/// ``` /// ```
pub fn modify(&self, f: impl FnOnce(&T) -> T) { pub fn modify(&self, f: impl FnOnce(&T) -> T) {
let current = self.slot.borrow(); let new_val = {
let new_val = f(current.as_ref()); let current = self.slot.borrow();
f(current.as_ref())
};
(self.setter)(new_val); (self.setter)(new_val);
} }
+47 -53
View File
@@ -28,17 +28,54 @@ impl WebsysDom {
pub fn new(cfg: WebConfig, sender_callback: Rc<dyn Fn(SchedulerMsg)>) -> Self { pub fn new(cfg: WebConfig, sender_callback: Rc<dyn Fn(SchedulerMsg)>) -> Self {
// eventually, we just want to let the interpreter do all the work of decoding events into our event type // eventually, we just want to let the interpreter do all the work of decoding events into our event type
let callback: Box<dyn FnMut(&Event)> = Box::new(move |event: &web_sys::Event| { let callback: Box<dyn FnMut(&Event)> = Box::new(move |event: &web_sys::Event| {
if let Ok(synthetic_event) = decode_trigger(event) { let mut target = event
.target()
.expect("missing target")
.dyn_into::<Element>()
.expect("not a valid element");
let typ = event.type_();
let decoded: anyhow::Result<UserEvent> = loop {
match target.get_attribute("data-dioxus-id").map(|f| f.parse()) {
Some(Ok(id)) => {
break Ok(UserEvent {
name: event_name_from_typ(&typ),
data: virtual_event_from_websys_event(event.clone()),
element: Some(ElementId(id)),
scope_id: None,
priority: dioxus_core::EventPriority::Medium,
});
}
Some(Err(e)) => {
break Err(e.into());
}
None => {
// walk the tree upwards until we actually find an event target
if let Some(parent) = target.parent_element() {
target = parent;
} else {
break Ok(UserEvent {
name: event_name_from_typ(&typ),
data: virtual_event_from_websys_event(event.clone()),
element: None,
scope_id: None,
priority: dioxus_core::EventPriority::Low,
});
}
}
}
};
if let Ok(synthetic_event) = decoded {
// Try to prevent default if the attribute is set // Try to prevent default if the attribute is set
if let Some(target) = event.target() { if let Some(node) = target.dyn_ref::<HtmlElement>() {
if let Some(node) = target.dyn_ref::<HtmlElement>() { if let Some(name) = node.get_attribute("dioxus-prevent-default") {
if let Some(name) = node.get_attribute("dioxus-prevent-default") { if name == synthetic_event.name
if name == synthetic_event.name || name.trim_start_matches("on") == synthetic_event.name
|| name.trim_start_matches("on") == synthetic_event.name {
{ log::trace!("Preventing default");
log::trace!("Preventing default"); event.prevent_default();
event.prevent_default();
}
} }
} }
} }
@@ -274,49 +311,6 @@ fn virtual_event_from_websys_event(event: web_sys::Event) -> Arc<dyn Any + Send
} }
} }
/// This function decodes a websys event and produces an EventTrigger
/// With the websys implementation, we attach a unique key to the nodes
fn decode_trigger(event: &web_sys::Event) -> anyhow::Result<UserEvent> {
let mut target = event
.target()
.expect("missing target")
.dyn_into::<Element>()
.expect("not a valid element");
let typ = event.type_();
loop {
match target.get_attribute("data-dioxus-id").map(|f| f.parse()) {
Some(Ok(id)) => {
return Ok(UserEvent {
name: event_name_from_typ(&typ),
data: virtual_event_from_websys_event(event.clone()),
element: Some(ElementId(id)),
scope_id: None,
priority: dioxus_core::EventPriority::Medium,
});
}
Some(Err(e)) => {
return Err(e.into());
}
None => {
// walk the tree upwards until we actually find an event target
if let Some(parent) = target.parent_element() {
target = parent;
} else {
return Ok(UserEvent {
name: event_name_from_typ(&typ),
data: virtual_event_from_websys_event(event.clone()),
element: None,
scope_id: None,
priority: dioxus_core::EventPriority::Low,
});
}
}
}
}
}
pub(crate) fn load_document() -> Document { pub(crate) fn load_document() -> Document {
web_sys::window() web_sys::window()
.expect("should have access to the Window") .expect("should have access to the Window")