xilem_html: Add SetAttr trait (experiment)

This commit is contained in:
Jonas Platte 2023-07-23 12:46:40 +02:00
parent 809b38e989
commit 33d4b08989
No known key found for this signature in database
GPG Key ID: CC154DE0E30B7C67
7 changed files with 101 additions and 2 deletions

View File

@ -96,6 +96,17 @@ macro_rules! element {
self.0.message(id_path, state, message, app_state) self.0.message(id_path, state, message, app_state)
} }
} }
impl<ViewSeq> crate::set_attr::SetAttr for $ty_name<ViewSeq> {
#[deny(unconditional_recursion)]
fn set_attr(
&mut self,
name: impl Into<std::borrow::Cow<'static, str>>,
value: impl Into<std::borrow::Cow<'static, str>>,
) {
self.0.set_attr(name, value);
}
}
}; };
} }

View File

@ -5,6 +5,7 @@
use crate::{ use crate::{
context::{ChangeFlags, Cx}, context::{ChangeFlags, Cx},
view::{DomElement, Pod, View, ViewMarker, ViewSequence}, view::{DomElement, Pod, View, ViewMarker, ViewSequence},
SetAttr,
}; };
use std::{borrow::Cow, cmp::Ordering, collections::BTreeMap, fmt}; use std::{borrow::Cow, cmp::Ordering, collections::BTreeMap, fmt};
@ -257,6 +258,17 @@ where
} }
} }
impl<El, ViewSeq> SetAttr for Element<El, ViewSeq> {
#[deny(unconditional_recursion)]
fn set_attr(
&mut self,
name: impl Into<Cow<'static, str>>,
value: impl Into<Cow<'static, str>>,
) {
self.set_attr(name, value);
}
}
#[cfg(feature = "typed")] #[cfg(feature = "typed")]
fn set_attribute(element: &web_sys::Element, name: &str, value: &str) { fn set_attribute(element: &web_sys::Element, name: &str, value: &str) {
// we have to special-case `value` because setting the value using `set_attribute` // we have to special-case `value` because setting the value using `set_attribute`

View File

@ -107,6 +107,21 @@ macro_rules! event {
self.inner.message(id_path, state, message, app_state) self.inner.message(id_path, state, message, app_state)
} }
} }
impl<T, A, V, F, OA> crate::set_attr::SetAttr for $ty_name<T, A, V, F, OA>
where
V: crate::view::View<T, A> + crate::set_attr::SetAttr,
V::Element: 'static,
{
#[deny(unconditional_recursion)]
fn set_attr(
&mut self,
name: impl Into<std::borrow::Cow<'static, str>>,
value: impl Into<std::borrow::Cow<'static, str>>,
) {
self.inner.set_attr(name, value);
}
}
}; };
} }

View File

@ -4,7 +4,7 @@
#[cfg(feature = "typed")] #[cfg(feature = "typed")]
pub mod events; pub mod events;
use std::{any::Any, marker::PhantomData, ops::Deref}; use std::{any::Any, borrow::Cow, marker::PhantomData, ops::Deref};
use gloo::events::{EventListener, EventListenerOptions}; use gloo::events::{EventListener, EventListenerOptions};
use wasm_bindgen::{JsCast, UnwrapThrowExt}; use wasm_bindgen::{JsCast, UnwrapThrowExt};
@ -13,6 +13,7 @@ use xilem_core::{Id, MessageResult};
use crate::{ use crate::{
context::{ChangeFlags, Cx}, context::{ChangeFlags, Cx},
view::{DomNode, View, ViewMarker}, view::{DomNode, View, ViewMarker},
SetAttr,
}; };
/// Wraps a [`View`] `V` and attaches an event listener. /// Wraps a [`View`] `V` and attaches an event listener.
@ -123,6 +124,20 @@ where
} }
} }
impl<E, V, F> SetAttr for OnEvent<E, V, F>
where
V: SetAttr,
{
#[deny(unconditional_recursion)]
fn set_attr(
&mut self,
name: impl Into<Cow<'static, str>>,
value: impl Into<Cow<'static, str>>,
) {
self.child.set_attr(name, value);
}
}
// Attach an event listener to the child's element // Attach an event listener to the child's element
pub fn on_event<E, V, F>(name: &'static str, child: V, callback: F) -> OnEvent<E, V, F> { pub fn on_event<E, V, F>(name: &'static str, child: V, callback: F) -> OnEvent<E, V, F> {
OnEvent::new(name, child, callback) OnEvent::new(name, child, callback)

View File

@ -13,6 +13,7 @@ mod context;
mod element; mod element;
mod event; mod event;
mod one_of; mod one_of;
mod set_attr;
mod view; mod view;
#[cfg(feature = "typed")] #[cfg(feature = "typed")]
mod view_ext; mod view_ext;
@ -29,6 +30,7 @@ pub use element::{element, Element, ElementState};
pub use event::events; pub use event::events;
pub use event::{on_event, Action, Event, OnEvent, OnEventState, OptionalAction}; pub use event::{on_event, Action, Event, OnEvent, OnEventState, OptionalAction};
pub use one_of::{OneOf2, OneOf3, OneOf4, OneOf5, OneOf6, OneOf7, OneOf8}; pub use one_of::{OneOf2, OneOf3, OneOf4, OneOf5, OneOf6, OneOf7, OneOf8};
pub use set_attr::SetAttr;
pub use view::{ pub use view::{
Adapt, AdaptState, AdaptThunk, AnyView, Memoize, Pod, View, ViewMarker, ViewSequence, Adapt, AdaptState, AdaptThunk, AnyView, Memoize, Pod, View, ViewMarker, ViewSequence,
}; };

View File

@ -0,0 +1,17 @@
use std::borrow::Cow;
pub trait SetAttr {
fn set_attr(&mut self, name: impl Into<Cow<'static, str>>, value: impl Into<Cow<'static, str>>);
fn attr(
mut self,
name: impl Into<Cow<'static, str>>,
value: impl Into<Cow<'static, str>>,
) -> Self
where
Self: Sized,
{
self.set_attr(name, value);
self
}
}

View File

@ -8,7 +8,7 @@ use std::{any::Any, borrow::Cow, ops::Deref};
use xilem_core::{Id, MessageResult}; use xilem_core::{Id, MessageResult};
use crate::{context::Cx, ChangeFlags}; use crate::{context::Cx, ChangeFlags, SetAttr};
mod sealed { mod sealed {
pub trait Sealed {} pub trait Sealed {}
@ -222,3 +222,30 @@ impl<T, A> View<T, A> for Cow<'static, str> {
fn new_text(text: &str) -> web_sys::Text { fn new_text(text: &str) -> web_sys::Text {
web_sys::Text::new_with_data(text).unwrap() web_sys::Text::new_with_data(text).unwrap()
} }
impl<ParentT, ParentA, ChildT, ChildA, V, F> SetAttr
for Adapt<ParentT, ParentA, ChildT, ChildA, V, F>
where
V: SetAttr,
{
fn set_attr(
&mut self,
name: impl Into<Cow<'static, str>>,
value: impl Into<Cow<'static, str>>,
) {
self.child.set_attr(name, value);
}
}
impl<ParentT, ChildT, V, F> SetAttr for AdaptState<ParentT, ChildT, V, F>
where
V: SetAttr,
{
fn set_attr(
&mut self,
name: impl Into<Cow<'static, str>>,
value: impl Into<Cow<'static, str>>,
) {
self.child.set_attr(name, value);
}
}