pass on: to components (and lay basis for passing all other attributes)
This commit is contained in:
parent
53703f208a
commit
9e276a8879
2
TODO.md
2
TODO.md
|
@ -5,7 +5,7 @@
|
|||
- [x] todomvc
|
||||
- [x] error_boundary
|
||||
- [x] parent\_child
|
||||
- [ ] on: on components
|
||||
- [x] on: on components
|
||||
- [ ] router
|
||||
- [ ] slots
|
||||
- [ ] hackernews
|
||||
|
|
|
@ -53,7 +53,6 @@ pub fn App() -> impl IntoView {
|
|||
// Button B: pass a closure
|
||||
<ButtonB on_click=move |_| set_right.update(|value| *value = !*value)/>
|
||||
|
||||
// TODO -- on:click on components
|
||||
// Button C: use a regular event listener
|
||||
// setting an event listener on a component like this applies it
|
||||
// to each of the top-level elements the component returns
|
||||
|
@ -99,10 +98,12 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
use leptos::tachys::view::add_attr::AddAnyAttr;
|
||||
|
||||
/// Button C is a dummy: it renders a button but doesn't handle
|
||||
/// its click. Instead, the parent component adds an event listener.
|
||||
#[component]
|
||||
pub fn ButtonC() -> impl IntoView {
|
||||
pub fn ButtonC() -> impl IntoView + AddAnyAttr<Dom> {
|
||||
view! {
|
||||
<button>
|
||||
"Toggle Italics"
|
||||
|
|
|
@ -1,23 +1,28 @@
|
|||
use leptos_dom::events::EventDescriptor;
|
||||
use leptos_dom::events::{on, EventDescriptor, On};
|
||||
use tachys::{
|
||||
html::attribute::global::OnAttribute,
|
||||
html::attribute::{global::OnAttribute, Attribute},
|
||||
hydration::Cursor,
|
||||
renderer::{dom::Dom, Renderer},
|
||||
renderer::{dom::Dom, DomRenderer, Renderer},
|
||||
ssr::StreamBuilder,
|
||||
view::{Mountable, Position, PositionState, Render, RenderHtml},
|
||||
view::{
|
||||
add_attr::AddAnyAttr, Mountable, Position, PositionState, Render,
|
||||
RenderHtml,
|
||||
},
|
||||
};
|
||||
|
||||
pub struct View<T>(T)
|
||||
where
|
||||
T: Sized;
|
||||
|
||||
pub trait IntoView: Sized + Render<Dom> + RenderHtml<Dom> {
|
||||
pub trait IntoView:
|
||||
Sized + Render<Dom> + RenderHtml<Dom> + AddAnyAttr<Dom>
|
||||
{
|
||||
fn into_view(self) -> View<Self>;
|
||||
}
|
||||
|
||||
impl<T: Render<Dom> + RenderHtml<Dom>> IntoView for T
|
||||
impl<T> IntoView for T
|
||||
where
|
||||
T: Sized,
|
||||
T: Sized + Render<Dom> + RenderHtml<Dom> + AddAnyAttr<Dom>,
|
||||
{
|
||||
fn into_view(self) -> View<Self> {
|
||||
View(self)
|
||||
|
@ -74,66 +79,27 @@ impl<T: RenderHtml<Dom>> RenderHtml<Dom> for View<T> {
|
|||
}
|
||||
}
|
||||
|
||||
/*pub trait IntoView {
|
||||
const MIN_HTML_LENGTH: usize;
|
||||
impl<T: AddAnyAttr<Dom>> AddAnyAttr<Dom> for View<T> {
|
||||
type Output<SomeNewAttr: Attribute<Dom>> =
|
||||
<T as AddAnyAttr<Dom>>::Output<SomeNewAttr>;
|
||||
|
||||
type State: Mountable<Dom>;
|
||||
|
||||
fn build(self) -> Self::State;
|
||||
|
||||
fn rebuild(self, state: &mut Self::State);
|
||||
|
||||
fn to_html_with_buf(self, buf: &mut String, position: &mut Position);
|
||||
|
||||
fn to_html_async_with_buf<const OUT_OF_ORDER: bool>(
|
||||
fn add_any_attr<NewAttr: Attribute<Dom>>(
|
||||
self,
|
||||
buf: &mut StreamBuilder,
|
||||
position: &mut Position,
|
||||
);
|
||||
|
||||
fn hydrate<const FROM_SERVER: bool>(
|
||||
self,
|
||||
cursor: &Cursor<Dom>,
|
||||
position: &PositionState,
|
||||
) -> Self::State;
|
||||
}
|
||||
|
||||
impl<T: RenderHtml<Dom>> IntoView for T {}
|
||||
|
||||
impl<T: IntoView> Render<Dom> for T {
|
||||
type State = <Self as IntoView>::State;
|
||||
|
||||
fn build(self) -> Self::State {
|
||||
IntoView::build(self)
|
||||
}
|
||||
|
||||
fn rebuild(self, state: &mut Self::State) {
|
||||
IntoView::rebuild(self, state);
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: IntoView> RenderHtml<Dom> for T {
|
||||
const MIN_LENGTH: usize = T::MIN_HTML_LENGTH;
|
||||
|
||||
fn to_html_with_buf(self, buf: &mut String, position: &mut Position) {
|
||||
IntoView::to_html_with_buf(self, buf, position);
|
||||
}
|
||||
|
||||
fn to_html_async_with_buf<const OUT_OF_ORDER: bool>(
|
||||
self,
|
||||
buf: &mut StreamBuilder,
|
||||
position: &mut Position,
|
||||
) where
|
||||
Self: Sized,
|
||||
attr: NewAttr,
|
||||
) -> Self::Output<NewAttr>
|
||||
where
|
||||
Self::Output<NewAttr>: RenderHtml<Dom>,
|
||||
{
|
||||
IntoView::to_html_async_with_buf::<OUT_OF_ORDER>(self, buf, position);
|
||||
self.0.add_any_attr(attr)
|
||||
}
|
||||
|
||||
fn hydrate<const FROM_SERVER: bool>(
|
||||
fn add_any_attr_by_ref<NewAttr: Attribute<Dom>>(
|
||||
self,
|
||||
cursor: &Cursor<Dom>,
|
||||
position: &PositionState,
|
||||
) -> Self::State {
|
||||
IntoView::hydrate::<FROM_SERVER>(self, cursor, position)
|
||||
attr: &NewAttr,
|
||||
) -> Self::Output<NewAttr>
|
||||
where
|
||||
Self::Output<NewAttr>: RenderHtml<Dom>,
|
||||
{
|
||||
self.0.add_any_attr_by_ref(attr)
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
#![no_std]
|
||||
#![allow(non_snake_case)]
|
||||
|
||||
pub trait TupleBuilder<Next> {
|
||||
type Output;
|
||||
pub trait TupleBuilder {
|
||||
type Output<Next>;
|
||||
|
||||
fn next_tuple(self, next: Next) -> Self::Output;
|
||||
fn next_tuple<Next>(self, next: Next) -> Self::Output<Next>;
|
||||
}
|
||||
|
||||
pub trait ConcatTuples<Next> {
|
||||
|
@ -14,11 +14,11 @@ pub trait ConcatTuples<Next> {
|
|||
}
|
||||
|
||||
macro_rules! impl_tuple_builder {
|
||||
($($ty:ident),* => $last:ident) => {
|
||||
impl<$($ty),*, $last> TupleBuilder<$last> for ($($ty,)*) {
|
||||
type Output = ($($ty,)* $last);
|
||||
($($ty:ident),*) => {
|
||||
impl<$($ty),*> TupleBuilder for ($($ty,)*) {
|
||||
type Output<Next> = ($($ty,)* Next);
|
||||
|
||||
fn next_tuple(self, next: $last) -> Self::Output {
|
||||
fn next_tuple<Next>(self, next: Next) -> Self::Output<Next> {
|
||||
let ($($ty,)*) = self;
|
||||
($($ty,)* next)
|
||||
}
|
||||
|
@ -26,51 +26,50 @@ macro_rules! impl_tuple_builder {
|
|||
};
|
||||
}
|
||||
|
||||
impl<A> TupleBuilder<A> for () {
|
||||
type Output = (A,);
|
||||
impl TupleBuilder for () {
|
||||
type Output<Next> = (Next,);
|
||||
|
||||
fn next_tuple(self, next: A) -> Self::Output {
|
||||
fn next_tuple<Next>(self, next: Next) -> Self::Output<Next> {
|
||||
(next,)
|
||||
}
|
||||
}
|
||||
|
||||
impl_tuple_builder!(A => B);
|
||||
impl_tuple_builder!(A, B => C);
|
||||
impl_tuple_builder!(A, B, C => D);
|
||||
impl_tuple_builder!(A, B, C, D => E);
|
||||
impl_tuple_builder!(A, B, C, D, E => F);
|
||||
impl_tuple_builder!(A, B, C, D, E, F => G);
|
||||
impl_tuple_builder!(A, B, C, D, E, F, G => H);
|
||||
impl_tuple_builder!(A, B, C, D, E, F, G, H => I);
|
||||
impl_tuple_builder!(A, B, C, D, E, F, G, H, I => J);
|
||||
impl_tuple_builder!(A, B, C, D, E, F, G, H, I, J => K);
|
||||
impl_tuple_builder!(A, B, C, D, E, F, G, H, I, J, K => L);
|
||||
impl_tuple_builder!(A, B, C, D, E, F, G, H, I, J, K, L => M);
|
||||
impl_tuple_builder!(A, B, C, D, E, F, G, H, I, J, K, L, M => N);
|
||||
impl_tuple_builder!(A, B, C, D, E, F, G, H, I, J, K, L, M, N => O);
|
||||
impl_tuple_builder!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O => P);
|
||||
impl_tuple_builder!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P => Q);
|
||||
impl_tuple_builder!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q => R);
|
||||
impl_tuple_builder!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R => S);
|
||||
impl_tuple_builder!(A);
|
||||
impl_tuple_builder!(A, B);
|
||||
impl_tuple_builder!(A, B, C);
|
||||
impl_tuple_builder!(A, B, C, D);
|
||||
impl_tuple_builder!(A, B, C, D, E);
|
||||
impl_tuple_builder!(A, B, C, D, E, F);
|
||||
impl_tuple_builder!(A, B, C, D, E, F, G);
|
||||
impl_tuple_builder!(A, B, C, D, E, F, G, H);
|
||||
impl_tuple_builder!(A, B, C, D, E, F, G, H, I);
|
||||
impl_tuple_builder!(A, B, C, D, E, F, G, H, I, J);
|
||||
impl_tuple_builder!(A, B, C, D, E, F, G, H, I, J, K);
|
||||
impl_tuple_builder!(A, B, C, D, E, F, G, H, I, J, K, L);
|
||||
impl_tuple_builder!(A, B, C, D, E, F, G, H, I, J, K, L, M);
|
||||
impl_tuple_builder!(A, B, C, D, E, F, G, H, I, J, K, L, M, N);
|
||||
impl_tuple_builder!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O);
|
||||
impl_tuple_builder!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P);
|
||||
impl_tuple_builder!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q);
|
||||
impl_tuple_builder!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R);
|
||||
impl_tuple_builder!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S);
|
||||
impl_tuple_builder!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T);
|
||||
impl_tuple_builder!(
|
||||
A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S => T
|
||||
A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U
|
||||
);
|
||||
impl_tuple_builder!(
|
||||
A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T => U
|
||||
A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V
|
||||
);
|
||||
impl_tuple_builder!(
|
||||
A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U => V
|
||||
A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W
|
||||
);
|
||||
impl_tuple_builder!(
|
||||
A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V => W
|
||||
A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X
|
||||
);
|
||||
impl_tuple_builder!(
|
||||
A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W => X
|
||||
A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y
|
||||
);
|
||||
impl_tuple_builder!(
|
||||
A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X => Y
|
||||
);
|
||||
impl_tuple_builder!(
|
||||
A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y =>
|
||||
A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y,
|
||||
Z
|
||||
);
|
||||
|
|
|
@ -1,201 +1,156 @@
|
|||
use crate::{
|
||||
html::attribute::{Attr, *},
|
||||
view::AddAttribute,
|
||||
view::add_attr::AddAnyAttr,
|
||||
};
|
||||
pub trait AriaAttributes<Rndr, V>
|
||||
where
|
||||
Self: Sized
|
||||
+ AddAttribute<Attr<AriaAtomic, V, Rndr>, Rndr>
|
||||
+ AddAttribute<Attr<AriaBusy, V, Rndr>, Rndr>
|
||||
+ AddAttribute<Attr<AriaControls, V, Rndr>, Rndr>
|
||||
+ AddAttribute<Attr<AriaCurrent, V, Rndr>, Rndr>
|
||||
+ AddAttribute<Attr<AriaDescribedby, V, Rndr>, Rndr>
|
||||
+ AddAttribute<Attr<AriaDescription, V, Rndr>, Rndr>
|
||||
+ AddAttribute<Attr<AriaDetails, V, Rndr>, Rndr>
|
||||
+ AddAttribute<Attr<AriaDisabled, V, Rndr>, Rndr>
|
||||
+ AddAttribute<Attr<AriaDropeffect, V, Rndr>, Rndr>
|
||||
+ AddAttribute<Attr<AriaErrormessage, V, Rndr>, Rndr>
|
||||
+ AddAttribute<Attr<AriaFlowto, V, Rndr>, Rndr>
|
||||
+ AddAttribute<Attr<AriaGrabbed, V, Rndr>, Rndr>
|
||||
+ AddAttribute<Attr<AriaHaspopup, V, Rndr>, Rndr>
|
||||
+ AddAttribute<Attr<AriaHidden, V, Rndr>, Rndr>
|
||||
+ AddAttribute<Attr<AriaInvalid, V, Rndr>, Rndr>
|
||||
+ AddAttribute<Attr<AriaKeyshortcuts, V, Rndr>, Rndr>
|
||||
+ AddAttribute<Attr<AriaLabel, V, Rndr>, Rndr>
|
||||
+ AddAttribute<Attr<AriaLabelledby, V, Rndr>, Rndr>
|
||||
+ AddAttribute<Attr<AriaLive, V, Rndr>, Rndr>
|
||||
+ AddAttribute<Attr<AriaOwns, V, Rndr>, Rndr>
|
||||
+ AddAttribute<Attr<AriaRelevant, V, Rndr>, Rndr>
|
||||
+ AddAttribute<Attr<AriaRoledescription, V, Rndr>, Rndr>,
|
||||
Self: Sized + AddAnyAttr<Rndr>,
|
||||
V: AttributeValue<Rndr>,
|
||||
Rndr: Renderer,
|
||||
{
|
||||
fn aria_atomic(
|
||||
self,
|
||||
value: V,
|
||||
) -> <Self as AddAttribute<Attr<AriaAtomic, V, Rndr>, Rndr>>::Output {
|
||||
self.add_attr(aria_atomic(value))
|
||||
) -> <Self as AddAnyAttr<Rndr>>::Output<Attr<AriaAtomic, V, Rndr>> {
|
||||
self.add_any_attr(aria_atomic(value))
|
||||
}
|
||||
|
||||
fn aria_busy(
|
||||
self,
|
||||
value: V,
|
||||
) -> <Self as AddAttribute<Attr<AriaBusy, V, Rndr>, Rndr>>::Output {
|
||||
self.add_attr(aria_busy(value))
|
||||
) -> <Self as AddAnyAttr<Rndr>>::Output<Attr<AriaBusy, V, Rndr>> {
|
||||
self.add_any_attr(aria_busy(value))
|
||||
}
|
||||
fn aria_controls(
|
||||
self,
|
||||
value: V,
|
||||
) -> <Self as AddAttribute<Attr<AriaControls, V, Rndr>, Rndr>>::Output {
|
||||
self.add_attr(aria_controls(value))
|
||||
) -> <Self as AddAnyAttr<Rndr>>::Output<Attr<AriaControls, V, Rndr>> {
|
||||
self.add_any_attr(aria_controls(value))
|
||||
}
|
||||
fn aria_current(
|
||||
self,
|
||||
value: V,
|
||||
) -> <Self as AddAttribute<Attr<AriaCurrent, V, Rndr>, Rndr>>::Output {
|
||||
self.add_attr(aria_current(value))
|
||||
) -> <Self as AddAnyAttr<Rndr>>::Output<Attr<AriaCurrent, V, Rndr>> {
|
||||
self.add_any_attr(aria_current(value))
|
||||
}
|
||||
fn aria_describedby(
|
||||
self,
|
||||
value: V,
|
||||
) -> <Self as AddAttribute<Attr<AriaDescribedby, V, Rndr>, Rndr>>::Output
|
||||
) -> <Self as AddAnyAttr<Rndr>>::Output<Attr<AriaDescribedby, V, Rndr>>
|
||||
{
|
||||
self.add_attr(aria_describedby(value))
|
||||
self.add_any_attr(aria_describedby(value))
|
||||
}
|
||||
fn aria_description(
|
||||
self,
|
||||
value: V,
|
||||
) -> <Self as AddAttribute<Attr<AriaDescription, V, Rndr>, Rndr>>::Output
|
||||
) -> <Self as AddAnyAttr<Rndr>>::Output<Attr<AriaDescription, V, Rndr>>
|
||||
{
|
||||
self.add_attr(aria_description(value))
|
||||
self.add_any_attr(aria_description(value))
|
||||
}
|
||||
fn aria_details(
|
||||
self,
|
||||
value: V,
|
||||
) -> <Self as AddAttribute<Attr<AriaDetails, V, Rndr>, Rndr>>::Output {
|
||||
self.add_attr(aria_details(value))
|
||||
) -> <Self as AddAnyAttr<Rndr>>::Output<Attr<AriaDetails, V, Rndr>> {
|
||||
self.add_any_attr(aria_details(value))
|
||||
}
|
||||
fn aria_disabled(
|
||||
self,
|
||||
value: V,
|
||||
) -> <Self as AddAttribute<Attr<AriaDisabled, V, Rndr>, Rndr>>::Output {
|
||||
self.add_attr(aria_disabled(value))
|
||||
) -> <Self as AddAnyAttr<Rndr>>::Output<Attr<AriaDisabled, V, Rndr>> {
|
||||
self.add_any_attr(aria_disabled(value))
|
||||
}
|
||||
fn aria_dropeffect(
|
||||
self,
|
||||
value: V,
|
||||
) -> <Self as AddAttribute<Attr<AriaDropeffect, V, Rndr>, Rndr>>::Output
|
||||
{
|
||||
self.add_attr(aria_dropeffect(value))
|
||||
) -> <Self as AddAnyAttr<Rndr>>::Output<Attr<AriaDropeffect, V, Rndr>> {
|
||||
self.add_any_attr(aria_dropeffect(value))
|
||||
}
|
||||
fn aria_errormessage(
|
||||
self,
|
||||
value: V,
|
||||
) -> <Self as AddAttribute<Attr<AriaErrormessage, V, Rndr>, Rndr>>::Output
|
||||
) -> <Self as AddAnyAttr<Rndr>>::Output<Attr<AriaErrormessage, V, Rndr>>
|
||||
{
|
||||
self.add_attr(aria_errormessage(value))
|
||||
self.add_any_attr(aria_errormessage(value))
|
||||
}
|
||||
fn aria_flowto(
|
||||
self,
|
||||
value: V,
|
||||
) -> <Self as AddAttribute<Attr<AriaFlowto, V, Rndr>, Rndr>>::Output {
|
||||
self.add_attr(aria_flowto(value))
|
||||
) -> <Self as AddAnyAttr<Rndr>>::Output<Attr<AriaFlowto, V, Rndr>> {
|
||||
self.add_any_attr(aria_flowto(value))
|
||||
}
|
||||
fn aria_grabbed(
|
||||
self,
|
||||
value: V,
|
||||
) -> <Self as AddAttribute<Attr<AriaGrabbed, V, Rndr>, Rndr>>::Output {
|
||||
self.add_attr(aria_grabbed(value))
|
||||
) -> <Self as AddAnyAttr<Rndr>>::Output<Attr<AriaGrabbed, V, Rndr>> {
|
||||
self.add_any_attr(aria_grabbed(value))
|
||||
}
|
||||
fn aria_haspopup(
|
||||
self,
|
||||
value: V,
|
||||
) -> <Self as AddAttribute<Attr<AriaHaspopup, V, Rndr>, Rndr>>::Output {
|
||||
self.add_attr(aria_haspopup(value))
|
||||
) -> <Self as AddAnyAttr<Rndr>>::Output<Attr<AriaHaspopup, V, Rndr>> {
|
||||
self.add_any_attr(aria_haspopup(value))
|
||||
}
|
||||
fn aria_hidden(
|
||||
self,
|
||||
value: V,
|
||||
) -> <Self as AddAttribute<Attr<AriaHidden, V, Rndr>, Rndr>>::Output {
|
||||
self.add_attr(aria_hidden(value))
|
||||
) -> <Self as AddAnyAttr<Rndr>>::Output<Attr<AriaHidden, V, Rndr>> {
|
||||
self.add_any_attr(aria_hidden(value))
|
||||
}
|
||||
fn aria_invalid(
|
||||
self,
|
||||
value: V,
|
||||
) -> <Self as AddAttribute<Attr<AriaInvalid, V, Rndr>, Rndr>>::Output {
|
||||
self.add_attr(aria_invalid(value))
|
||||
) -> <Self as AddAnyAttr<Rndr>>::Output<Attr<AriaInvalid, V, Rndr>> {
|
||||
self.add_any_attr(aria_invalid(value))
|
||||
}
|
||||
fn aria_keyshortcuts(
|
||||
self,
|
||||
value: V,
|
||||
) -> <Self as AddAttribute<Attr<AriaKeyshortcuts, V, Rndr>, Rndr>>::Output
|
||||
) -> <Self as AddAnyAttr<Rndr>>::Output<Attr<AriaKeyshortcuts, V, Rndr>>
|
||||
{
|
||||
self.add_attr(aria_keyshortcuts(value))
|
||||
self.add_any_attr(aria_keyshortcuts(value))
|
||||
}
|
||||
fn aria_label(
|
||||
self,
|
||||
value: V,
|
||||
) -> <Self as AddAttribute<Attr<AriaLabel, V, Rndr>, Rndr>>::Output {
|
||||
self.add_attr(aria_label(value))
|
||||
) -> <Self as AddAnyAttr<Rndr>>::Output<Attr<AriaLabel, V, Rndr>> {
|
||||
self.add_any_attr(aria_label(value))
|
||||
}
|
||||
fn aria_labelledby(
|
||||
self,
|
||||
value: V,
|
||||
) -> <Self as AddAttribute<Attr<AriaLabelledby, V, Rndr>, Rndr>>::Output
|
||||
{
|
||||
self.add_attr(aria_labelledby(value))
|
||||
) -> <Self as AddAnyAttr<Rndr>>::Output<Attr<AriaLabelledby, V, Rndr>> {
|
||||
self.add_any_attr(aria_labelledby(value))
|
||||
}
|
||||
fn aria_live(
|
||||
self,
|
||||
value: V,
|
||||
) -> <Self as AddAttribute<Attr<AriaLive, V, Rndr>, Rndr>>::Output {
|
||||
self.add_attr(aria_live(value))
|
||||
) -> <Self as AddAnyAttr<Rndr>>::Output<Attr<AriaLive, V, Rndr>> {
|
||||
self.add_any_attr(aria_live(value))
|
||||
}
|
||||
fn aria_owns(
|
||||
self,
|
||||
value: V,
|
||||
) -> <Self as AddAttribute<Attr<AriaOwns, V, Rndr>, Rndr>>::Output {
|
||||
self.add_attr(aria_owns(value))
|
||||
) -> <Self as AddAnyAttr<Rndr>>::Output<Attr<AriaOwns, V, Rndr>> {
|
||||
self.add_any_attr(aria_owns(value))
|
||||
}
|
||||
fn aria_relevant(
|
||||
self,
|
||||
value: V,
|
||||
) -> <Self as AddAttribute<Attr<AriaRelevant, V, Rndr>, Rndr>>::Output {
|
||||
self.add_attr(aria_relevant(value))
|
||||
) -> <Self as AddAnyAttr<Rndr>>::Output<Attr<AriaRelevant, V, Rndr>> {
|
||||
self.add_any_attr(aria_relevant(value))
|
||||
}
|
||||
fn aria_roledescription(
|
||||
self,
|
||||
value: V,
|
||||
) -> <Self as AddAttribute<Attr<AriaRoledescription, V, Rndr>, Rndr>>::Output
|
||||
) -> <Self as AddAnyAttr<Rndr>>::Output<Attr<AriaRoledescription, V, Rndr>>
|
||||
{
|
||||
self.add_attr(aria_roledescription(value))
|
||||
self.add_any_attr(aria_roledescription(value))
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, Rndr, V> AriaAttributes<Rndr, V> for T
|
||||
where
|
||||
T: AddAttribute<Attr<AriaAtomic, V, Rndr>, Rndr>
|
||||
+ AddAttribute<Attr<AriaBusy, V, Rndr>, Rndr>
|
||||
+ AddAttribute<Attr<AriaControls, V, Rndr>, Rndr>
|
||||
+ AddAttribute<Attr<AriaCurrent, V, Rndr>, Rndr>
|
||||
+ AddAttribute<Attr<AriaDescribedby, V, Rndr>, Rndr>
|
||||
+ AddAttribute<Attr<AriaDescription, V, Rndr>, Rndr>
|
||||
+ AddAttribute<Attr<AriaDetails, V, Rndr>, Rndr>
|
||||
+ AddAttribute<Attr<AriaDisabled, V, Rndr>, Rndr>
|
||||
+ AddAttribute<Attr<AriaDropeffect, V, Rndr>, Rndr>
|
||||
+ AddAttribute<Attr<AriaErrormessage, V, Rndr>, Rndr>
|
||||
+ AddAttribute<Attr<AriaFlowto, V, Rndr>, Rndr>
|
||||
+ AddAttribute<Attr<AriaGrabbed, V, Rndr>, Rndr>
|
||||
+ AddAttribute<Attr<AriaHaspopup, V, Rndr>, Rndr>
|
||||
+ AddAttribute<Attr<AriaHidden, V, Rndr>, Rndr>
|
||||
+ AddAttribute<Attr<AriaInvalid, V, Rndr>, Rndr>
|
||||
+ AddAttribute<Attr<AriaKeyshortcuts, V, Rndr>, Rndr>
|
||||
+ AddAttribute<Attr<AriaLabel, V, Rndr>, Rndr>
|
||||
+ AddAttribute<Attr<AriaLabelledby, V, Rndr>, Rndr>
|
||||
+ AddAttribute<Attr<AriaLive, V, Rndr>, Rndr>
|
||||
+ AddAttribute<Attr<AriaOwns, V, Rndr>, Rndr>
|
||||
+ AddAttribute<Attr<AriaRelevant, V, Rndr>, Rndr>
|
||||
+ AddAttribute<Attr<AriaRoledescription, V, Rndr>, Rndr>,
|
||||
T: AddAnyAttr<Rndr>,
|
||||
V: AttributeValue<Rndr>,
|
||||
Rndr: Renderer,
|
||||
{
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
use super::NextAttribute;
|
||||
use crate::{
|
||||
html::attribute::{Attribute, AttributeValue},
|
||||
renderer::DomRenderer,
|
||||
view::{AddAttribute, Position, ToTemplate},
|
||||
view::{add_attr::AddAnyAttr, Position, ToTemplate},
|
||||
};
|
||||
use std::{borrow::Cow, marker::PhantomData, rc::Rc, sync::Arc};
|
||||
|
||||
|
@ -66,6 +67,22 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<K, V, R> NextAttribute<R> for CustomAttr<K, V, R>
|
||||
where
|
||||
K: CustomAttributeKey,
|
||||
V: AttributeValue<R>,
|
||||
R: DomRenderer,
|
||||
{
|
||||
type Output<NewAttr: Attribute<R>> = (Self, NewAttr);
|
||||
|
||||
fn add_any_attr<NewAttr: Attribute<R>>(
|
||||
self,
|
||||
new_attr: NewAttr,
|
||||
) -> Self::Output<NewAttr> {
|
||||
(self, new_attr)
|
||||
}
|
||||
}
|
||||
|
||||
impl<K, V, R> ToTemplate for CustomAttr<K, V, R>
|
||||
where
|
||||
K: CustomAttributeKey,
|
||||
|
@ -125,20 +142,20 @@ where
|
|||
K: CustomAttributeKey,
|
||||
V: AttributeValue<Rndr>,
|
||||
Rndr: DomRenderer,
|
||||
Self: Sized + AddAttribute<CustomAttr<K, V, Rndr>, Rndr>,
|
||||
Self: Sized + AddAnyAttr<Rndr>,
|
||||
{
|
||||
fn attr(
|
||||
self,
|
||||
key: K,
|
||||
value: V,
|
||||
) -> <Self as AddAttribute<CustomAttr<K, V, Rndr>, Rndr>>::Output {
|
||||
self.add_attr(custom_attribute(key, value))
|
||||
) -> <Self as AddAnyAttr<Rndr>>::Output<CustomAttr<K, V, Rndr>> {
|
||||
self.add_any_attr(custom_attribute(key, value))
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, K, V, Rndr> CustomAttribute<K, V, Rndr> for T
|
||||
where
|
||||
T: AddAttribute<CustomAttr<K, V, Rndr>, Rndr>,
|
||||
T: AddAnyAttr<Rndr>,
|
||||
K: CustomAttributeKey,
|
||||
V: AttributeValue<Rndr>,
|
||||
Rndr: DomRenderer,
|
||||
|
|
|
@ -9,7 +9,7 @@ use crate::{
|
|||
style::{style, IntoStyle, Style},
|
||||
},
|
||||
renderer::DomRenderer,
|
||||
view::AddAttribute,
|
||||
view::add_attr::AddAnyAttr,
|
||||
};
|
||||
use core::convert::From;
|
||||
|
||||
|
@ -25,14 +25,14 @@ where
|
|||
|
||||
impl<T, C, Rndr> ClassAttribute<C, Rndr> for T
|
||||
where
|
||||
T: AddAttribute<Class<C, Rndr>, Rndr>,
|
||||
T: AddAnyAttr<Rndr>,
|
||||
C: IntoClass<Rndr>,
|
||||
Rndr: DomRenderer,
|
||||
{
|
||||
type Output = <Self as AddAttribute<Class<C, Rndr>, Rndr>>::Output;
|
||||
type Output = <Self as AddAnyAttr<Rndr>>::Output<Class<C, Rndr>>;
|
||||
|
||||
fn class(self, value: C) -> Self::Output {
|
||||
self.add_attr(class(value))
|
||||
self.add_any_attr(class(value))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -48,14 +48,14 @@ where
|
|||
|
||||
impl<T, K, P, Rndr> PropAttribute<K, P, Rndr> for T
|
||||
where
|
||||
T: AddAttribute<Property<K, P, Rndr>, Rndr>,
|
||||
T: AddAnyAttr<Rndr>,
|
||||
K: AsRef<str>,
|
||||
P: IntoProperty<Rndr>,
|
||||
Rndr: DomRenderer,
|
||||
{
|
||||
type Output = <Self as AddAttribute<Property<K, P, Rndr>, Rndr>>::Output;
|
||||
type Output = <Self as AddAnyAttr<Rndr>>::Output<Property<K, P, Rndr>>;
|
||||
fn prop(self, key: K, value: P) -> Self::Output {
|
||||
self.add_attr(property(key, value))
|
||||
self.add_any_attr(property(key, value))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -71,14 +71,14 @@ where
|
|||
|
||||
impl<T, S, Rndr> StyleAttribute<S, Rndr> for T
|
||||
where
|
||||
T: AddAttribute<Style<S, Rndr>, Rndr>,
|
||||
T: AddAnyAttr<Rndr>,
|
||||
S: IntoStyle<Rndr>,
|
||||
Rndr: DomRenderer,
|
||||
{
|
||||
type Output = <Self as AddAttribute<Style<S, Rndr>, Rndr>>::Output;
|
||||
type Output = <Self as AddAnyAttr<Rndr>>::Output<Style<S, Rndr>>;
|
||||
|
||||
fn style(self, value: S) -> Self::Output {
|
||||
self.add_attr(style(value))
|
||||
self.add_any_attr(style(value))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -90,17 +90,17 @@ pub trait OnAttribute<E, F, Rndr> {
|
|||
|
||||
impl<T, E, F, Rndr> OnAttribute<E, F, Rndr> for T
|
||||
where
|
||||
T: AddAttribute<On<Rndr>, Rndr>,
|
||||
T: AddAnyAttr<Rndr>,
|
||||
E: EventDescriptor + 'static,
|
||||
E::EventType: 'static,
|
||||
E::EventType: From<Rndr::Event>,
|
||||
F: FnMut(E::EventType) + 'static,
|
||||
Rndr: DomRenderer,
|
||||
{
|
||||
type Output = <Self as AddAttribute<On<Rndr>, Rndr>>::Output;
|
||||
type Output = <Self as AddAnyAttr<Rndr>>::Output<On<Rndr>>;
|
||||
|
||||
fn on(self, event: E, cb: F) -> Self::Output {
|
||||
self.add_attr(on(event, cb))
|
||||
self.add_any_attr(on(event, cb))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -113,7 +113,7 @@ pub trait OnTargetAttribute<E, F, T, Rndr> {
|
|||
impl<T, E, F, Rndr> OnTargetAttribute<E, F, Self, Rndr> for T
|
||||
where
|
||||
Self: ElementType,
|
||||
T: AddAttribute<On<Rndr>, Rndr>,
|
||||
T: AddAnyAttr<Rndr>,
|
||||
E: EventDescriptor + 'static,
|
||||
E::EventType: 'static,
|
||||
E::EventType: From<Rndr::Event>,
|
||||
|
@ -121,276 +121,221 @@ where
|
|||
+ 'static,
|
||||
Rndr: DomRenderer,
|
||||
{
|
||||
type Output = <Self as AddAttribute<On<Rndr>, Rndr>>::Output;
|
||||
fn on_target(self, event: E, cb: F) -> Self::Output
|
||||
where {
|
||||
self.add_attr(on_target(event, cb))
|
||||
type Output = <Self as AddAnyAttr<Rndr>>::Output<On<Rndr>>;
|
||||
|
||||
fn on_target(self, event: E, cb: F) -> Self::Output {
|
||||
self.add_any_attr(on_target(event, cb))
|
||||
}
|
||||
}
|
||||
|
||||
pub trait GlobalAttributes<Rndr, V>
|
||||
where
|
||||
Self: Sized
|
||||
+ AddAttribute<Attr<Accesskey, V, Rndr>, Rndr>
|
||||
+ AddAttribute<Attr<Autocapitalize, V, Rndr>, Rndr>
|
||||
+ AddAttribute<Attr<Autofocus, V, Rndr>, Rndr>
|
||||
+ AddAttribute<Attr<Contenteditable, V, Rndr>, Rndr>
|
||||
+ AddAttribute<Attr<Dir, V, Rndr>, Rndr>
|
||||
+ AddAttribute<Attr<Draggable, V, Rndr>, Rndr>
|
||||
+ AddAttribute<Attr<Enterkeyhint, V, Rndr>, Rndr>
|
||||
+ AddAttribute<Attr<Hidden, V, Rndr>, Rndr>
|
||||
+ AddAttribute<Attr<Id, V, Rndr>, Rndr>
|
||||
+ AddAttribute<Attr<Inert, V, Rndr>, Rndr>
|
||||
+ AddAttribute<Attr<Inputmode, V, Rndr>, Rndr>
|
||||
+ AddAttribute<Attr<Is, V, Rndr>, Rndr>
|
||||
+ AddAttribute<Attr<Itemid, V, Rndr>, Rndr>
|
||||
+ AddAttribute<Attr<Itemprop, V, Rndr>, Rndr>
|
||||
+ AddAttribute<Attr<Itemref, V, Rndr>, Rndr>
|
||||
+ AddAttribute<Attr<Itemscope, V, Rndr>, Rndr>
|
||||
+ AddAttribute<Attr<Itemtype, V, Rndr>, Rndr>
|
||||
+ AddAttribute<Attr<Lang, V, Rndr>, Rndr>
|
||||
+ AddAttribute<Attr<Nonce, V, Rndr>, Rndr>
|
||||
+ AddAttribute<Attr<Part, V, Rndr>, Rndr>
|
||||
+ AddAttribute<Attr<Popover, V, Rndr>, Rndr>
|
||||
+ AddAttribute<Attr<Role, V, Rndr>, Rndr>
|
||||
+ AddAttribute<Attr<Slot, V, Rndr>, Rndr>
|
||||
+ AddAttribute<Attr<Spellcheck, V, Rndr>, Rndr>
|
||||
+ AddAttribute<Attr<Tabindex, V, Rndr>, Rndr>
|
||||
+ AddAttribute<Attr<Title, V, Rndr>, Rndr>
|
||||
+ AddAttribute<Attr<Translate, V, Rndr>, Rndr>
|
||||
+ AddAttribute<Attr<Virtualkeyboardpolicy, V, Rndr>, Rndr>,
|
||||
Self: Sized + AddAnyAttr<Rndr>,
|
||||
V: AttributeValue<Rndr>,
|
||||
Rndr: Renderer,
|
||||
{
|
||||
fn accesskey(
|
||||
self,
|
||||
value: V,
|
||||
) -> <Self as AddAttribute<Attr<Accesskey, V, Rndr>, Rndr>>::Output {
|
||||
self.add_attr(accesskey(value))
|
||||
) -> <Self as AddAnyAttr<Rndr>>::Output<Attr<Accesskey, V, Rndr>> {
|
||||
self.add_any_attr(accesskey(value))
|
||||
}
|
||||
|
||||
fn autocapitalize(
|
||||
self,
|
||||
value: V,
|
||||
) -> <Self as AddAttribute<Attr<Autocapitalize, V, Rndr>, Rndr>>::Output
|
||||
{
|
||||
self.add_attr(autocapitalize(value))
|
||||
) -> <Self as AddAnyAttr<Rndr>>::Output<Attr<Autocapitalize, V, Rndr>> {
|
||||
self.add_any_attr(autocapitalize(value))
|
||||
}
|
||||
|
||||
fn autofocus(
|
||||
self,
|
||||
value: V,
|
||||
) -> <Self as AddAttribute<Attr<Autofocus, V, Rndr>, Rndr>>::Output {
|
||||
self.add_attr(autofocus(value))
|
||||
) -> <Self as AddAnyAttr<Rndr>>::Output<Attr<Autofocus, V, Rndr>> {
|
||||
self.add_any_attr(autofocus(value))
|
||||
}
|
||||
|
||||
fn contenteditable(
|
||||
self,
|
||||
value: V,
|
||||
) -> <Self as AddAttribute<Attr<Contenteditable, V, Rndr>, Rndr>>::Output
|
||||
) -> <Self as AddAnyAttr<Rndr>>::Output<Attr<Contenteditable, V, Rndr>>
|
||||
{
|
||||
self.add_attr(contenteditable(value))
|
||||
self.add_any_attr(contenteditable(value))
|
||||
}
|
||||
|
||||
fn dir(
|
||||
self,
|
||||
value: V,
|
||||
) -> <Self as AddAttribute<Attr<Dir, V, Rndr>, Rndr>>::Output {
|
||||
self.add_attr(dir(value))
|
||||
) -> <Self as AddAnyAttr<Rndr>>::Output<Attr<Dir, V, Rndr>> {
|
||||
self.add_any_attr(dir(value))
|
||||
}
|
||||
|
||||
fn draggable(
|
||||
self,
|
||||
value: V,
|
||||
) -> <Self as AddAttribute<Attr<Draggable, V, Rndr>, Rndr>>::Output {
|
||||
self.add_attr(draggable(value))
|
||||
) -> <Self as AddAnyAttr<Rndr>>::Output<Attr<Draggable, V, Rndr>> {
|
||||
self.add_any_attr(draggable(value))
|
||||
}
|
||||
|
||||
fn enterkeyhint(
|
||||
self,
|
||||
value: V,
|
||||
) -> <Self as AddAttribute<Attr<Enterkeyhint, V, Rndr>, Rndr>>::Output {
|
||||
self.add_attr(enterkeyhint(value))
|
||||
) -> <Self as AddAnyAttr<Rndr>>::Output<Attr<Enterkeyhint, V, Rndr>> {
|
||||
self.add_any_attr(enterkeyhint(value))
|
||||
}
|
||||
|
||||
fn hidden(
|
||||
self,
|
||||
value: V,
|
||||
) -> <Self as AddAttribute<Attr<Hidden, V, Rndr>, Rndr>>::Output {
|
||||
self.add_attr(hidden(value))
|
||||
) -> <Self as AddAnyAttr<Rndr>>::Output<Attr<Hidden, V, Rndr>> {
|
||||
self.add_any_attr(hidden(value))
|
||||
}
|
||||
|
||||
fn id(
|
||||
self,
|
||||
value: V,
|
||||
) -> <Self as AddAttribute<Attr<Id, V, Rndr>, Rndr>>::Output {
|
||||
self.add_attr(id(value))
|
||||
) -> <Self as AddAnyAttr<Rndr>>::Output<Attr<Id, V, Rndr>> {
|
||||
self.add_any_attr(id(value))
|
||||
}
|
||||
|
||||
fn inert(
|
||||
self,
|
||||
value: V,
|
||||
) -> <Self as AddAttribute<Attr<Inert, V, Rndr>, Rndr>>::Output {
|
||||
self.add_attr(inert(value))
|
||||
) -> <Self as AddAnyAttr<Rndr>>::Output<Attr<Inert, V, Rndr>> {
|
||||
self.add_any_attr(inert(value))
|
||||
}
|
||||
|
||||
fn inputmode(
|
||||
self,
|
||||
value: V,
|
||||
) -> <Self as AddAttribute<Attr<Inputmode, V, Rndr>, Rndr>>::Output {
|
||||
self.add_attr(inputmode(value))
|
||||
) -> <Self as AddAnyAttr<Rndr>>::Output<Attr<Inputmode, V, Rndr>> {
|
||||
self.add_any_attr(inputmode(value))
|
||||
}
|
||||
|
||||
fn is(
|
||||
self,
|
||||
value: V,
|
||||
) -> <Self as AddAttribute<Attr<Is, V, Rndr>, Rndr>>::Output {
|
||||
self.add_attr(is(value))
|
||||
) -> <Self as AddAnyAttr<Rndr>>::Output<Attr<Is, V, Rndr>> {
|
||||
self.add_any_attr(is(value))
|
||||
}
|
||||
|
||||
fn itemid(
|
||||
self,
|
||||
value: V,
|
||||
) -> <Self as AddAttribute<Attr<Itemid, V, Rndr>, Rndr>>::Output {
|
||||
self.add_attr(itemid(value))
|
||||
) -> <Self as AddAnyAttr<Rndr>>::Output<Attr<Itemid, V, Rndr>> {
|
||||
self.add_any_attr(itemid(value))
|
||||
}
|
||||
|
||||
fn itemprop(
|
||||
self,
|
||||
value: V,
|
||||
) -> <Self as AddAttribute<Attr<Itemprop, V, Rndr>, Rndr>>::Output {
|
||||
self.add_attr(itemprop(value))
|
||||
) -> <Self as AddAnyAttr<Rndr>>::Output<Attr<Itemprop, V, Rndr>> {
|
||||
self.add_any_attr(itemprop(value))
|
||||
}
|
||||
|
||||
fn itemref(
|
||||
self,
|
||||
value: V,
|
||||
) -> <Self as AddAttribute<Attr<Itemref, V, Rndr>, Rndr>>::Output {
|
||||
self.add_attr(itemref(value))
|
||||
) -> <Self as AddAnyAttr<Rndr>>::Output<Attr<Itemref, V, Rndr>> {
|
||||
self.add_any_attr(itemref(value))
|
||||
}
|
||||
|
||||
fn itemscope(
|
||||
self,
|
||||
value: V,
|
||||
) -> <Self as AddAttribute<Attr<Itemscope, V, Rndr>, Rndr>>::Output {
|
||||
self.add_attr(itemscope(value))
|
||||
) -> <Self as AddAnyAttr<Rndr>>::Output<Attr<Itemscope, V, Rndr>> {
|
||||
self.add_any_attr(itemscope(value))
|
||||
}
|
||||
|
||||
fn itemtype(
|
||||
self,
|
||||
value: V,
|
||||
) -> <Self as AddAttribute<Attr<Itemtype, V, Rndr>, Rndr>>::Output {
|
||||
self.add_attr(itemtype(value))
|
||||
) -> <Self as AddAnyAttr<Rndr>>::Output<Attr<Itemtype, V, Rndr>> {
|
||||
self.add_any_attr(itemtype(value))
|
||||
}
|
||||
|
||||
fn lang(
|
||||
self,
|
||||
value: V,
|
||||
) -> <Self as AddAttribute<Attr<Lang, V, Rndr>, Rndr>>::Output {
|
||||
self.add_attr(lang(value))
|
||||
) -> <Self as AddAnyAttr<Rndr>>::Output<Attr<Lang, V, Rndr>> {
|
||||
self.add_any_attr(lang(value))
|
||||
}
|
||||
|
||||
fn nonce(
|
||||
self,
|
||||
value: V,
|
||||
) -> <Self as AddAttribute<Attr<Nonce, V, Rndr>, Rndr>>::Output {
|
||||
self.add_attr(nonce(value))
|
||||
) -> <Self as AddAnyAttr<Rndr>>::Output<Attr<Nonce, V, Rndr>> {
|
||||
self.add_any_attr(nonce(value))
|
||||
}
|
||||
|
||||
fn part(
|
||||
self,
|
||||
value: V,
|
||||
) -> <Self as AddAttribute<Attr<Part, V, Rndr>, Rndr>>::Output {
|
||||
self.add_attr(part(value))
|
||||
) -> <Self as AddAnyAttr<Rndr>>::Output<Attr<Part, V, Rndr>> {
|
||||
self.add_any_attr(part(value))
|
||||
}
|
||||
|
||||
fn popover(
|
||||
self,
|
||||
value: V,
|
||||
) -> <Self as AddAttribute<Attr<Popover, V, Rndr>, Rndr>>::Output {
|
||||
self.add_attr(popover(value))
|
||||
) -> <Self as AddAnyAttr<Rndr>>::Output<Attr<Popover, V, Rndr>> {
|
||||
self.add_any_attr(popover(value))
|
||||
}
|
||||
|
||||
fn role(
|
||||
self,
|
||||
value: V,
|
||||
) -> <Self as AddAttribute<Attr<Role, V, Rndr>, Rndr>>::Output {
|
||||
self.add_attr(role(value))
|
||||
) -> <Self as AddAnyAttr<Rndr>>::Output<Attr<Role, V, Rndr>> {
|
||||
self.add_any_attr(role(value))
|
||||
}
|
||||
|
||||
fn slot(
|
||||
self,
|
||||
value: V,
|
||||
) -> <Self as AddAttribute<Attr<Slot, V, Rndr>, Rndr>>::Output {
|
||||
self.add_attr(slot(value))
|
||||
) -> <Self as AddAnyAttr<Rndr>>::Output<Attr<Slot, V, Rndr>> {
|
||||
self.add_any_attr(slot(value))
|
||||
}
|
||||
|
||||
fn spellcheck(
|
||||
self,
|
||||
value: V,
|
||||
) -> <Self as AddAttribute<Attr<Spellcheck, V, Rndr>, Rndr>>::Output {
|
||||
self.add_attr(spellcheck(value))
|
||||
) -> <Self as AddAnyAttr<Rndr>>::Output<Attr<Spellcheck, V, Rndr>> {
|
||||
self.add_any_attr(spellcheck(value))
|
||||
}
|
||||
|
||||
fn tabindex(
|
||||
self,
|
||||
value: V,
|
||||
) -> <Self as AddAttribute<Attr<Tabindex, V, Rndr>, Rndr>>::Output {
|
||||
self.add_attr(tabindex(value))
|
||||
) -> <Self as AddAnyAttr<Rndr>>::Output<Attr<Tabindex, V, Rndr>> {
|
||||
self.add_any_attr(tabindex(value))
|
||||
}
|
||||
|
||||
fn title(
|
||||
self,
|
||||
value: V,
|
||||
) -> <Self as AddAttribute<Attr<Title, V, Rndr>, Rndr>>::Output {
|
||||
self.add_attr(title(value))
|
||||
) -> <Self as AddAnyAttr<Rndr>>::Output<Attr<Title, V, Rndr>> {
|
||||
self.add_any_attr(title(value))
|
||||
}
|
||||
|
||||
fn translate(
|
||||
self,
|
||||
value: V,
|
||||
) -> <Self as AddAttribute<Attr<Translate, V, Rndr>, Rndr>>::Output {
|
||||
self.add_attr(translate(value))
|
||||
) -> <Self as AddAnyAttr<Rndr>>::Output<Attr<Translate, V, Rndr>> {
|
||||
self.add_any_attr(translate(value))
|
||||
}
|
||||
|
||||
fn virtualkeyboardpolicy(
|
||||
self,
|
||||
value: V,
|
||||
) -> <Self as AddAttribute<Attr<Virtualkeyboardpolicy, V, Rndr>, Rndr>>::Output{
|
||||
self.add_attr(virtualkeyboardpolicy(value))
|
||||
) -> <Self as AddAnyAttr<Rndr>>::Output<Attr<Virtualkeyboardpolicy, V, Rndr>>
|
||||
{
|
||||
self.add_any_attr(virtualkeyboardpolicy(value))
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, Rndr, V> GlobalAttributes<Rndr, V> for T
|
||||
where
|
||||
T: AddAttribute<Attr<Accesskey, V, Rndr>, Rndr>
|
||||
+ AddAttribute<Attr<Autocapitalize, V, Rndr>, Rndr>
|
||||
+ AddAttribute<Attr<Autofocus, V, Rndr>, Rndr>
|
||||
+ AddAttribute<Attr<Contenteditable, V, Rndr>, Rndr>
|
||||
+ AddAttribute<Attr<Dir, V, Rndr>, Rndr>
|
||||
+ AddAttribute<Attr<Draggable, V, Rndr>, Rndr>
|
||||
+ AddAttribute<Attr<Enterkeyhint, V, Rndr>, Rndr>
|
||||
+ AddAttribute<Attr<Hidden, V, Rndr>, Rndr>
|
||||
+ AddAttribute<Attr<Id, V, Rndr>, Rndr>
|
||||
+ AddAttribute<Attr<Inert, V, Rndr>, Rndr>
|
||||
+ AddAttribute<Attr<Inputmode, V, Rndr>, Rndr>
|
||||
+ AddAttribute<Attr<Is, V, Rndr>, Rndr>
|
||||
+ AddAttribute<Attr<Itemid, V, Rndr>, Rndr>
|
||||
+ AddAttribute<Attr<Itemprop, V, Rndr>, Rndr>
|
||||
+ AddAttribute<Attr<Itemref, V, Rndr>, Rndr>
|
||||
+ AddAttribute<Attr<Itemscope, V, Rndr>, Rndr>
|
||||
+ AddAttribute<Attr<Itemtype, V, Rndr>, Rndr>
|
||||
+ AddAttribute<Attr<Lang, V, Rndr>, Rndr>
|
||||
+ AddAttribute<Attr<Nonce, V, Rndr>, Rndr>
|
||||
+ AddAttribute<Attr<Part, V, Rndr>, Rndr>
|
||||
+ AddAttribute<Attr<Popover, V, Rndr>, Rndr>
|
||||
+ AddAttribute<Attr<Role, V, Rndr>, Rndr>
|
||||
+ AddAttribute<Attr<Slot, V, Rndr>, Rndr>
|
||||
+ AddAttribute<Attr<Spellcheck, V, Rndr>, Rndr>
|
||||
+ AddAttribute<Attr<Tabindex, V, Rndr>, Rndr>
|
||||
+ AddAttribute<Attr<Title, V, Rndr>, Rndr>
|
||||
+ AddAttribute<Attr<Translate, V, Rndr>, Rndr>
|
||||
+ AddAttribute<Attr<Virtualkeyboardpolicy, V, Rndr>, Rndr>,
|
||||
T: AddAnyAttr<Rndr>,
|
||||
V: AttributeValue<Rndr>,
|
||||
Rndr: Renderer,
|
||||
{
|
||||
|
|
|
@ -11,7 +11,7 @@ pub use key::*;
|
|||
use std::{fmt::Debug, marker::PhantomData};
|
||||
pub use value::*;
|
||||
|
||||
pub trait Attribute<R: Renderer> {
|
||||
pub trait Attribute<R: Renderer>: NextAttribute<R> {
|
||||
const MIN_LENGTH: usize;
|
||||
|
||||
type State;
|
||||
|
@ -31,6 +31,15 @@ pub trait Attribute<R: Renderer> {
|
|||
fn rebuild(self, state: &mut Self::State);
|
||||
}
|
||||
|
||||
pub trait NextAttribute<R: Renderer> {
|
||||
type Output<NewAttr: Attribute<R>>: Attribute<R>;
|
||||
|
||||
fn add_any_attr<NewAttr: Attribute<R>>(
|
||||
self,
|
||||
new_attr: NewAttr,
|
||||
) -> Self::Output<NewAttr>;
|
||||
}
|
||||
|
||||
impl<R> Attribute<R> for ()
|
||||
where
|
||||
R: Renderer,
|
||||
|
@ -56,6 +65,20 @@ where
|
|||
fn rebuild(self, _state: &mut Self::State) {}
|
||||
}
|
||||
|
||||
impl<R> NextAttribute<R> for ()
|
||||
where
|
||||
R: Renderer,
|
||||
{
|
||||
type Output<NewAttr: Attribute<R>> = (NewAttr,);
|
||||
|
||||
fn add_any_attr<NewAttr: Attribute<R>>(
|
||||
self,
|
||||
new_attr: NewAttr,
|
||||
) -> Self::Output<NewAttr> {
|
||||
(new_attr,)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Attr<K, V, R>(pub K, pub V, PhantomData<R>)
|
||||
where
|
||||
|
@ -113,6 +136,22 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<K, V, R> NextAttribute<R> for Attr<K, V, R>
|
||||
where
|
||||
K: AttributeKey,
|
||||
V: AttributeValue<R>,
|
||||
R: Renderer,
|
||||
{
|
||||
type Output<NewAttr: Attribute<R>> = (Self, NewAttr);
|
||||
|
||||
fn add_any_attr<NewAttr: Attribute<R>>(
|
||||
self,
|
||||
new_attr: NewAttr,
|
||||
) -> Self::Output<NewAttr> {
|
||||
(self, new_attr)
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! impl_attr_for_tuples {
|
||||
($first:ident, $($ty:ident),* $(,)?) => {
|
||||
impl<$first, $($ty),*, Rndr> Attribute<Rndr> for ($first, $($ty,)*)
|
||||
|
@ -161,6 +200,93 @@ macro_rules! impl_attr_for_tuples {
|
|||
$([<$ty:lower>].rebuild([<view_ $ty:lower>]));*
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<$first, $($ty),*, Rndr> NextAttribute<Rndr> for ($first, $($ty,)*)
|
||||
where
|
||||
$first: Attribute<Rndr>,
|
||||
$($ty: Attribute<Rndr>),*,
|
||||
Rndr: Renderer
|
||||
{
|
||||
type Output<NewAttr: Attribute<Rndr>> = ($first, $($ty,)* NewAttr);
|
||||
|
||||
fn add_any_attr<NewAttr: Attribute<Rndr>>(
|
||||
self,
|
||||
new_attr: NewAttr,
|
||||
) -> Self::Output<NewAttr> {
|
||||
#[allow(non_snake_case)]
|
||||
let ($first, $($ty,)*) = self;
|
||||
($first, $($ty,)* new_attr)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! impl_attr_for_tuples_truncate_additional {
|
||||
($first:ident, $($ty:ident),* $(,)?) => {
|
||||
impl<$first, $($ty),*, Rndr> Attribute<Rndr> for ($first, $($ty,)*)
|
||||
where
|
||||
$first: Attribute<Rndr>,
|
||||
$($ty: Attribute<Rndr>),*,
|
||||
Rndr: Renderer
|
||||
{
|
||||
const MIN_LENGTH: usize = $first::MIN_LENGTH $(+ $ty::MIN_LENGTH)*;
|
||||
|
||||
type State = ($first::State, $($ty::State,)*);
|
||||
|
||||
fn to_html(self, buf: &mut String, class: &mut String, style: &mut String, inner_html: &mut String,) {
|
||||
paste::paste! {
|
||||
let ([<$first:lower>], $([<$ty:lower>],)* ) = self;
|
||||
[<$first:lower>].to_html(buf, class, style, inner_html);
|
||||
$([<$ty:lower>].to_html(buf, class, style, inner_html));*
|
||||
}
|
||||
}
|
||||
|
||||
fn hydrate<const FROM_SERVER: bool>(self, el: &Rndr::Element) -> Self::State {
|
||||
paste::paste! {
|
||||
let ([<$first:lower>], $([<$ty:lower>],)* ) = self;
|
||||
(
|
||||
[<$first:lower>].hydrate::<FROM_SERVER>(el),
|
||||
$([<$ty:lower>].hydrate::<FROM_SERVER>(el)),*
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fn build(self, el: &Rndr::Element) -> Self::State {
|
||||
paste::paste! {
|
||||
let ([<$first:lower>], $([<$ty:lower>],)*) = self;
|
||||
(
|
||||
[<$first:lower>].build(el),
|
||||
$([<$ty:lower>].build(el)),*
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fn rebuild(self, state: &mut Self::State) {
|
||||
paste::paste! {
|
||||
let ([<$first:lower>], $([<$ty:lower>],)*) = self;
|
||||
let ([<view_ $first:lower>], $([<view_ $ty:lower>],)*) = state;
|
||||
[<$first:lower>].rebuild([<view_ $first:lower>]);
|
||||
$([<$ty:lower>].rebuild([<view_ $ty:lower>]));*
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<$first, $($ty),*, Rndr> NextAttribute<Rndr> for ($first, $($ty,)*)
|
||||
where
|
||||
$first: Attribute<Rndr>,
|
||||
$($ty: Attribute<Rndr>),*,
|
||||
Rndr: Renderer
|
||||
{
|
||||
type Output<NewAttr: Attribute<Rndr>> = ($first, $($ty,)*);
|
||||
|
||||
fn add_any_attr<NewAttr: Attribute<Rndr>>(
|
||||
self,
|
||||
_new_attr: NewAttr,
|
||||
) -> Self::Output<NewAttr> {
|
||||
todo!("adding more than 26 attributes is not supported");
|
||||
//($first, $($ty,)*)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -200,6 +326,21 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<A, Rndr> NextAttribute<Rndr> for (A,)
|
||||
where
|
||||
A: Attribute<Rndr>,
|
||||
Rndr: Renderer,
|
||||
{
|
||||
type Output<NewAttr: Attribute<Rndr>> = (A, NewAttr);
|
||||
|
||||
fn add_any_attr<NewAttr: Attribute<Rndr>>(
|
||||
self,
|
||||
new_attr: NewAttr,
|
||||
) -> Self::Output<NewAttr> {
|
||||
(self.0, new_attr)
|
||||
}
|
||||
}
|
||||
|
||||
impl_attr_for_tuples!(A, B);
|
||||
impl_attr_for_tuples!(A, B, C);
|
||||
impl_attr_for_tuples!(A, B, C, D);
|
||||
|
@ -236,7 +377,7 @@ impl_attr_for_tuples!(
|
|||
impl_attr_for_tuples!(
|
||||
A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y
|
||||
);
|
||||
impl_attr_for_tuples!(
|
||||
impl_attr_for_tuples_truncate_additional!(
|
||||
A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y,
|
||||
Z
|
||||
);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use super::attribute::Attribute;
|
||||
use super::attribute::{Attribute, NextAttribute};
|
||||
use crate::{
|
||||
renderer::DomRenderer,
|
||||
view::{Position, ToTemplate},
|
||||
|
@ -59,6 +59,21 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<C, R> NextAttribute<R> for Class<C, R>
|
||||
where
|
||||
C: IntoClass<R>,
|
||||
R: DomRenderer,
|
||||
{
|
||||
type Output<NewAttr: Attribute<R>> = (Self, NewAttr);
|
||||
|
||||
fn add_any_attr<NewAttr: Attribute<R>>(
|
||||
self,
|
||||
new_attr: NewAttr,
|
||||
) -> Self::Output<NewAttr> {
|
||||
(self, new_attr)
|
||||
}
|
||||
}
|
||||
|
||||
impl<C, R> ToTemplate for Class<C, R>
|
||||
where
|
||||
C: IntoClass<R>,
|
||||
|
|
|
@ -49,13 +49,13 @@ macro_rules! html_elements {
|
|||
#[doc = concat!("The [`", stringify!($attr), "`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/", stringify!($tag), "#", stringify!($attr) ,") attribute on `<", stringify!($tag), ">`.")]
|
||||
pub fn $attr<V>(self, value: V) -> HtmlElement <
|
||||
[<$tag:camel>],
|
||||
<At as TupleBuilder<Attr<$crate::html::attribute::[<$attr:camel>], V, Rndr>>>::Output,
|
||||
<At as TupleBuilder>::Output<Attr<$crate::html::attribute::[<$attr:camel>], V, Rndr>>,
|
||||
Ch, Rndr
|
||||
>
|
||||
where
|
||||
V: AttributeValue<Rndr>,
|
||||
At: TupleBuilder<Attr<$crate::html::attribute::[<$attr:camel>], V, Rndr>>,
|
||||
<At as TupleBuilder<Attr<$crate::html::attribute::[<$attr:camel>], V, Rndr>>>::Output: Attribute<Rndr>,
|
||||
At: TupleBuilder,
|
||||
<At as TupleBuilder>::Output<Attr<$crate::html::attribute::[<$attr:camel>], V, Rndr>>: Attribute<Rndr>,
|
||||
{
|
||||
let HtmlElement { tag, rndr, children, attributes } = self;
|
||||
HtmlElement {
|
||||
|
@ -135,14 +135,15 @@ macro_rules! html_self_closing_elements {
|
|||
#[doc = concat!("The [`", stringify!($attr), "`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/", stringify!($tag), "#", stringify!($attr) ,") attribute on `<", stringify!($tag), ">`.")]
|
||||
pub fn $attr<V>(self, value: V) -> HtmlElement<
|
||||
[<$tag:camel>],
|
||||
<At as TupleBuilder<Attr<$crate::html::attribute::[<$attr:camel>], V, Rndr>>>::Output,
|
||||
<At as TupleBuilder>::Output<Attr<$crate::html::attribute::[<$attr:camel>], V, Rndr>>,
|
||||
(),
|
||||
Rndr
|
||||
>
|
||||
where
|
||||
V: AttributeValue<Rndr>,
|
||||
At: TupleBuilder<Attr<$crate::html::attribute::[<$attr:camel>], V, Rndr>>,
|
||||
<At as TupleBuilder<Attr<$crate::html::attribute::[<$attr:camel>], V, Rndr>>>::Output: Attribute<Rndr>,
|
||||
At: TupleBuilder,
|
||||
<At as TupleBuilder>::Output<Attr<$crate::html::attribute::[<$attr:camel>], V, Rndr>>: Attribute<Rndr>,
|
||||
|
||||
{
|
||||
let HtmlElement { tag, rndr, children, attributes } = self;
|
||||
HtmlElement {
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
use super::{ElementWithChildren, HtmlElement};
|
||||
use crate::{
|
||||
html::{attribute::Attribute, element::AddAttribute},
|
||||
html::attribute::{Attribute, NextAttribute},
|
||||
prelude::Render,
|
||||
renderer::{DomRenderer, Renderer},
|
||||
view::add_attr::AddAnyAttr,
|
||||
};
|
||||
use std::marker::PhantomData;
|
||||
|
||||
|
@ -68,33 +69,48 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<T, R> NextAttribute<R> for InnerHtml<T, R>
|
||||
where
|
||||
T: AsRef<str> + PartialEq,
|
||||
R: DomRenderer,
|
||||
{
|
||||
type Output<NewAttr: Attribute<R>> = (Self, NewAttr);
|
||||
|
||||
fn add_any_attr<NewAttr: Attribute<R>>(
|
||||
self,
|
||||
new_attr: NewAttr,
|
||||
) -> Self::Output<NewAttr> {
|
||||
(self, new_attr)
|
||||
}
|
||||
}
|
||||
|
||||
pub trait InnerHtmlAttribute<T, Rndr>
|
||||
where
|
||||
T: AsRef<str>,
|
||||
T: AsRef<str> + PartialEq,
|
||||
Rndr: DomRenderer,
|
||||
Self: Sized + AddAttribute<InnerHtml<T, Rndr>, Rndr>,
|
||||
Self: Sized + AddAnyAttr<Rndr>,
|
||||
{
|
||||
fn inner_html(
|
||||
self,
|
||||
value: T,
|
||||
) -> <Self as AddAttribute<InnerHtml<T, Rndr>, Rndr>>::Output {
|
||||
self.add_attr(inner_html(value))
|
||||
) -> <Self as AddAnyAttr<Rndr>>::Output<InnerHtml<T, Rndr>> {
|
||||
self.add_any_attr(inner_html(value))
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, E, At, Rndr> InnerHtmlAttribute<T, Rndr>
|
||||
for HtmlElement<E, At, (), Rndr>
|
||||
where
|
||||
Self: AddAttribute<InnerHtml<T, Rndr>, Rndr>,
|
||||
Self: AddAnyAttr<Rndr>,
|
||||
E: ElementWithChildren,
|
||||
At: Attribute<Rndr>,
|
||||
T: AsRef<str>,
|
||||
T: AsRef<str> + PartialEq,
|
||||
Rndr: DomRenderer,
|
||||
{
|
||||
fn inner_html(
|
||||
self,
|
||||
value: T,
|
||||
) -> <Self as AddAttribute<InnerHtml<T, Rndr>, Rndr>>::Output {
|
||||
self.add_attr(inner_html(value))
|
||||
) -> <Self as AddAnyAttr<Rndr>>::Output<InnerHtml<T, Rndr>> {
|
||||
self.add_any_attr(inner_html(value))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,8 +4,8 @@ use crate::{
|
|||
renderer::{CastFrom, Renderer},
|
||||
ssr::StreamBuilder,
|
||||
view::{
|
||||
AddAttribute, Mountable, Position, PositionState, Render, RenderHtml,
|
||||
ToTemplate,
|
||||
add_attr::AddAnyAttr, Mountable, Position, PositionState, Render,
|
||||
RenderHtml, ToTemplate,
|
||||
},
|
||||
};
|
||||
use const_str_slice_concat::{
|
||||
|
@ -17,17 +17,13 @@ use std::marker::PhantomData;
|
|||
mod custom;
|
||||
mod elements;
|
||||
mod inner_html;
|
||||
use super::attribute::NextAttribute;
|
||||
pub use custom::*;
|
||||
pub use elements::*;
|
||||
pub use inner_html::*;
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||
pub struct HtmlElement<E, At, Ch, Rndr>
|
||||
where
|
||||
At: Attribute<Rndr>,
|
||||
Ch: Render<Rndr>,
|
||||
Rndr: Renderer,
|
||||
{
|
||||
pub struct HtmlElement<E, At, Ch, Rndr> {
|
||||
pub(crate) tag: E,
|
||||
pub(crate) rndr: PhantomData<Rndr>,
|
||||
pub(crate) attributes: At,
|
||||
|
@ -37,9 +33,6 @@ where
|
|||
impl<E, At, Ch, Rndr> ElementType for HtmlElement<E, At, Ch, Rndr>
|
||||
where
|
||||
E: ElementType,
|
||||
At: Attribute<Rndr>,
|
||||
Ch: Render<Rndr>,
|
||||
Rndr: Renderer,
|
||||
{
|
||||
type Output = E::Output;
|
||||
|
||||
|
@ -52,12 +45,7 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<E, At, Ch, Rndr> HtmlElement<E, At, Ch, Rndr>
|
||||
where
|
||||
At: Attribute<Rndr>,
|
||||
Ch: Render<Rndr>,
|
||||
Rndr: Renderer,
|
||||
{
|
||||
impl<E, At, Ch, Rndr> HtmlElement<E, At, Ch, Rndr> {
|
||||
pub fn children(&self) -> &Ch {
|
||||
&self.children
|
||||
}
|
||||
|
@ -79,14 +67,13 @@ impl<E, At, Ch, NewChild, Rndr> ElementChild<Rndr, NewChild>
|
|||
for HtmlElement<E, At, Ch, Rndr>
|
||||
where
|
||||
E: ElementWithChildren,
|
||||
At: Attribute<Rndr>,
|
||||
Ch: Render<Rndr> + TupleBuilder<NewChild>,
|
||||
<Ch as TupleBuilder<NewChild>>::Output: Render<Rndr>,
|
||||
Ch: Render<Rndr> + TupleBuilder,
|
||||
<Ch as TupleBuilder>::Output<NewChild>: Render<Rndr>,
|
||||
Rndr: Renderer,
|
||||
NewChild: Render<Rndr>,
|
||||
{
|
||||
type Output =
|
||||
HtmlElement<E, At, <Ch as TupleBuilder<NewChild>>::Output, Rndr>;
|
||||
HtmlElement<E, At, <Ch as TupleBuilder>::Output<NewChild>, Rndr>;
|
||||
|
||||
fn child(self, child: NewChild) -> Self::Output {
|
||||
let HtmlElement {
|
||||
|
@ -104,19 +91,25 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<E, At, Ch, Rndr, NewAttr> AddAttribute<NewAttr, Rndr>
|
||||
for HtmlElement<E, At, Ch, Rndr>
|
||||
impl<E, At, Ch, Rndr> AddAnyAttr<Rndr> for HtmlElement<E, At, Ch, Rndr>
|
||||
where
|
||||
E: ElementType,
|
||||
At: Attribute<Rndr> + TupleBuilder<NewAttr>,
|
||||
<At as TupleBuilder<NewAttr>>::Output: Attribute<Rndr>,
|
||||
Ch: Render<Rndr>,
|
||||
E: ElementType + CreateElement<Rndr>,
|
||||
Ch: RenderHtml<Rndr>,
|
||||
Rndr: Renderer,
|
||||
At: Attribute<Rndr>,
|
||||
Rndr: Renderer,
|
||||
{
|
||||
type Output =
|
||||
HtmlElement<E, <At as TupleBuilder<NewAttr>>::Output, Ch, Rndr>;
|
||||
type Output<SomeNewAttr: Attribute<Rndr>> = HtmlElement<
|
||||
E,
|
||||
<At as NextAttribute<Rndr>>::Output<SomeNewAttr>,
|
||||
Ch,
|
||||
Rndr,
|
||||
>;
|
||||
|
||||
fn add_attr(self, attr: NewAttr) -> Self::Output {
|
||||
fn add_any_attr<NewAttr: Attribute<Rndr>>(
|
||||
self,
|
||||
attr: NewAttr,
|
||||
) -> Self::Output<NewAttr> {
|
||||
let HtmlElement {
|
||||
tag,
|
||||
attributes,
|
||||
|
@ -125,11 +118,18 @@ where
|
|||
} = self;
|
||||
HtmlElement {
|
||||
tag,
|
||||
attributes: attributes.next_tuple(attr),
|
||||
attributes: attributes.add_any_attr(attr),
|
||||
children,
|
||||
rndr,
|
||||
}
|
||||
}
|
||||
|
||||
fn add_any_attr_by_ref<NewAttr: Attribute<Rndr>>(
|
||||
self,
|
||||
attr: &NewAttr,
|
||||
) -> Self::Output<NewAttr> {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
pub trait ElementChild<Rndr, NewChild>
|
||||
|
|
|
@ -157,6 +157,20 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<R> NextAttribute<R> for On<R>
|
||||
where
|
||||
R: DomRenderer,
|
||||
{
|
||||
type Output<NewAttr: Attribute<R>> = (Self, NewAttr);
|
||||
|
||||
fn add_any_attr<NewAttr: Attribute<R>>(
|
||||
self,
|
||||
new_attr: NewAttr,
|
||||
) -> Self::Output<NewAttr> {
|
||||
(self, new_attr)
|
||||
}
|
||||
}
|
||||
|
||||
impl<R> ToTemplate for On<R>
|
||||
where
|
||||
R: DomRenderer,
|
||||
|
@ -441,6 +455,7 @@ generate_event_types! {
|
|||
}
|
||||
|
||||
// Export `web_sys` event types
|
||||
use super::attribute::NextAttribute;
|
||||
pub use web_sys::{
|
||||
AnimationEvent, BeforeUnloadEvent, CompositionEvent, CustomEvent,
|
||||
DeviceMotionEvent, DeviceOrientationEvent, DragEvent, ErrorEvent, Event,
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
use super::{attribute::Attribute, element::ElementType};
|
||||
use super::{
|
||||
attribute::{Attribute, NextAttribute},
|
||||
element::ElementType,
|
||||
};
|
||||
use crate::{
|
||||
html::element::HtmlElement, prelude::Render, renderer::Renderer,
|
||||
view::AddAttribute,
|
||||
view::add_attr::AddAnyAttr,
|
||||
};
|
||||
use std::marker::PhantomData;
|
||||
|
||||
|
@ -70,22 +73,40 @@ where
|
|||
fn rebuild(self, _state: &mut Self::State) {}
|
||||
}
|
||||
|
||||
impl<E, C, Rndr> NextAttribute<Rndr> for NodeRefAttr<E, C, Rndr>
|
||||
where
|
||||
E: ElementType,
|
||||
C: NodeRefContainer<E, Rndr>,
|
||||
Rndr: Renderer,
|
||||
Rndr::Element: PartialEq,
|
||||
{
|
||||
type Output<NewAttr: Attribute<Rndr>> = (Self, NewAttr);
|
||||
|
||||
fn add_any_attr<NewAttr: Attribute<Rndr>>(
|
||||
self,
|
||||
new_attr: NewAttr,
|
||||
) -> Self::Output<NewAttr> {
|
||||
(self, new_attr)
|
||||
}
|
||||
}
|
||||
|
||||
pub trait NodeRefAttribute<E, C, Rndr>
|
||||
where
|
||||
E: ElementType,
|
||||
C: NodeRefContainer<E, Rndr>,
|
||||
Rndr: Renderer,
|
||||
Rndr::Element: PartialEq,
|
||||
{
|
||||
fn node_ref(
|
||||
self,
|
||||
container: C,
|
||||
) -> <Self as AddAttribute<NodeRefAttr<E, C, Rndr>, Rndr>>::Output
|
||||
) -> <Self as AddAnyAttr<Rndr>>::Output<NodeRefAttr<E, C, Rndr>>
|
||||
where
|
||||
Self: Sized + AddAttribute<NodeRefAttr<E, C, Rndr>, Rndr>,
|
||||
<Self as AddAttribute<NodeRefAttr<E, C, Rndr>, Rndr>>::Output:
|
||||
Self: Sized + AddAnyAttr<Rndr>,
|
||||
<Self as AddAnyAttr<Rndr>>::Output<NodeRefAttr<E, C, Rndr>>:
|
||||
Render<Rndr>,
|
||||
{
|
||||
self.add_attr(node_ref(container))
|
||||
self.add_any_attr(node_ref(container))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -97,5 +118,6 @@ where
|
|||
Ch: Render<Rndr>,
|
||||
C: NodeRefContainer<E, Rndr>,
|
||||
Rndr: Renderer,
|
||||
Rndr::Element: PartialEq,
|
||||
{
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use super::attribute::Attribute;
|
||||
use super::attribute::{Attribute, NextAttribute};
|
||||
use crate::{
|
||||
renderer::DomRenderer,
|
||||
view::{Position, ToTemplate},
|
||||
|
@ -62,6 +62,22 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<K, P, R> NextAttribute<R> for Property<K, P, R>
|
||||
where
|
||||
K: AsRef<str>,
|
||||
P: IntoProperty<R>,
|
||||
R: DomRenderer,
|
||||
{
|
||||
type Output<NewAttr: Attribute<R>> = (Self, NewAttr);
|
||||
|
||||
fn add_any_attr<NewAttr: Attribute<R>>(
|
||||
self,
|
||||
new_attr: NewAttr,
|
||||
) -> Self::Output<NewAttr> {
|
||||
(self, new_attr)
|
||||
}
|
||||
}
|
||||
|
||||
impl<K, P, R> ToTemplate for Property<K, P, R>
|
||||
where
|
||||
K: AsRef<str>,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use super::attribute::Attribute;
|
||||
use super::attribute::{Attribute, NextAttribute};
|
||||
use crate::{
|
||||
renderer::DomRenderer,
|
||||
view::{Position, ToTemplate},
|
||||
|
@ -60,6 +60,21 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<S, R> NextAttribute<R> for Style<S, R>
|
||||
where
|
||||
S: IntoStyle<R>,
|
||||
R: DomRenderer,
|
||||
{
|
||||
type Output<NewAttr: Attribute<R>> = (Self, NewAttr);
|
||||
|
||||
fn add_any_attr<NewAttr: Attribute<R>>(
|
||||
self,
|
||||
new_attr: NewAttr,
|
||||
) -> Self::Output<NewAttr> {
|
||||
(self, new_attr)
|
||||
}
|
||||
}
|
||||
|
||||
impl<S, R> ToTemplate for Style<S, R>
|
||||
where
|
||||
S: IntoStyle<R>,
|
||||
|
|
|
@ -17,13 +17,13 @@ macro_rules! mathml_global {
|
|||
paste::paste! {
|
||||
pub fn $attr<V>(self, value: V) -> HtmlElement <
|
||||
[<$tag:camel>],
|
||||
<At as TupleBuilder<Attr<$crate::html::attribute::[<$attr:camel>], V, Rndr>>>::Output,
|
||||
<At as TupleBuilder>::Output<Attr<$crate::html::attribute::[<$attr:camel>], V, Rndr>>,
|
||||
Ch, Rndr
|
||||
>
|
||||
where
|
||||
V: AttributeValue<Rndr>,
|
||||
At: TupleBuilder<Attr<$crate::html::attribute::[<$attr:camel>], V, Rndr>>,
|
||||
<At as TupleBuilder<Attr<$crate::html::attribute::[<$attr:camel>], V, Rndr>>>::Output: Attribute<Rndr>,
|
||||
At: TupleBuilder,
|
||||
<At as TupleBuilder>::Output<Attr<$crate::html::attribute::[<$attr:camel>], V, Rndr>>: Attribute<Rndr>,
|
||||
{
|
||||
let HtmlElement { tag, rndr, children, attributes } = self;
|
||||
HtmlElement {
|
||||
|
@ -75,13 +75,13 @@ macro_rules! mathml_elements {
|
|||
$(
|
||||
pub fn $attr<V>(self, value: V) -> HtmlElement <
|
||||
[<$tag:camel>],
|
||||
<At as TupleBuilder<Attr<$crate::html::attribute::[<$attr:camel>], V, Rndr>>>::Output,
|
||||
<At as TupleBuilder>::Output<Attr<$crate::html::attribute::[<$attr:camel>], V, Rndr>>,
|
||||
Ch, Rndr
|
||||
>
|
||||
where
|
||||
V: AttributeValue<Rndr>,
|
||||
At: TupleBuilder<Attr<$crate::html::attribute::[<$attr:camel>], V, Rndr>>,
|
||||
<At as TupleBuilder<Attr<$crate::html::attribute::[<$attr:camel>], V, Rndr>>>::Output: Attribute<Rndr>,
|
||||
At: TupleBuilder,
|
||||
<At as TupleBuilder>::Output<Attr<$crate::html::attribute::[<$attr:camel>], V, Rndr>>: Attribute<Rndr>,
|
||||
{
|
||||
let HtmlElement { tag, rndr, children, attributes } = self;
|
||||
HtmlElement {
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
use super::RenderHtml;
|
||||
use crate::{html::attribute::Attribute, renderer::Renderer};
|
||||
|
||||
/// Allows adding a new attribute to some type, before it is rendered.
|
||||
/// This takes place at compile time as part of the builder syntax for creating a statically typed
|
||||
/// view tree.
|
||||
///
|
||||
/// Normally, this is used to add an attribute to an HTML element. But it is required to be
|
||||
/// implemented for all types that implement [`RenderHtml`], so that attributes can be spread onto
|
||||
/// other structures like the return type of a component.
|
||||
pub trait AddAnyAttr<Rndr>
|
||||
where
|
||||
Rndr: Renderer,
|
||||
{
|
||||
type Output<SomeNewAttr: Attribute<Rndr>>: RenderHtml<Rndr>;
|
||||
|
||||
fn add_any_attr<NewAttr: Attribute<Rndr>>(
|
||||
self,
|
||||
attr: NewAttr,
|
||||
) -> Self::Output<NewAttr>
|
||||
where
|
||||
Self::Output<NewAttr>: RenderHtml<Rndr>;
|
||||
|
||||
fn add_any_attr_by_ref<NewAttr: Attribute<Rndr>>(
|
||||
self,
|
||||
attr: &NewAttr,
|
||||
) -> Self::Output<NewAttr>
|
||||
where
|
||||
Self::Output<NewAttr>: RenderHtml<Rndr>;
|
||||
}
|
|
@ -2,6 +2,7 @@ use crate::{hydration::Cursor, renderer::Renderer, ssr::StreamBuilder};
|
|||
use parking_lot::RwLock;
|
||||
use std::sync::Arc;
|
||||
|
||||
pub mod add_attr;
|
||||
pub mod any_view;
|
||||
pub mod either;
|
||||
pub mod error_boundary;
|
||||
|
@ -51,32 +52,6 @@ impl core::fmt::Display for NeverError {
|
|||
|
||||
impl std::error::Error for NeverError {}
|
||||
|
||||
/// The `AddAttr` trait allows adding a new attribute to some type, before it is rendered.
|
||||
/// This takes place at compile time as part of the builder syntax for creating a statically typed
|
||||
/// view tree.
|
||||
///
|
||||
/// Normally, this is used to add an attribute to an HTML element. But it is required to be
|
||||
/// implemented for all types that implement [`RenderHtml`], so that attributes can be spread onto
|
||||
/// other structures like the return type of a component.
|
||||
pub trait AddAttribute<NewAttr, Rndr>: Sized
|
||||
where
|
||||
Rndr: Renderer,
|
||||
{
|
||||
/// The type of the modified view after the attribute has been added.
|
||||
type Output;
|
||||
|
||||
/// Adds an owned attribute to the view.
|
||||
fn add_attr(self, attr: NewAttr) -> Self::Output;
|
||||
|
||||
/// Adds the attribute to the view by reference.
|
||||
fn add_attr_by_ref(self, attr: &NewAttr) -> Self::Output
|
||||
where
|
||||
NewAttr: Sized + Clone,
|
||||
{
|
||||
self.add_attr(attr.clone())
|
||||
}
|
||||
}
|
||||
|
||||
/// The `RenderHtml` trait allows rendering something to HTML, and transforming
|
||||
/// that HTML into an interactive interface.
|
||||
///
|
||||
|
|
|
@ -4,7 +4,7 @@ use super::{
|
|||
};
|
||||
use crate::{
|
||||
html::{
|
||||
attribute::{Attribute, AttributeKey, AttributeValue},
|
||||
attribute::{Attribute, AttributeKey, AttributeValue, NextAttribute},
|
||||
class::IntoClass,
|
||||
style::IntoStyle,
|
||||
},
|
||||
|
@ -92,6 +92,21 @@ where
|
|||
fn rebuild(self, _state: &mut Self::State) {}
|
||||
}
|
||||
|
||||
impl<K, const V: &'static str, R> NextAttribute<R> for StaticAttr<K, V>
|
||||
where
|
||||
K: AttributeKey,
|
||||
R: Renderer,
|
||||
{
|
||||
type Output<NewAttr: Attribute<R>> = (Self, NewAttr);
|
||||
|
||||
fn add_any_attr<NewAttr: Attribute<R>>(
|
||||
self,
|
||||
new_attr: NewAttr,
|
||||
) -> Self::Output<NewAttr> {
|
||||
(StaticAttr::<K, V> { ty: PhantomData }, new_attr)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Static<const V: &'static str>;
|
||||
|
||||
|
|
|
@ -3,8 +3,9 @@ use super::{
|
|||
ToTemplate,
|
||||
};
|
||||
use crate::{
|
||||
html::attribute::Attribute,
|
||||
hydration::Cursor,
|
||||
view::{AddAttribute, StreamBuilder},
|
||||
view::{add_attr::AddAnyAttr, StreamBuilder},
|
||||
};
|
||||
use const_str_slice_concat::{
|
||||
const_concat, const_concat_with_separator, str_from_buffer,
|
||||
|
@ -46,6 +47,31 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<Rndr> AddAnyAttr<Rndr> for ()
|
||||
where
|
||||
Rndr: Renderer,
|
||||
{
|
||||
type Output<SomeNewAttr: Attribute<Rndr>> = ();
|
||||
|
||||
fn add_any_attr<NewAttr: Attribute<Rndr>>(
|
||||
self,
|
||||
attr: NewAttr,
|
||||
) -> Self::Output<NewAttr>
|
||||
where
|
||||
Self::Output<NewAttr>: RenderHtml<Rndr>,
|
||||
{
|
||||
}
|
||||
|
||||
fn add_any_attr_by_ref<NewAttr: Attribute<Rndr>>(
|
||||
self,
|
||||
attr: &NewAttr,
|
||||
) -> Self::Output<NewAttr>
|
||||
where
|
||||
Self::Output<NewAttr>: RenderHtml<Rndr>,
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
impl<R: Renderer> Mountable<R> for () {
|
||||
fn unmount(&mut self) {}
|
||||
|
||||
|
@ -143,6 +169,34 @@ impl<A: ToTemplate> ToTemplate for (A,) {
|
|||
}
|
||||
}
|
||||
|
||||
impl<A, Rndr> AddAnyAttr<Rndr> for (A,)
|
||||
where
|
||||
A: AddAnyAttr<Rndr>,
|
||||
Rndr: Renderer,
|
||||
{
|
||||
type Output<SomeNewAttr: Attribute<Rndr>> = (A::Output<SomeNewAttr>,);
|
||||
|
||||
fn add_any_attr<NewAttr: Attribute<Rndr>>(
|
||||
self,
|
||||
attr: NewAttr,
|
||||
) -> Self::Output<NewAttr>
|
||||
where
|
||||
Self::Output<NewAttr>: RenderHtml<Rndr>,
|
||||
{
|
||||
(self.0.add_any_attr(attr),)
|
||||
}
|
||||
|
||||
fn add_any_attr_by_ref<NewAttr: Attribute<Rndr>>(
|
||||
self,
|
||||
attr: &NewAttr,
|
||||
) -> Self::Output<NewAttr>
|
||||
where
|
||||
Self::Output<NewAttr>: RenderHtml<Rndr>,
|
||||
{
|
||||
(self.0.add_any_attr_by_ref(attr),)
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! impl_view_for_tuples {
|
||||
($first:ident, $($ty:ident),* $(,)?) => {
|
||||
impl<$first, $($ty),*, Rndr> Render<Rndr> for ($first, $($ty,)*)
|
||||
|
@ -295,25 +349,36 @@ macro_rules! impl_view_for_tuples {
|
|||
}
|
||||
}
|
||||
|
||||
impl<NewAttr, $first, $($ty),*, Rndr> AddAttribute<NewAttr, Rndr> for ($first, $($ty,)*)
|
||||
where
|
||||
$first: AddAttribute<NewAttr, Rndr>,
|
||||
$($ty: AddAttribute<NewAttr, Rndr>),*,
|
||||
NewAttr: Sized + Clone,
|
||||
Rndr: Renderer
|
||||
impl<$first, $($ty,)* Rndr> AddAnyAttr<Rndr> for ($first, $($ty,)*)
|
||||
where
|
||||
$first: AddAnyAttr<Rndr>,
|
||||
$($ty: AddAnyAttr<Rndr>),*,
|
||||
Rndr: Renderer,
|
||||
{
|
||||
type Output = (<$first as AddAttribute<NewAttr, Rndr>>::Output, $(<$ty as AddAttribute<NewAttr, Rndr>>::Output,)*);
|
||||
type Output<SomeNewAttr: Attribute<Rndr>> = ($first::Output<SomeNewAttr>, $($ty::Output<SomeNewAttr>,)*);
|
||||
|
||||
fn add_attr(self, attr: NewAttr) -> Self::Output {
|
||||
self.add_attr_by_ref(&attr)
|
||||
fn add_any_attr<NewAttr: Attribute<Rndr>>(
|
||||
self,
|
||||
attr: NewAttr,
|
||||
) -> Self::Output<NewAttr>
|
||||
where
|
||||
Self::Output<NewAttr>: RenderHtml<Rndr>,
|
||||
{
|
||||
self.add_any_attr_by_ref(&attr)
|
||||
}
|
||||
|
||||
fn add_attr_by_ref(self, attr: &NewAttr) -> Self::Output where NewAttr: Sized + Clone {
|
||||
fn add_any_attr_by_ref<NewAttr: Attribute<Rndr>>(
|
||||
self,
|
||||
attr: &NewAttr,
|
||||
) -> Self::Output<NewAttr>
|
||||
where
|
||||
Self::Output<NewAttr>: RenderHtml<Rndr>,
|
||||
{
|
||||
#[allow(non_snake_case)]
|
||||
let ($first, $($ty,)*) = self;
|
||||
(
|
||||
$first.add_attr_by_ref(attr),
|
||||
$($ty.add_attr_by_ref(attr)),*
|
||||
$first.add_any_attr_by_ref(&attr),
|
||||
$($ty.add_any_attr_by_ref(&attr)),*
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue