From 04e3d5b3c250ca3207f79af8a19eca8233940da6 Mon Sep 17 00:00:00 2001 From: Manuel Cillero Date: Mon, 23 Mar 2026 15:52:06 +0100 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20Completa=20la=20API=20de=20temas=20?= =?UTF-8?q?con=20setup=5Fcomponent!?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Elimina `action::theme` fusionando sus responsabilidades en `action::component`. Renombra `AlterMarkup` a `TransformMarkup` y `FnActionAlterMarkup` a `FnActionTransformMarkup`. Simplifica `ActionKey` y mueve los tipos de función al módulo de componente. --- src/base/action.rs | 26 ------ src/base/action/component.rs | 27 +++++- .../component/after_render_component.rs | 16 +--- .../component/before_render_component.rs | 16 +--- ...onent.rs => transform_markup_component.rs} | 41 ++++------ src/base/action/page/after_render_body.rs | 4 +- src/base/action/page/before_render_body.rs | 4 +- src/base/action/theme.rs | 7 -- .../action/theme/after_render_component.rs | 50 ----------- .../action/theme/before_render_component.rs | 50 ----------- src/core/action.rs | 37 +++------ src/core/action/all.rs | 2 - src/core/action/definition.rs | 11 +-- src/core/component/definition.rs | 40 ++++----- src/core/extension/definition.rs | 6 +- src/core/theme.rs | 82 +++++++++++++++++-- src/core/theme/definition.rs | 34 +++++--- src/prelude.rs | 4 +- 18 files changed, 178 insertions(+), 279 deletions(-) rename src/base/action/component/{alter_markup_component.rs => transform_markup_component.rs} (63%) delete mode 100644 src/base/action/theme.rs delete mode 100644 src/base/action/theme/after_render_component.rs delete mode 100644 src/base/action/theme/before_render_component.rs diff --git a/src/base/action.rs b/src/base/action.rs index c4f5d27a..1e4debca 100644 --- a/src/base/action.rs +++ b/src/base/action.rs @@ -1,31 +1,5 @@ //! Acciones predefinidas para alterar el funcionamiento interno de PageTop. -use crate::prelude::*; - -/// Tipo de función para manipular componentes y su contexto de renderizado. -/// -/// Se usa en acciones definidas en [`action::component`] y [`action::theme`] para alterar el -/// comportamiento de los componentes. -/// -/// Recibe referencias mutables (`&mut`) del componente `component` y del contexto `cx`. -pub type FnActionWithComponent = fn(component: &mut C, cx: &mut Context); - -/// Tipo de función para modificar el [`Markup`] generado por un componente. -/// -/// Se usa en [`action::component::AlterMarkup`] para permitir a las extensiones modificar el HTML -/// final producido por el renderizado de un componente. La edición trabaja a nivel de texto: el -/// [`Markup`] recibido expone su contenido como [`String`], lo que permite aplicar búsquedas, -/// sustituciones, concatenaciones y cualquier otra primitiva de trabajo con cadenas. -/// -/// La función recibe referencias mutables del componente `component` y del contexto `cx`, y toma -/// posesión del `markup` producido hasta ese momento. Devuelve el nuevo [`Markup`] modificado, que -/// se encadena como entrada para la siguiente acción registrada, si la hay. -pub type FnActionAlterMarkup = fn(component: &mut C, cx: &mut Context, markup: Markup) -> Markup; - -// **< Acciones por tipo >************************************************************************** - pub mod component; -pub mod theme; - pub mod page; diff --git a/src/base/action/component.rs b/src/base/action/component.rs index 924f4075..b25dd3b1 100644 --- a/src/base/action/component.rs +++ b/src/base/action/component.rs @@ -1,10 +1,33 @@ //! Acciones que operan sobre componentes. +use pagetop::prelude::*; + +/// Tipo de función para manipular componentes y su contexto de renderizado. +/// +/// Se usa en [`action::component::BeforeRender`] y [`action::component::AfterRender`] para alterar +/// el comportamiento predefinido de los componentes. +/// +/// Recibe referencias mutables (`&mut`) del componente `component` y del contexto `cx`. +pub type FnActionWithComponent = fn(component: &mut C, cx: &mut Context); + +/// Tipo de función para alterar el [`Markup`] generado por un componente. +/// +/// Se usa en [`action::component::TransformMarkup`] para permitir a las extensiones alterar el HTML +/// final producido por el renderizado de un componente. La edición trabaja a nivel de texto: el +/// [`Markup`] recibido expone su contenido como [`String`], lo que permite aplicar búsquedas, +/// sustituciones, concatenaciones y cualquier otra primitiva de trabajo con cadenas. +/// +/// La función recibe una referencia inmutable al componente `component` (el renderizado ya ha +/// concluido, solo se necesita leer su estado), una referencia mutable al contexto `cx`, y toma +/// posesión del `markup` producido hasta ese momento. Devuelve el nuevo [`Markup`] transformado, +/// que se encadena como entrada para la siguiente acción registrada, si la hay. +pub type FnActionTransformMarkup = fn(component: &C, cx: &mut Context, markup: Markup) -> Markup; + mod before_render_component; pub use before_render_component::*; mod after_render_component; pub use after_render_component::*; -mod alter_markup_component; -pub use alter_markup_component::*; +mod transform_markup_component; +pub use transform_markup_component::*; diff --git a/src/base/action/component/after_render_component.rs b/src/base/action/component/after_render_component.rs index 0bed68c5..0778e9c8 100644 --- a/src/base/action/component/after_render_component.rs +++ b/src/base/action/component/after_render_component.rs @@ -1,6 +1,6 @@ use crate::prelude::*; -use crate::base::action::FnActionWithComponent; +use super::FnActionWithComponent; /// Ejecuta [`FnActionWithComponent`] después de renderizar un componente. pub struct AfterRender { @@ -57,24 +57,14 @@ impl AfterRender { pub(crate) fn dispatch(component: &mut C, cx: &mut Context) { // Primero despacha las acciones para el tipo de componente. dispatch_actions( - &ActionKey::new( - UniqueId::of::(), - None, - Some(UniqueId::of::()), - None, - ), + &ActionKey::new(UniqueId::of::(), Some(UniqueId::of::()), None), |action: &Self| (action.f)(component, cx), ); // Y luego despacha las acciones para el tipo de componente con un identificador dado. if let Some(id) = component.id() { dispatch_actions( - &ActionKey::new( - UniqueId::of::(), - None, - Some(UniqueId::of::()), - Some(id), - ), + &ActionKey::new(UniqueId::of::(), Some(UniqueId::of::()), Some(id)), |action: &Self| (action.f)(component, cx), ); } diff --git a/src/base/action/component/before_render_component.rs b/src/base/action/component/before_render_component.rs index 14f756d4..051a3dd6 100644 --- a/src/base/action/component/before_render_component.rs +++ b/src/base/action/component/before_render_component.rs @@ -1,6 +1,6 @@ use crate::prelude::*; -use crate::base::action::FnActionWithComponent; +use super::FnActionWithComponent; /// Ejecuta [`FnActionWithComponent`] antes de renderizar el componente. pub struct BeforeRender { @@ -57,24 +57,14 @@ impl BeforeRender { pub(crate) fn dispatch(component: &mut C, cx: &mut Context) { // Primero despacha las acciones para el tipo de componente. dispatch_actions( - &ActionKey::new( - UniqueId::of::(), - None, - Some(UniqueId::of::()), - None, - ), + &ActionKey::new(UniqueId::of::(), Some(UniqueId::of::()), None), |action: &Self| (action.f)(component, cx), ); // Y luego despacha las aciones para el tipo de componente con un identificador dado. if let Some(id) = component.id() { dispatch_actions( - &ActionKey::new( - UniqueId::of::(), - None, - Some(UniqueId::of::()), - Some(id), - ), + &ActionKey::new(UniqueId::of::(), Some(UniqueId::of::()), Some(id)), |action: &Self| (action.f)(component, cx), ); } diff --git a/src/base/action/component/alter_markup_component.rs b/src/base/action/component/transform_markup_component.rs similarity index 63% rename from src/base/action/component/alter_markup_component.rs rename to src/base/action/component/transform_markup_component.rs index 8bddd97a..0dfd1f51 100644 --- a/src/base/action/component/alter_markup_component.rs +++ b/src/base/action/component/transform_markup_component.rs @@ -1,18 +1,17 @@ use crate::prelude::*; -use crate::base::action::FnActionAlterMarkup; -use crate::html::html; +use super::FnActionTransformMarkup; -/// Ejecuta [`FnActionAlterMarkup`] para modificar el renderizado de un componente. -pub struct AlterMarkup { - f: FnActionAlterMarkup, +/// Ejecuta [`FnActionTransformMarkup`] para alterar el renderizado de componentes. +pub struct TransformMarkup { + f: FnActionTransformMarkup, referer_type_id: Option, referer_id: AttrId, weight: Weight, } -/// Filtro para despachar [`FnActionAlterMarkup`] sobre el renderizado de un componente `C`. -impl ActionDispatcher for AlterMarkup { +/// Filtro para despachar [`FnActionTransformMarkup`] sobre el renderizado de un componente `C`. +impl ActionDispatcher for TransformMarkup { /// Devuelve el identificador de tipo ([`UniqueId`]) del componente `C`. fn referer_type_id(&self) -> Option { self.referer_type_id @@ -29,10 +28,10 @@ impl ActionDispatcher for AlterMarkup { } } -impl AlterMarkup { - /// Permite [registrar](Extension::actions) una nueva acción [`FnActionAlterMarkup`]. - pub fn new(f: FnActionAlterMarkup) -> Self { - AlterMarkup { +impl TransformMarkup { + /// Permite [registrar](Extension::actions) una nueva acción [`FnActionTransformMarkup`]. + pub fn new(f: FnActionTransformMarkup) -> Self { + TransformMarkup { f, referer_type_id: Some(UniqueId::of::()), referer_id: AttrId::default(), @@ -40,8 +39,8 @@ impl AlterMarkup { } } - /// Afina el registro para ejecutar la acción [`FnActionAlterMarkup`] sólo para el componente - /// `C` con identificador `id`. + /// Afina el registro para ejecutar la acción [`FnActionTransformMarkup`] sólo para el + /// componente `C` con identificador `id`. pub fn filter_by_referer_id(mut self, id: impl AsRef) -> Self { self.referer_id.alter_id(id); self @@ -55,17 +54,12 @@ impl AlterMarkup { /// Despacha las acciones encadenando el [`Markup`] entre cada una. #[inline] - pub(crate) fn dispatch(component: &mut C, cx: &mut Context, markup: Markup) -> Markup { + pub(crate) fn dispatch(component: &C, cx: &mut Context, markup: Markup) -> Markup { let mut output = markup; // Primero despacha las acciones para el tipo de componente. dispatch_actions( - &ActionKey::new( - UniqueId::of::(), - None, - Some(UniqueId::of::()), - None, - ), + &ActionKey::new(UniqueId::of::(), Some(UniqueId::of::()), None), |action: &Self| { let taken = std::mem::replace(&mut output, html! {}); output = (action.f)(component, cx, taken); @@ -75,12 +69,7 @@ impl AlterMarkup { // Y luego despacha las acciones para el tipo de componente con un identificador dado. if let Some(id) = component.id() { dispatch_actions( - &ActionKey::new( - UniqueId::of::(), - None, - Some(UniqueId::of::()), - Some(id), - ), + &ActionKey::new(UniqueId::of::(), Some(UniqueId::of::()), Some(id)), |action: &Self| { let taken = std::mem::replace(&mut output, html! {}); output = (action.f)(component, cx, taken); diff --git a/src/base/action/page/after_render_body.rs b/src/base/action/page/after_render_body.rs index 7ecc353a..74ee0df1 100644 --- a/src/base/action/page/after_render_body.rs +++ b/src/base/action/page/after_render_body.rs @@ -1,6 +1,6 @@ use crate::prelude::*; -use crate::base::action::page::FnActionWithPage; +use super::FnActionWithPage; /// Ejecuta [`FnActionWithPage`](crate::base::action::page::FnActionWithPage) después de renderizar /// el cuerpo de la página. @@ -39,7 +39,7 @@ impl AfterRenderBody { #[allow(clippy::inline_always)] pub(crate) fn dispatch(page: &mut Page) { dispatch_actions( - &ActionKey::new(UniqueId::of::(), None, None, None), + &ActionKey::new(UniqueId::of::(), None, None), |action: &Self| (action.f)(page), ); } diff --git a/src/base/action/page/before_render_body.rs b/src/base/action/page/before_render_body.rs index d4ae64d0..7a72854f 100644 --- a/src/base/action/page/before_render_body.rs +++ b/src/base/action/page/before_render_body.rs @@ -1,6 +1,6 @@ use crate::prelude::*; -use crate::base::action::page::FnActionWithPage; +use super::FnActionWithPage; /// Ejecuta [`FnActionWithPage`](crate::base::action::page::FnActionWithPage) antes de renderizar /// el cuerpo de la página. @@ -39,7 +39,7 @@ impl BeforeRenderBody { #[allow(clippy::inline_always)] pub(crate) fn dispatch(page: &mut Page) { dispatch_actions( - &ActionKey::new(UniqueId::of::(), None, None, None), + &ActionKey::new(UniqueId::of::(), None, None), |action: &Self| (action.f)(page), ); } diff --git a/src/base/action/theme.rs b/src/base/action/theme.rs deleted file mode 100644 index a3db61a0..00000000 --- a/src/base/action/theme.rs +++ /dev/null @@ -1,7 +0,0 @@ -//! Acciones lanzadas desde los temas. - -mod before_render_component; -pub use before_render_component::*; - -mod after_render_component; -pub use after_render_component::*; diff --git a/src/base/action/theme/after_render_component.rs b/src/base/action/theme/after_render_component.rs deleted file mode 100644 index a31ad56a..00000000 --- a/src/base/action/theme/after_render_component.rs +++ /dev/null @@ -1,50 +0,0 @@ -use crate::prelude::*; - -use crate::base::action::FnActionWithComponent; - -/// Ejecuta [`FnActionWithComponent`] después de que un tema renderice el componente. -pub struct AfterRender { - f: FnActionWithComponent, - theme_type_id: Option, - referer_type_id: Option, -} - -/// Filtro para despachar [`FnActionWithComponent`] después de que un tema renderice el componente -/// `C`. -impl ActionDispatcher for AfterRender { - /// Devuelve el identificador de tipo ([`UniqueId`]) del tema. - fn theme_type_id(&self) -> Option { - self.theme_type_id - } - - /// Devuelve el identificador de tipo ([`UniqueId`]) del componente `C`. - fn referer_type_id(&self) -> Option { - self.referer_type_id - } -} - -impl AfterRender { - /// Permite [registrar](Extension::actions) una nueva acción [`FnActionWithComponent`] para un - /// tema dado. - pub fn new(theme: ThemeRef, f: FnActionWithComponent) -> Self { - AfterRender { - f, - theme_type_id: Some(theme.type_id()), - referer_type_id: Some(UniqueId::of::()), - } - } - - /// Despacha las acciones. - #[inline] - pub(crate) fn dispatch(component: &mut C, cx: &mut Context) { - dispatch_actions( - &ActionKey::new( - UniqueId::of::(), - Some(cx.theme().type_id()), - Some(UniqueId::of::()), - None, - ), - |action: &Self| (action.f)(component, cx), - ); - } -} diff --git a/src/base/action/theme/before_render_component.rs b/src/base/action/theme/before_render_component.rs deleted file mode 100644 index c00de8e9..00000000 --- a/src/base/action/theme/before_render_component.rs +++ /dev/null @@ -1,50 +0,0 @@ -use crate::prelude::*; - -use crate::base::action::FnActionWithComponent; - -/// Ejecuta [`FnActionWithComponent`] antes de que un tema renderice el componente. -pub struct BeforeRender { - f: FnActionWithComponent, - theme_type_id: Option, - referer_type_id: Option, -} - -/// Filtro para despachar [`FnActionWithComponent`] antes de que un tema renderice el componente -/// `C`. -impl ActionDispatcher for BeforeRender { - /// Devuelve el identificador de tipo ([`UniqueId`]) del tema. - fn theme_type_id(&self) -> Option { - self.theme_type_id - } - - /// Devuelve el identificador de tipo ([`UniqueId`]) del componente `C`. - fn referer_type_id(&self) -> Option { - self.referer_type_id - } -} - -impl BeforeRender { - /// Permite [registrar](Extension::actions) una nueva acción [`FnActionWithComponent`] para un - /// tema dado. - pub fn new(theme: ThemeRef, f: FnActionWithComponent) -> Self { - BeforeRender { - f, - theme_type_id: Some(theme.type_id()), - referer_type_id: Some(UniqueId::of::()), - } - } - - /// Despacha las acciones. - #[inline] - pub(crate) fn dispatch(component: &mut C, cx: &mut Context) { - dispatch_actions( - &ActionKey::new( - UniqueId::of::(), - Some(cx.theme().type_id()), - Some(UniqueId::of::()), - None, - ), - |action: &Self| (action.f)(component, cx), - ); - } -} diff --git a/src/core/action.rs b/src/core/action.rs index de66b296..ceb5eef4 100644 --- a/src/core/action.rs +++ b/src/core/action.rs @@ -14,50 +14,37 @@ mod all; pub(crate) use all::add_action; pub use all::dispatch_actions; -// **< actions_boxed! >***************************************************************************** +// **< actions! >*********************************************************************************** /// Facilita la implementación del método [`actions()`](crate::core::extension::Extension::actions). /// /// Evita escribir repetidamente `Box::new(...)` para cada acción de la lista, manteniendo el código /// más limpio. /// -/// # Ejemplos +/// # Ejemplo /// -/// Acciones de tema que ajustan un componente antes y después de renderizarlo: -/// -/// ```rust,ignore -/// impl Extension for MyTheme { -/// fn actions(&self) -> Vec { -/// actions_boxed![ -/// action::theme::BeforeRender::