Skip to content

Commit 70ae9f6

Browse files
committed
wip: redesign event listener
1 parent 9cf82b5 commit 70ae9f6

File tree

8 files changed

+575
-346
lines changed

8 files changed

+575
-346
lines changed
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
use std::{marker::PhantomData, pin::Pin};
2+
3+
use frender_common::convert::FromMut;
4+
use frender_dom::{event_types::EventType, HandleEvent, MaybeHandleEvent};
5+
6+
use crate::{
7+
update_element::{OnEventType, PinnedNonReactiveRenderStateKind, PinnedRenderWithBehavior, UnpinnedNonReactiveRenderStateKind, UnpinnedRenderWithBehavior},
8+
RenderHtml,
9+
};
10+
11+
pub type UnpinnedEventListenerOf<EVT, E, R, F> = <E as ::frender_dom::OnEvent<R, EVT>>::EventListenerUnpinned<F>;
12+
pub type PinnedEventListenerOf<EVT, E, R, F> = <E as ::frender_dom::OnEvent<R, EVT>>::EventListener<F>;
13+
14+
enum Never {}
15+
pub struct Kind<EVT, ET, H>(Never, PhantomData<(EVT, ET, H)>);
16+
17+
impl<EVT: EventType, ET: OnEventType<EVT>, H: HandleEvent<EVT::Event> + 'static> UnpinnedNonReactiveRenderStateKind for Kind<EVT, ET, H> {
18+
type UnpinnedNonReactiveState<R: ?Sized + crate::RenderHtml> = UnpinnedEventListenerOf<EVT, ET::OnEvent<R>, R, H>;
19+
}
20+
21+
impl<EVT: EventType, ET: OnEventType<EVT>, F: HandleEvent<EVT::Event> + 'static> PinnedNonReactiveRenderStateKind for Kind<EVT, ET, F> {
22+
type PinnedNonReactiveState<R: ?Sized + crate::RenderHtml> = PinnedEventListenerOf<EVT, ET::OnEvent<R>, R, F>;
23+
}
24+
25+
pub struct Property<EVT, F> {
26+
_event_type: PhantomData<EVT>,
27+
f: F,
28+
}
29+
30+
impl<EVT, F> Property<EVT, F> {
31+
pub(crate) fn new(f: F) -> Self {
32+
Self { _event_type: PhantomData, f }
33+
}
34+
}
35+
36+
impl<
37+
//
38+
EVT: EventType,
39+
H: HandleEvent<EVT::Event> + 'static,
40+
F: MaybeHandleEvent<EVT::Event, HandleEvent = H> + 'static,
41+
BT: OnEventType<EVT>,
42+
> PinnedRenderWithBehavior<BT> for Property<EVT, F>
43+
{
44+
type PinnedRenderStateKind = Kind<EVT, BT, H>;
45+
46+
fn pinned_render_init_with_behavior<R: ?Sized + RenderHtml>(
47+
//
48+
this: Self,
49+
renderer: &mut R,
50+
b: &mut BT::OfBehaviorType<R>,
51+
state: ::core::pin::Pin<&mut <Self::PinnedRenderStateKind as crate::update_element::PinnedNonReactiveRenderStateKind>::PinnedNonReactiveState<R>>,
52+
) {
53+
<Self as PinnedRenderWithBehavior<BT>>::pinned_render_update_with_behavior(this, renderer, b, state)
54+
}
55+
56+
fn pinned_render_update_with_behavior<R: ?Sized + RenderHtml>(
57+
//
58+
this: Self,
59+
renderer: &mut R,
60+
b: &mut BT::OfBehaviorType<R>,
61+
mut state: ::core::pin::Pin<&mut <Self::PinnedRenderStateKind as crate::update_element::PinnedNonReactiveRenderStateKind>::PinnedNonReactiveState<R>>,
62+
) {
63+
let element = <BT::OnEvent<R>>::from_mut(b);
64+
65+
if let Some(this) = this.f.into() {
66+
frender_dom::RegisterOrUpdate::register_or_update(state, element, renderer, this)
67+
} else {
68+
state.set(Default::default())
69+
}
70+
}
71+
}
72+
73+
impl<
74+
//
75+
EVT: EventType,
76+
H: HandleEvent<EVT::Event> + 'static,
77+
F: MaybeHandleEvent<EVT::Event, HandleEvent = H> + 'static,
78+
BT: OnEventType<EVT>,
79+
> UnpinnedRenderWithBehavior<BT> for Property<EVT, F>
80+
{
81+
type UnpinnedRenderStateKind = Kind<EVT, BT, H>;
82+
83+
fn unpinned_render_init_with_behavior<R: ?Sized + RenderHtml>(
84+
//
85+
this: Self,
86+
renderer: &mut R,
87+
b: &mut <BT as crate::BehaviorType>::OfBehaviorType<R>,
88+
) -> <Self::UnpinnedRenderStateKind as UnpinnedNonReactiveRenderStateKind>::UnpinnedNonReactiveState<R> {
89+
// TODO: refactor without default
90+
let mut state = Default::default();
91+
<Self as UnpinnedRenderWithBehavior<BT>>::unpinned_render_update_with_behavior(this, renderer, b, &mut state);
92+
state
93+
}
94+
95+
fn unpinned_render_update_with_behavior<R: ?Sized + RenderHtml>(
96+
//
97+
this: Self,
98+
renderer: &mut R,
99+
b: &mut <BT as crate::BehaviorType>::OfBehaviorType<R>,
100+
state: &mut <Self::UnpinnedRenderStateKind as UnpinnedNonReactiveRenderStateKind>::UnpinnedNonReactiveState<R>,
101+
) {
102+
let element = <BT::OnEvent<R>>::from_mut(b);
103+
let mut state = Pin::new(state);
104+
105+
if let Some(this) = this.f.into() {
106+
frender_dom::RegisterOrUpdate::register_or_update(state, element, renderer, this)
107+
} else {
108+
state.set(Default::default())
109+
}
110+
}
111+
}

packages/frender-html/src/html.rs

Lines changed: 4 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ use frender_dom::{
33
render::{Render, RenderTextFromKnown, RenderWithContext},
44
special::textarea::TextAreaValue,
55
ui_handle::UiHandle,
6-
OnEvent,
76
};
87

98
use crate::impl_bounds::{DomTokens, Style};
@@ -31,6 +30,8 @@ crate::macros::def_intrinsic_component_props!(
3130
#[cfg(feature = "web")]
3231
use crate::shims::prelude::*;
3332

33+
use frender_dom::OnEvent;
34+
3435
use super::*;
3536
}
3637

@@ -43,9 +44,6 @@ crate::macros::def_intrinsic_component_props!(
4344
#[event_types]
4445
pub mod event_types {}
4546

46-
#[event_type_helpers]
47-
mod event_type_helpers {}
48-
4947
#[tag_and_props_markers]
5048
#[cfg(feature = "components")]
5149
#[cfg(feature = "macros_not_expanded")]
@@ -108,43 +106,9 @@ crate::macros::def_intrinsic_component_props!(
108106
pub trait Element {
109107
trait_bounds!(
110108
frender_dom::behaviors::Element<Renderer>
109+
//
111110
+ frender_dom::behaviors::ElementWithChildren<Renderer>
112111
+ frender_dom::behaviors::ElementWithClassList<Renderer>
113-
+ OnEvent<Renderer, event_types::on_cancel>
114-
+ OnEvent<Renderer, event_types::on_error>
115-
+ OnEvent<Renderer, event_types::on_scroll>
116-
+ OnEvent<Renderer, event_types::on_security_policy_violation>
117-
+ OnEvent<Renderer, event_types::on_select>
118-
+ OnEvent<Renderer, event_types::on_wheel>
119-
+ OnEvent<Renderer, event_types::on_copy>
120-
+ OnEvent<Renderer, event_types::on_cut>
121-
+ OnEvent<Renderer, event_types::on_paste>
122-
+ OnEvent<Renderer, event_types::on_composition_end>
123-
+ OnEvent<Renderer, event_types::on_composition_start>
124-
+ OnEvent<Renderer, event_types::on_composition_update>
125-
+ OnEvent<Renderer, event_types::on_blur>
126-
+ OnEvent<Renderer, event_types::on_focus>
127-
+ OnEvent<Renderer, event_types::on_focus_in>
128-
+ OnEvent<Renderer, event_types::on_focus_out>
129-
+ OnEvent<Renderer, event_types::on_fullscreen_change>
130-
+ OnEvent<Renderer, event_types::on_fullscreen_error>
131-
+ OnEvent<Renderer, event_types::on_key_down>
132-
+ OnEvent<Renderer, event_types::on_key_up>
133-
+ OnEvent<Renderer, event_types::on_aux_click>
134-
+ OnEvent<Renderer, event_types::on_click>
135-
+ OnEvent<Renderer, event_types::on_context_menu>
136-
+ OnEvent<Renderer, event_types::on_double_click>
137-
+ OnEvent<Renderer, event_types::on_mouse_down>
138-
+ OnEvent<Renderer, event_types::on_mouse_enter>
139-
+ OnEvent<Renderer, event_types::on_mouse_leave>
140-
+ OnEvent<Renderer, event_types::on_mouse_move>
141-
+ OnEvent<Renderer, event_types::on_mouse_out>
142-
+ OnEvent<Renderer, event_types::on_mouse_over>
143-
+ OnEvent<Renderer, event_types::on_mouse_up>
144-
+ OnEvent<Renderer, event_types::on_touch_cancel>
145-
+ OnEvent<Renderer, event_types::on_touch_end>
146-
+ OnEvent<Renderer, event_types::on_touch_move>
147-
+ OnEvent<Renderer, event_types::on_touch_start>
148112
);
149113

150114
impl_for_web!();
@@ -746,36 +710,8 @@ crate::macros::def_intrinsic_component_props!(
746710
pub trait HtmlElement {
747711
trait_bounds!(
748712
frender_dom::behaviors::HtmlElement<Renderer>
713+
//
749714
+ frender_dom::behaviors::ElementWithStyle<Renderer>
750-
+ OnEvent<Renderer, event_types::on_invalid>
751-
+ OnEvent<Renderer, event_types::on_animation_cancel>
752-
+ OnEvent<Renderer, event_types::on_animation_end>
753-
+ OnEvent<Renderer, event_types::on_animation_iteration>
754-
+ OnEvent<Renderer, event_types::on_animation_start>
755-
+ OnEvent<Renderer, event_types::on_before_input>
756-
+ OnEvent<Renderer, event_types::on_input>
757-
+ OnEvent<Renderer, event_types::on_change>
758-
+ OnEvent<Renderer, event_types::on_got_pointer_capture>
759-
+ OnEvent<Renderer, event_types::on_lost_pointer_capture>
760-
+ OnEvent<Renderer, event_types::on_pointer_cancel>
761-
+ OnEvent<Renderer, event_types::on_pointer_down>
762-
+ OnEvent<Renderer, event_types::on_pointer_enter>
763-
+ OnEvent<Renderer, event_types::on_pointer_leave>
764-
+ OnEvent<Renderer, event_types::on_pointer_move>
765-
+ OnEvent<Renderer, event_types::on_pointer_out>
766-
+ OnEvent<Renderer, event_types::on_pointer_over>
767-
+ OnEvent<Renderer, event_types::on_pointer_up>
768-
+ OnEvent<Renderer, event_types::on_transition_cancel>
769-
+ OnEvent<Renderer, event_types::on_transition_end>
770-
+ OnEvent<Renderer, event_types::on_transition_run>
771-
+ OnEvent<Renderer, event_types::on_transition_start>
772-
+ OnEvent<Renderer, event_types::on_drag>
773-
+ OnEvent<Renderer, event_types::on_drag_end>
774-
+ OnEvent<Renderer, event_types::on_drag_enter>
775-
+ OnEvent<Renderer, event_types::on_drag_leave>
776-
+ OnEvent<Renderer, event_types::on_drag_over>
777-
+ OnEvent<Renderer, event_types::on_drag_start>
778-
+ OnEvent<Renderer, event_types::on_drop>
779715
);
780716

781717
define!(
@@ -1137,31 +1073,6 @@ crate::macros::def_intrinsic_component_props!(
11371073
pub trait HtmlMediaElement {
11381074
special_super_traits!(ElementWithSrcAttribute, ElementWithCrossOriginAttribute);
11391075

1140-
trait_bounds!(
1141-
OnEvent<Renderer, event_types::on_abort>
1142-
+ OnEvent<Renderer, event_types::on_can_play>
1143-
+ OnEvent<Renderer, event_types::on_can_play_through>
1144-
+ OnEvent<Renderer, event_types::on_duration_change>
1145-
+ OnEvent<Renderer, event_types::on_emptied>
1146-
+ OnEvent<Renderer, event_types::on_ended>
1147-
+ OnEvent<Renderer, event_types::on_loaded_data>
1148-
+ OnEvent<Renderer, event_types::on_loaded_metadata>
1149-
+ OnEvent<Renderer, event_types::on_load_start>
1150-
+ OnEvent<Renderer, event_types::on_pause>
1151-
+ OnEvent<Renderer, event_types::on_play>
1152-
+ OnEvent<Renderer, event_types::on_playing>
1153-
+ OnEvent<Renderer, event_types::on_progress>
1154-
+ OnEvent<Renderer, event_types::on_rate_change>
1155-
+ OnEvent<Renderer, event_types::on_resize>
1156-
+ OnEvent<Renderer, event_types::on_seeked>
1157-
+ OnEvent<Renderer, event_types::on_seeking>
1158-
+ OnEvent<Renderer, event_types::on_stalled>
1159-
+ OnEvent<Renderer, event_types::on_suspend>
1160-
+ OnEvent<Renderer, event_types::on_time_update>
1161-
+ OnEvent<Renderer, event_types::on_volume_change>
1162-
+ OnEvent<Renderer, event_types::on_waiting>
1163-
);
1164-
11651076
impl_for_web!();
11661077

11671078
fn auto_play(value: attr_value![bool]) {
@@ -1399,11 +1310,6 @@ crate::macros::def_intrinsic_component_props!(
13991310
ElementWithRelAttribute,
14001311
ElementWithNameAttribute,
14011312
);
1402-
trait_bounds!(
1403-
OnEvent<Renderer, event_types::on_form_data>
1404-
+ OnEvent<Renderer, event_types::on_reset>
1405-
+ OnEvent<Renderer, event_types::on_submit>
1406-
);
14071313
define!(tags = (form,));
14081314
impl_for_web!();
14091315
// TODO: mark HtmlFormElement.accept as deprecated

packages/frender-html/src/impl_bounds.rs

Lines changed: 13 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ macro_rules! default_impl_csr {
101101
}
102102
$csr:ident !{ $($csr_fields:tt)* }
103103
) => {
104+
#[cfg(todo)]
104105
impl<
105106
V: $($bounds)*::Bounds::<$($bounds_tp,)*>,
106107
ET: $crate::html::behavior_type_traits::$csr_element_ty,
@@ -229,6 +230,7 @@ pub(crate) mod DomTokens {
229230
}
230231
$csr:ident !{ $($csr_fields:tt)* }
231232
) => {
233+
#[cfg(todo)]
232234
impl<
233235
V: $($bounds)*::Bounds::<$($bounds_tp,)*>,
234236
ET: $crate::html::behavior_type_traits::$csr_element_ty,
@@ -425,7 +427,7 @@ pub(crate) mod MaybeHandleEvent {
425427
meta! {
426428
wrapper! {$($wrapper:tt)*}
427429
prop_marker! {$($prop_marker:tt)*}
428-
bounds_attrs! { #[event($($bounds_tp:tt)*)] }
430+
bounds_attrs! { #[event($event_name:ident::$event_trait_name:ident)] }
429431
bounds! {$($bounds:tt)*}
430432
bounds_tps! {}
431433
csr_element_ty! { $csr_element_ty:ident }
@@ -434,82 +436,14 @@ pub(crate) mod MaybeHandleEvent {
434436
$csr:ident !{ $($csr_fields:tt)* }
435437
) => {
436438
impl<
437-
H: frender_dom::HandleEvent<dyn $($bounds_tp)* ::Event> + 'static,
438-
V: frender_dom::MaybeHandleEvent<dyn $($bounds_tp)* ::Event, HandleEvent = H> + 'static,
439-
ET: $crate::html::behavior_type_traits::$csr_element_ty,
440-
>
441-
$crate::UpdateNodeNonReactive<
442-
ET
443-
>
444-
for $($wrapper)*::<V> {
445-
type State<Renderer: $crate::RenderHtml + ?::core::marker::Sized> =
446-
$($bounds_tp)*::UnpinnedEventListenerOf<
447-
ET::$csr_element_ty<Renderer>,
448-
Renderer,
449-
H,
450-
>;
451-
452-
fn update_node_non_reactive<Renderer: $crate::RenderHtml + ?::core::marker::Sized>(
453-
Self(this): Self,
454-
renderer: &mut Renderer,
455-
element: &mut ET::OfBehaviorType<Renderer>,
456-
state: &mut Self::State<Renderer>,
457-
) {
458-
#[allow(unused_imports)]
459-
use $crate::html::behaviors_prelude::$csr_element_ty::*;
460-
461-
let element = <<ET as $crate::html::behavior_type_traits::$csr_element_ty>::$csr_element_ty::<Renderer> as frender_common::convert::FromMut<_>>::from_mut(element);
462-
463-
if let Some(this) = this.into() {
464-
frender_dom::RegisterOrUpdate::register_or_update(
465-
std::pin::Pin::new(state),
466-
element,
467-
renderer,
468-
this,
469-
)
470-
} else {
471-
*state = Default::default()
472-
}
473-
}
474-
}
475-
476-
impl<
477-
H: frender_dom::HandleEvent<dyn $($bounds_tp)* ::Event> + 'static,
478-
V: frender_dom::MaybeHandleEvent<dyn $($bounds_tp)* ::Event, HandleEvent = H> + 'static,
479-
ET: $crate::html::behavior_type_traits::$csr_element_ty,
480-
>
481-
$crate::UpdateNodeNonReactivePinned<
482-
ET
483-
>
484-
for $($wrapper)*::<V> {
485-
type StatePinned<Renderer: $crate::RenderHtml + ?::core::marker::Sized> =
486-
$($bounds_tp)*::EventListenerOf<
487-
ET::$csr_element_ty<Renderer>,
488-
Renderer,
489-
H,
490-
>;
491-
492-
fn update_node_non_reactive_pinned<Renderer: $crate::RenderHtml + ?::core::marker::Sized>(
493-
Self(this): Self,
494-
renderer: &mut Renderer,
495-
element: &mut ET::OfBehaviorType<Renderer>,
496-
mut state: std::pin::Pin<&mut Self::StatePinned<Renderer>>,
497-
) {
498-
#[allow(unused_imports)]
499-
use $crate::html::behaviors_prelude::$csr_element_ty::*;
500-
501-
let element = <<ET as $crate::html::behavior_type_traits::$csr_element_ty>::$csr_element_ty::<Renderer> as frender_common::convert::FromMut<_>>::from_mut(element);
502-
503-
if let Some(this) = this.into() {
504-
frender_dom::RegisterOrUpdate::register_or_update(
505-
state,
506-
element,
507-
renderer,
508-
this,
509-
)
510-
} else {
511-
state.set(Default::default())
512-
}
439+
H: frender_dom::HandleEvent<dyn crate::dom::event::$event_trait_name> + 'static,
440+
F: frender_dom::MaybeHandleEvent<dyn crate::dom::event::$event_trait_name, HandleEvent = H> + 'static,
441+
> crate::update_element::IntoProperty
442+
for $($wrapper)*::<F>
443+
{
444+
type IntoProperty = crate::event_listener::Property<crate::html::event_types::$event_name, F>;
445+
fn into_property(Self(this): Self) -> Self::IntoProperty {
446+
crate::event_listener::Property::new(this)
513447
}
514448
}
515449
};
@@ -530,6 +464,7 @@ pub(crate) mod MaybeHandleEvent {
530464
}
531465
$ssr:ident !{ $($ssr_fields:tt)* }
532466
) => {
467+
#[cfg(todo)]
533468
impl<
534469
V: frender_dom::MaybeHandleEvent<dyn $($bounds_tp)* ::Event> + 'static,
535470
> $crate::dom::component::IntoSpaceAndHtmlAttributesOrEmpty
@@ -561,6 +496,7 @@ pub(crate) mod SetRef {
561496
}
562497
$csr:ident !{ $($csr_fields:tt)* }
563498
) => {
499+
#[cfg(todo)]
564500
impl<
565501
V: FnOnce($(&$bounds_tps),*),
566502
ET: $crate::html::behavior_type_traits::$csr_element_ty,

0 commit comments

Comments
 (0)