mirror of
https://github.com/leptos-rs/leptos
synced 2024-11-10 06:44:17 +00:00
Merge pull request #2997 from leptos-rs/2971
Changes related to stack overflows
This commit is contained in:
commit
23ce022c60
7 changed files with 105 additions and 47 deletions
|
@ -17,8 +17,6 @@ where
|
|||
rndr: PhantomData,
|
||||
attributes: (),
|
||||
children: (),
|
||||
#[cfg(debug_assertions)]
|
||||
defined_at: std::panic::Location::caller(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -35,8 +35,6 @@ macro_rules! html_element_inner {
|
|||
attributes: (),
|
||||
children: (),
|
||||
rndr: PhantomData,
|
||||
#[cfg(debug_assertions)]
|
||||
defined_at: std::panic::Location::caller()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -63,17 +61,12 @@ macro_rules! html_element_inner {
|
|||
At: NextTuple,
|
||||
<At as NextTuple>::Output<Attr<$crate::html::attribute::[<$attr:camel>], V, Rndr>>: Attribute<Rndr>,
|
||||
{
|
||||
let HtmlElement { tag, rndr, children, attributes,
|
||||
#[cfg(debug_assertions)]
|
||||
defined_at
|
||||
} = self;
|
||||
let HtmlElement { tag, rndr, children, attributes } = self;
|
||||
HtmlElement {
|
||||
tag,
|
||||
rndr,
|
||||
children,
|
||||
attributes: attributes.next_tuple($crate::html::attribute::$attr(value)),
|
||||
#[cfg(debug_assertions)]
|
||||
defined_at
|
||||
}
|
||||
}
|
||||
)*
|
||||
|
@ -161,8 +154,6 @@ macro_rules! html_self_closing_elements {
|
|||
children: (),
|
||||
rndr: PhantomData,
|
||||
tag: [<$tag:camel>],
|
||||
#[cfg(debug_assertions)]
|
||||
defined_at: std::panic::Location::caller()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -191,16 +182,12 @@ macro_rules! html_self_closing_elements {
|
|||
|
||||
{
|
||||
let HtmlElement { tag, rndr, children, attributes,
|
||||
#[cfg(debug_assertions)]
|
||||
defined_at
|
||||
} = self;
|
||||
HtmlElement {
|
||||
tag,
|
||||
rndr,
|
||||
children,
|
||||
attributes: attributes.next_tuple($crate::html::attribute::$attr(value)),
|
||||
#[cfg(debug_assertions)]
|
||||
defined_at
|
||||
}
|
||||
}
|
||||
)*
|
||||
|
|
|
@ -32,8 +32,6 @@ pub struct HtmlElement<E, At, Ch, Rndr> {
|
|||
pub(crate) rndr: PhantomData<Rndr>,
|
||||
pub(crate) attributes: At,
|
||||
pub(crate) children: Ch,
|
||||
#[cfg(debug_assertions)]
|
||||
pub(crate) defined_at: &'static std::panic::Location<'static>,
|
||||
}
|
||||
|
||||
impl<E: Clone, At: Clone, Ch: Clone, Rndr> Clone
|
||||
|
@ -45,8 +43,6 @@ impl<E: Clone, At: Clone, Ch: Clone, Rndr> Clone
|
|||
rndr: PhantomData,
|
||||
attributes: self.attributes.clone(),
|
||||
children: self.children.clone(),
|
||||
#[cfg(debug_assertions)]
|
||||
defined_at: self.defined_at,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -85,16 +81,12 @@ where
|
|||
rndr,
|
||||
attributes,
|
||||
children,
|
||||
#[cfg(debug_assertions)]
|
||||
defined_at,
|
||||
} = self;
|
||||
HtmlElement {
|
||||
tag,
|
||||
rndr,
|
||||
attributes,
|
||||
children: children.next_tuple(child),
|
||||
#[cfg(debug_assertions)]
|
||||
defined_at,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -122,16 +114,12 @@ where
|
|||
attributes,
|
||||
children,
|
||||
rndr,
|
||||
#[cfg(debug_assertions)]
|
||||
defined_at,
|
||||
} = self;
|
||||
HtmlElement {
|
||||
tag,
|
||||
attributes: attributes.add_any_attr(attr),
|
||||
children,
|
||||
rndr,
|
||||
#[cfg(debug_assertions)]
|
||||
defined_at,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -262,8 +250,6 @@ where
|
|||
rndr: PhantomData,
|
||||
attributes,
|
||||
children,
|
||||
#[cfg(debug_assertions)]
|
||||
defined_at: self.defined_at,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -26,17 +26,12 @@ macro_rules! mathml_global {
|
|||
At: NextTuple,
|
||||
<At as NextTuple>::Output<Attr<$crate::html::attribute::[<$attr:camel>], V, Rndr>>: Attribute<Rndr>,
|
||||
{
|
||||
let HtmlElement { tag, rndr, children, attributes,
|
||||
#[cfg(debug_assertions)]
|
||||
defined_at
|
||||
} = self;
|
||||
let HtmlElement { tag, rndr, children, attributes } = self;
|
||||
HtmlElement {
|
||||
tag,
|
||||
rndr,
|
||||
children,
|
||||
attributes: attributes.next_tuple($crate::html::attribute::$attr(value)),
|
||||
#[cfg(debug_assertions)]
|
||||
defined_at
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -59,8 +54,6 @@ macro_rules! mathml_elements {
|
|||
attributes: (),
|
||||
children: (),
|
||||
rndr: PhantomData,
|
||||
#[cfg(debug_assertions)]
|
||||
defined_at: std::panic::Location::caller()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -95,17 +88,12 @@ macro_rules! mathml_elements {
|
|||
At: NextTuple,
|
||||
<At as NextTuple>::Output<Attr<$crate::html::attribute::[<$attr:camel>], V, Rndr>>: Attribute<Rndr>,
|
||||
{
|
||||
let HtmlElement { tag, rndr, children, attributes,
|
||||
#[cfg(debug_assertions)]
|
||||
defined_at
|
||||
} = self;
|
||||
let HtmlElement { tag, rndr, children, attributes } = self;
|
||||
HtmlElement {
|
||||
tag,
|
||||
rndr,
|
||||
children,
|
||||
attributes: attributes.next_tuple($crate::html::attribute::$attr(value)),
|
||||
#[cfg(debug_assertions)]
|
||||
defined_at
|
||||
}
|
||||
}
|
||||
)*
|
||||
|
|
|
@ -27,8 +27,6 @@ macro_rules! svg_elements {
|
|||
attributes: (),
|
||||
children: (),
|
||||
rndr: PhantomData,
|
||||
#[cfg(debug_assertions)]
|
||||
defined_at: std::panic::Location::caller()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use super::RenderHtml;
|
||||
use super::{BoxedView, RenderHtml};
|
||||
use crate::{html::attribute::Attribute, renderer::Renderer};
|
||||
|
||||
/// Allows adding a new attribute to some type, before it is rendered.
|
||||
|
@ -44,3 +44,22 @@ macro_rules! no_attrs {
|
|||
}
|
||||
};
|
||||
}
|
||||
|
||||
impl<T, Rndr> AddAnyAttr<Rndr> for BoxedView<T>
|
||||
where
|
||||
T: AddAnyAttr<Rndr>,
|
||||
Rndr: Renderer,
|
||||
{
|
||||
type Output<SomeNewAttr: Attribute<Rndr>> =
|
||||
BoxedView<T::Output<SomeNewAttr>>;
|
||||
|
||||
fn add_any_attr<NewAttr: Attribute<Rndr>>(
|
||||
self,
|
||||
attr: NewAttr,
|
||||
) -> Self::Output<NewAttr>
|
||||
where
|
||||
Self::Output<NewAttr>: RenderHtml<Rndr>,
|
||||
{
|
||||
BoxedView::new(self.into_inner().add_any_attr(attr))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -425,3 +425,85 @@ pub enum Position {
|
|||
/// This is the last child of its parent.
|
||||
LastChild,
|
||||
}
|
||||
|
||||
/// A view stored on the heap.
|
||||
///
|
||||
/// This is a newtype around `Box<_>` that allows us to implement rendering traits on it.
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct BoxedView<T>(Box<T>);
|
||||
|
||||
impl<T> BoxedView<T> {
|
||||
/// Stores view on the heap.
|
||||
pub fn new(value: T) -> Self {
|
||||
Self(Box::new(value))
|
||||
}
|
||||
|
||||
/// Deferences the view to its inner value.
|
||||
pub fn into_inner(self) -> T {
|
||||
*self.0
|
||||
}
|
||||
|
||||
/// Gives a shared reference to the view.
|
||||
pub fn as_ref(&self) -> &T {
|
||||
&self.0
|
||||
}
|
||||
|
||||
/// Gives an exclusive reference to the view.
|
||||
pub fn as_mut(&mut self) -> &mut T {
|
||||
&mut self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, Rndr> Render<Rndr> for BoxedView<T>
|
||||
where
|
||||
T: Render<Rndr>,
|
||||
Rndr: Renderer,
|
||||
{
|
||||
type State = T::State;
|
||||
|
||||
fn build(self) -> Self::State {
|
||||
self.into_inner().build()
|
||||
}
|
||||
|
||||
fn rebuild(self, state: &mut Self::State) {
|
||||
self.into_inner().rebuild(state);
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, Rndr> RenderHtml<Rndr> for BoxedView<T>
|
||||
where
|
||||
T: RenderHtml<Rndr>,
|
||||
Rndr: Renderer,
|
||||
{
|
||||
type AsyncOutput = BoxedView<T::AsyncOutput>;
|
||||
|
||||
const MIN_LENGTH: usize = T::MIN_LENGTH;
|
||||
|
||||
fn dry_resolve(&mut self) {
|
||||
self.as_mut().dry_resolve();
|
||||
}
|
||||
|
||||
async fn resolve(self) -> Self::AsyncOutput {
|
||||
let inner = self.into_inner().resolve().await;
|
||||
BoxedView::new(inner)
|
||||
}
|
||||
|
||||
fn to_html_with_buf(
|
||||
self,
|
||||
buf: &mut String,
|
||||
position: &mut Position,
|
||||
escape: bool,
|
||||
mark_branches: bool,
|
||||
) {
|
||||
self.into_inner()
|
||||
.to_html_with_buf(buf, position, escape, mark_branches)
|
||||
}
|
||||
|
||||
fn hydrate<const FROM_SERVER: bool>(
|
||||
self,
|
||||
cursor: &Cursor<Rndr>,
|
||||
position: &PositionState,
|
||||
) -> Self::State {
|
||||
self.into_inner().hydrate::<FROM_SERVER>(cursor, position)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue