Merge branch 'master' into jk/debugging-diff
This commit is contained in:
commit
1978f195b3
2 files changed
+65
-68
No files matched your search
@@ -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();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -92,7 +93,7 @@ impl<T: 'static> UseState<T> {
|
|||||||
/// }
|
/// }
|
||||||
/// })
|
/// })
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn current(&self) -> Rc<T> {
|
pub fn current(&self) -> Rc<T> {
|
||||||
self.slot.borrow().clone()
|
self.slot.borrow().clone()
|
||||||
@@ -137,10 +138,10 @@ impl<T: 'static> UseState<T> {
|
|||||||
/// # use dioxus_hooks::*;
|
/// # use dioxus_hooks::*;
|
||||||
/// fn component(cx: Scope) -> Element {
|
/// fn component(cx: Scope) -> Element {
|
||||||
/// let (value, set_value) = use_state(&cx, || 0);
|
/// let (value, set_value) = use_state(&cx, || 0);
|
||||||
///
|
///
|
||||||
/// // to increment the value
|
/// // to increment the value
|
||||||
/// set_value.modify(|v| v + 1);
|
/// set_value.modify(|v| v + 1);
|
||||||
///
|
///
|
||||||
/// // usage in async
|
/// // usage in async
|
||||||
/// cx.spawn({
|
/// cx.spawn({
|
||||||
/// let set_value = set_value.to_owned();
|
/// let set_value = set_value.to_owned();
|
||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -176,7 +179,7 @@ impl<T: 'static> UseState<T> {
|
|||||||
/// # use dioxus_hooks::*;
|
/// # use dioxus_hooks::*;
|
||||||
/// fn component(cx: Scope) -> Element {
|
/// fn component(cx: Scope) -> Element {
|
||||||
/// let (value, set_value) = use_state(&cx, || 0);
|
/// let (value, set_value) = use_state(&cx, || 0);
|
||||||
///
|
///
|
||||||
/// let as_rc = set_value.get();
|
/// let as_rc = set_value.get();
|
||||||
/// assert_eq!(as_rc.as_ref(), &0);
|
/// assert_eq!(as_rc.as_ref(), &0);
|
||||||
///
|
///
|
||||||
@@ -201,7 +204,7 @@ impl<T: 'static> UseState<T> {
|
|||||||
/// }
|
/// }
|
||||||
/// })
|
/// })
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
pub fn needs_update(&self) {
|
pub fn needs_update(&self) {
|
||||||
(self.update_callback)();
|
(self.update_callback)();
|
||||||
}
|
}
|
||||||
|
|||||||
+47
-53
@@ -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")
|
||||||
|
|||||||
Reference in new issue
Block a user