mirror of
https://github.com/leptos-rs/leptos
synced 2024-11-10 14:54:16 +00:00
renamed IntoNode
to IntoView
and Node
to View, and fixed broken doc links
This commit is contained in:
parent
1fbe8bd790
commit
b3d813d0c1
9 changed files with 221 additions and 216 deletions
|
@ -5,7 +5,7 @@ mod unit;
|
|||
|
||||
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
||||
use crate::{mount_child, MountKind, Mountable};
|
||||
use crate::{Comment, IntoNode, Node};
|
||||
use crate::{Comment, IntoView, View};
|
||||
pub use dyn_child::*;
|
||||
pub use each::*;
|
||||
pub use fragment::*;
|
||||
|
@ -23,7 +23,7 @@ pub enum CoreComponent {
|
|||
Unit(UnitRepr),
|
||||
/// The [`DynChild`] component.
|
||||
DynChild(DynChildRepr),
|
||||
/// The [`Each`] component.
|
||||
/// The [`EachKey`] component.
|
||||
Each(EachRepr),
|
||||
}
|
||||
|
||||
|
@ -37,14 +37,14 @@ pub struct ComponentRepr {
|
|||
#[cfg(debug_assertions)]
|
||||
_opening: Comment,
|
||||
/// The children of the component.
|
||||
pub children: Vec<Node>,
|
||||
pub children: Vec<View>,
|
||||
closing: Comment,
|
||||
disposer: Option<ScopeDisposer>,
|
||||
}
|
||||
|
||||
impl Drop for ComponentRepr {
|
||||
fn drop(&mut self) {
|
||||
// TODO: all ComponentReprs are immediately dropped,
|
||||
// TODO: all ComponentReprs are immediately dropped,
|
||||
// which means their scopes are immediately disposed,
|
||||
// which means components have no reactivity
|
||||
if let Some(disposer) = self.disposer.take() {
|
||||
|
@ -71,15 +71,15 @@ impl Mountable for ComponentRepr {
|
|||
}
|
||||
}
|
||||
|
||||
impl IntoNode for ComponentRepr {
|
||||
impl IntoView for ComponentRepr {
|
||||
#[cfg_attr(debug_assertions, instrument(level = "trace", name = "<Component />", skip_all, fields(name = %self.name)))]
|
||||
fn into_node(self, _: Scope) -> Node {
|
||||
fn into_view(self, _: Scope) -> View {
|
||||
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
||||
for child in &self.children {
|
||||
mount_child(MountKind::Before(&self.closing.node), child);
|
||||
}
|
||||
|
||||
Node::Component(self)
|
||||
View::Component(self)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -133,7 +133,7 @@ impl ComponentRepr {
|
|||
/// A user-defined `leptos` component.
|
||||
pub struct Component<F>
|
||||
where
|
||||
F: FnOnce(Scope) -> Node,
|
||||
F: FnOnce(Scope) -> View,
|
||||
{
|
||||
name: Cow<'static, str>,
|
||||
children_fn: F,
|
||||
|
@ -141,7 +141,7 @@ where
|
|||
|
||||
impl<F> Component<F>
|
||||
where
|
||||
F: FnOnce(Scope) -> Node,
|
||||
F: FnOnce(Scope) -> View,
|
||||
{
|
||||
/// Creates a new component.
|
||||
pub fn new(name: impl Into<Cow<'static, str>>, f: F) -> Self {
|
||||
|
@ -152,16 +152,17 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<F> IntoNode for Component<F>
|
||||
impl<F> IntoView for Component<F>
|
||||
where
|
||||
F: FnOnce(Scope) -> Node,
|
||||
F: FnOnce(Scope) -> View,
|
||||
{
|
||||
fn into_node(self, cx: Scope) -> Node {
|
||||
fn into_view(self, cx: Scope) -> View {
|
||||
let Self { name, children_fn } = self;
|
||||
|
||||
let mut children = None;
|
||||
|
||||
let disposer = cx.child_scope(|cx| children = Some(cx.untrack(move || children_fn(cx))));
|
||||
let disposer =
|
||||
cx.child_scope(|cx| children = Some(cx.untrack(move || children_fn(cx))));
|
||||
|
||||
let children = children.unwrap();
|
||||
|
||||
|
@ -170,6 +171,6 @@ where
|
|||
repr.disposer = Some(disposer);
|
||||
repr.children = vec![children];
|
||||
|
||||
repr.into_node(cx)
|
||||
repr.into_view(cx)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
||||
use crate::{mount_child, MountKind, Mountable};
|
||||
use crate::{Comment, IntoNode, Node};
|
||||
use crate::{Comment, IntoView, View};
|
||||
use leptos_reactive::{create_effect, Scope};
|
||||
use std::{borrow::Cow, cell::RefCell, rc::Rc};
|
||||
use wasm_bindgen::JsCast;
|
||||
|
@ -12,7 +12,7 @@ pub struct DynChildRepr {
|
|||
document_fragment: web_sys::DocumentFragment,
|
||||
#[cfg(debug_assertions)]
|
||||
opening: Comment,
|
||||
child: Rc<RefCell<Box<Option<Node>>>>,
|
||||
child: Rc<RefCell<Box<Option<View>>>>,
|
||||
closing: Comment,
|
||||
}
|
||||
|
||||
|
@ -69,11 +69,11 @@ impl DynChildRepr {
|
|||
}
|
||||
}
|
||||
|
||||
/// Represents any [`Node`] that can change over time.
|
||||
/// Represents any [`View`] that can change over time.
|
||||
pub struct DynChild<CF, N>
|
||||
where
|
||||
CF: Fn() -> N + 'static,
|
||||
N: IntoNode,
|
||||
N: IntoView,
|
||||
{
|
||||
child_fn: CF,
|
||||
}
|
||||
|
@ -81,7 +81,7 @@ where
|
|||
impl<CF, N> DynChild<CF, N>
|
||||
where
|
||||
CF: Fn() -> N + 'static,
|
||||
N: IntoNode,
|
||||
N: IntoView,
|
||||
{
|
||||
/// Creates a new dynamic child which will re-render whenever it's
|
||||
/// signal dependencies change.
|
||||
|
@ -90,16 +90,16 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<CF, N> IntoNode for DynChild<CF, N>
|
||||
impl<CF, N> IntoView for DynChild<CF, N>
|
||||
where
|
||||
CF: Fn() -> N + 'static,
|
||||
N: IntoNode,
|
||||
N: IntoView,
|
||||
{
|
||||
#[cfg_attr(
|
||||
debug_assertions,
|
||||
instrument(level = "trace", name = "<DynChild />", skip_all)
|
||||
)]
|
||||
fn into_node(self, cx: Scope) -> crate::Node {
|
||||
fn into_view(self, cx: Scope) -> crate::View {
|
||||
let Self { child_fn } = self;
|
||||
|
||||
let component = DynChildRepr::new();
|
||||
|
@ -123,7 +123,7 @@ where
|
|||
create_effect(cx, move |prev_run| {
|
||||
let _guard = span.enter();
|
||||
let _guard = trace_span!("DynChild reactive").entered();
|
||||
let new_child = child_fn().into_node(cx);
|
||||
let new_child = child_fn().into_view(cx);
|
||||
if let Some(t) = new_child.get_text() {
|
||||
let mut prev_text_node_borrow = prev_text_node.borrow_mut();
|
||||
|
||||
|
@ -155,11 +155,11 @@ where
|
|||
|
||||
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
||||
mount_child(MountKind::Before(&closing), &new_child);
|
||||
|
||||
|
||||
**child.borrow_mut() = Some(new_child);
|
||||
}
|
||||
});
|
||||
|
||||
Node::CoreComponent(crate::CoreComponent::DynChild(component))
|
||||
View::CoreComponent(crate::CoreComponent::DynChild(component))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
||||
use crate::{mount_child, MountKind, Mountable, RANGE};
|
||||
use crate::{Comment, CoreComponent, IntoNode, Node};
|
||||
use crate::{Comment, CoreComponent, IntoView, View};
|
||||
use itertools::{EitherOrBoth, Itertools};
|
||||
use leptos_reactive::{create_effect, Scope};
|
||||
use rustc_hash::FxHasher;
|
||||
|
@ -39,7 +39,7 @@ impl VecExt for Vec<Option<EachItem>> {
|
|||
}
|
||||
}
|
||||
|
||||
/// The internal representation of the [`Each`] core-component.
|
||||
/// The internal representation of the [`EachKey`] core-component.
|
||||
#[derive(Debug)]
|
||||
pub struct EachRepr {
|
||||
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
||||
|
@ -110,19 +110,19 @@ impl Mountable for EachRepr {
|
|||
}
|
||||
}
|
||||
|
||||
/// The internal representation of an [`Each`] item.
|
||||
/// The internal representation of an [`EachKey`] item.
|
||||
#[derive(Debug)]
|
||||
struct EachItem {
|
||||
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
||||
document_fragment: web_sys::DocumentFragment,
|
||||
#[cfg(debug_assertions)]
|
||||
opening: Comment,
|
||||
child: Node,
|
||||
child: View,
|
||||
closing: Comment,
|
||||
}
|
||||
|
||||
impl EachItem {
|
||||
fn new(child: Node) -> Self {
|
||||
fn new(child: View) -> Self {
|
||||
let markers = (
|
||||
Comment::new(Cow::Borrowed("</EachItem>")),
|
||||
#[cfg(debug_assertions)]
|
||||
|
@ -201,7 +201,7 @@ where
|
|||
IF: Fn() -> I + 'static,
|
||||
I: IntoIterator<Item = T>,
|
||||
EF: Fn(T) -> N + 'static,
|
||||
N: IntoNode,
|
||||
N: IntoView,
|
||||
KF: Fn(&T) -> K + 'static,
|
||||
K: Eq + Hash + 'static,
|
||||
T: 'static,
|
||||
|
@ -216,12 +216,12 @@ where
|
|||
IF: Fn() -> I + 'static,
|
||||
I: IntoIterator<Item = T>,
|
||||
EF: Fn(T) -> N + 'static,
|
||||
N: IntoNode,
|
||||
N: IntoView,
|
||||
KF: Fn(&T) -> K,
|
||||
K: Eq + Hash + 'static,
|
||||
T: 'static,
|
||||
{
|
||||
/// Creates a new [`Each`] component.
|
||||
/// Creates a new [`EachKey`] component.
|
||||
pub fn new(items_fn: IF, key_fn: KF, each_fn: EF) -> Self {
|
||||
Self {
|
||||
items_fn,
|
||||
|
@ -231,12 +231,12 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<IF, I, T, EF, N, KF, K> IntoNode for EachKey<IF, I, T, EF, N, KF, K>
|
||||
impl<IF, I, T, EF, N, KF, K> IntoView for EachKey<IF, I, T, EF, N, KF, K>
|
||||
where
|
||||
IF: Fn() -> I + 'static,
|
||||
I: IntoIterator<Item = T>,
|
||||
EF: Fn(T) -> N + 'static,
|
||||
N: IntoNode,
|
||||
N: IntoView,
|
||||
KF: Fn(&T) -> K + 'static,
|
||||
K: Eq + Hash + 'static,
|
||||
T: 'static,
|
||||
|
@ -245,7 +245,7 @@ where
|
|||
debug_assertions,
|
||||
instrument(level = "trace", name = "<Each />", skip_all)
|
||||
)]
|
||||
fn into_node(self, cx: leptos_reactive::Scope) -> crate::Node {
|
||||
fn into_view(self, cx: leptos_reactive::Scope) -> crate::View {
|
||||
let Self {
|
||||
items_fn,
|
||||
each_fn,
|
||||
|
@ -294,7 +294,7 @@ where
|
|||
*children_borrow = Vec::with_capacity(items.len());
|
||||
|
||||
for item in items {
|
||||
let child = each_fn(item).into_node(cx);
|
||||
let child = each_fn(item).into_view(cx);
|
||||
|
||||
let each_item = EachItem::new(child);
|
||||
|
||||
|
@ -308,7 +308,7 @@ where
|
|||
HashRun(hashed_items)
|
||||
});
|
||||
|
||||
Node::CoreComponent(CoreComponent::Each(component))
|
||||
View::CoreComponent(CoreComponent::Each(component))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -483,7 +483,7 @@ fn apply_cmds<T, EF, N>(
|
|||
each_fn: &EF,
|
||||
) where
|
||||
EF: Fn(T) -> N,
|
||||
N: IntoNode,
|
||||
N: IntoView,
|
||||
{
|
||||
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
||||
let range = &RANGE;
|
||||
|
@ -558,7 +558,7 @@ fn apply_cmds<T, EF, N>(
|
|||
for DiffOpAdd { at, mode } in cmds.added {
|
||||
let item = std::mem::replace(&mut items[at], None).unwrap();
|
||||
|
||||
let child = each_fn(item).into_node(cx);
|
||||
let child = each_fn(item).into_view(cx);
|
||||
|
||||
let each_item = EachItem::new(child);
|
||||
|
||||
|
@ -605,7 +605,7 @@ where
|
|||
IF: Fn() -> I + 'static,
|
||||
I: IntoIterator<Item = T>,
|
||||
EF: Fn(T) -> N + 'static,
|
||||
N: IntoNode,
|
||||
N: IntoView,
|
||||
KF: Fn(&T) -> K + 'static,
|
||||
K: Eq + Hash + 'static,
|
||||
T: 'static,
|
||||
|
@ -661,16 +661,16 @@ where
|
|||
pub fn For<IF, I, T, EF, N, KF, K>(
|
||||
cx: Scope,
|
||||
props: ForProps<IF, I, T, EF, N, KF, K>,
|
||||
) -> Node
|
||||
) -> View
|
||||
where
|
||||
IF: Fn() -> I + 'static,
|
||||
I: IntoIterator<Item = T>,
|
||||
EF: Fn(T) -> N + 'static,
|
||||
N: IntoNode,
|
||||
N: IntoView,
|
||||
KF: Fn(&T) -> K + 'static,
|
||||
K: Eq + Hash + 'static,
|
||||
T: 'static,
|
||||
{
|
||||
let each_fn = (props.children)().swap_remove(0);
|
||||
EachKey::new(props.each, props.key, each_fn).into_node(cx)
|
||||
EachKey::new(props.each, props.key, each_fn).into_view(cx)
|
||||
}
|
||||
|
|
|
@ -1,21 +1,21 @@
|
|||
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
||||
use crate::{mount_child, MountKind};
|
||||
use crate::{ComponentRepr, IntoNode, Node};
|
||||
use crate::{ComponentRepr, IntoView, View};
|
||||
|
||||
/// Represents a group of [`Nodes`](Node).
|
||||
/// Represents a group of [`views`](View).
|
||||
#[derive(Debug)]
|
||||
pub struct Fragment(Vec<Node>);
|
||||
pub struct Fragment(Vec<View>);
|
||||
|
||||
impl Fragment {
|
||||
/// Creates a new [`Fragment`] from a [`Vec<Node>`].
|
||||
pub fn new(nodes: Vec<Node>) -> Self {
|
||||
pub fn new(nodes: Vec<View>) -> Self {
|
||||
Self(nodes)
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoNode for Fragment {
|
||||
impl IntoView for Fragment {
|
||||
#[cfg_attr(debug_assertions, instrument(level = "trace", name = "</>", skip_all, fields(children = self.0.len())))]
|
||||
fn into_node(self, _cx: leptos_reactive::Scope) -> Node {
|
||||
fn into_view(self, _cx: leptos_reactive::Scope) -> View {
|
||||
let mut frag = ComponentRepr::new("");
|
||||
|
||||
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
||||
|
@ -28,6 +28,6 @@ impl IntoNode for Fragment {
|
|||
|
||||
frag.children = self.0;
|
||||
|
||||
Node::Component(frag)
|
||||
View::Component(frag)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
||||
use crate::Mountable;
|
||||
use crate::{Comment, CoreComponent, IntoNode, Node};
|
||||
use crate::{Comment, CoreComponent, IntoView, View};
|
||||
use wasm_bindgen::JsCast;
|
||||
|
||||
/// The internal representation of the [`Unit`] core-component.
|
||||
|
@ -32,14 +32,14 @@ impl Mountable for UnitRepr {
|
|||
#[derive(Clone, Copy, Debug)]
|
||||
pub struct Unit;
|
||||
|
||||
impl IntoNode for Unit {
|
||||
impl IntoView for Unit {
|
||||
#[cfg_attr(
|
||||
debug_assertions,
|
||||
instrument(level = "trace", name = "<() />", skip_all)
|
||||
)]
|
||||
fn into_node(self, _: leptos_reactive::Scope) -> crate::Node {
|
||||
fn into_view(self, _: leptos_reactive::Scope) -> crate::View {
|
||||
let component = UnitRepr::default();
|
||||
|
||||
Node::CoreComponent(CoreComponent::Unit(component))
|
||||
View::CoreComponent(CoreComponent::Unit(component))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
||||
use crate::events::*;
|
||||
use crate::{
|
||||
components::DynChild, ev::EventDescriptor, Element, Fragment, IntoNode, Node,
|
||||
Text,
|
||||
components::DynChild, ev::EventDescriptor, Element, Fragment, IntoView, Text,
|
||||
View,
|
||||
};
|
||||
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
||||
use crate::{mount_child, MountKind};
|
||||
|
@ -52,8 +52,7 @@ pub trait IntoElement: IntoElementBounds {
|
|||
}
|
||||
}
|
||||
|
||||
/// Represents potentially any element, which you can change
|
||||
/// at any time before calling [`HtmlElement::into_node`].
|
||||
/// Represents potentially any element.
|
||||
#[derive(Clone, Debug)]
|
||||
#[cfg_attr(all(target_arch = "wasm32", feature = "web"), derive(educe::Educe))]
|
||||
#[cfg_attr(all(target_arch = "wasm32", feature = "web"), educe(Deref))]
|
||||
|
@ -124,7 +123,7 @@ cfg_if! {
|
|||
pub(crate) attrs: SmallVec<[(Cow<'static, str>, Cow<'static, str>); 4]>,
|
||||
#[educe(Debug(ignore))]
|
||||
#[allow(clippy::type_complexity)]
|
||||
pub(crate) children: SmallVec<[Box<dyn FnOnce(Scope) -> Node>; 4]>,
|
||||
pub(crate) children: SmallVec<[Box<dyn FnOnce(Scope) -> View>; 4]>,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -418,11 +417,11 @@ impl<El: IntoElement> HtmlElement<El> {
|
|||
}
|
||||
|
||||
/// Inserts a child into this element.
|
||||
pub fn child<C: IntoNode + 'static>(mut self, child: C) -> Self {
|
||||
pub fn child<C: IntoView + 'static>(mut self, child: C) -> Self {
|
||||
cfg_if! {
|
||||
if #[cfg(all(target_arch = "wasm32", feature = "web"))] {
|
||||
{
|
||||
let child = child.into_node(self.cx);
|
||||
let child = child.into_view(self.cx);
|
||||
|
||||
mount_child(MountKind::Append(self.element.get_element()), &child)
|
||||
}
|
||||
|
@ -440,11 +439,11 @@ impl<El: IntoElement> HtmlElement<El> {
|
|||
pub fn dyn_child<CF, N>(mut self, child_fn: CF) -> Self
|
||||
where
|
||||
CF: Fn() -> N + 'static,
|
||||
N: IntoNode,
|
||||
N: IntoView,
|
||||
{
|
||||
cfg_if! {
|
||||
if #[cfg(all(target_arch = "wasm32", feature = "web"))] {
|
||||
mount_child(MountKind::Append(self.element.get_element()), &DynChild::new(child_fn).into_node(self.cx))
|
||||
mount_child(MountKind::Append(self.element.get_element()), &DynChild::new(child_fn).into_view(self.cx))
|
||||
} else {
|
||||
self
|
||||
.children
|
||||
|
@ -456,12 +455,12 @@ impl<El: IntoElement> HtmlElement<El> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<El: IntoElement> IntoNode for HtmlElement<El> {
|
||||
impl<El: IntoElement> IntoView for HtmlElement<El> {
|
||||
#[cfg_attr(debug_assertions, instrument(level = "trace", name = "<HtmlElement />", skip_all, fields(tag = %self.element.name())))]
|
||||
fn into_node(self, cx: Scope) -> Node {
|
||||
fn into_view(self, cx: Scope) -> View {
|
||||
cfg_if! {
|
||||
if #[cfg(all(target_arch = "wasm32", feature = "web"))] {
|
||||
Node::Element(Element::new(self.element))
|
||||
View::Element(Element::new(self.element))
|
||||
} else {
|
||||
let Self { element, attrs, children, .. } = self;
|
||||
let mut element = Element::new(element);
|
||||
|
@ -473,31 +472,31 @@ impl<El: IntoElement> IntoNode for HtmlElement<El> {
|
|||
element.attrs = attrs;
|
||||
element.children.extend(children);
|
||||
|
||||
Node::Element(element)
|
||||
View::Element(element)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<El: IntoElement> IntoNode for Vec<HtmlElement<El>> {
|
||||
impl<El: IntoElement> IntoView for Vec<HtmlElement<El>> {
|
||||
#[cfg_attr(
|
||||
debug_assertions,
|
||||
instrument(level = "trace", name = "Vec<HtmlElement>", skip_all)
|
||||
)]
|
||||
fn into_node(self, cx: Scope) -> Node {
|
||||
Fragment::new(self.into_iter().map(|el| el.into_node(cx)).collect())
|
||||
.into_node(cx)
|
||||
fn into_view(self, cx: Scope) -> View {
|
||||
Fragment::new(self.into_iter().map(|el| el.into_view(cx)).collect())
|
||||
.into_view(cx)
|
||||
}
|
||||
}
|
||||
|
||||
impl<El: IntoElement, const N: usize> IntoNode for [HtmlElement<El>; N] {
|
||||
impl<El: IntoElement, const N: usize> IntoView for [HtmlElement<El>; N] {
|
||||
#[cfg_attr(
|
||||
debug_assertions,
|
||||
instrument(level = "trace", name = "[HtmlElement; N]", skip_all)
|
||||
)]
|
||||
fn into_node(self, cx: Scope) -> Node {
|
||||
Fragment::new(self.into_iter().map(|el| el.into_node(cx)).collect())
|
||||
.into_node(cx)
|
||||
fn into_view(self, cx: Scope) -> View {
|
||||
Fragment::new(self.into_iter().map(|el| el.into_view(cx)).collect())
|
||||
.into_view(cx)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -514,9 +513,9 @@ pub fn custom<El: IntoElement>(cx: Scope, el: El) -> HtmlElement<Custom> {
|
|||
}
|
||||
|
||||
/// Creates a text node.
|
||||
pub fn text(text: impl Into<Cow<'static, str>>) -> Node {
|
||||
pub fn text(text: impl Into<Cow<'static, str>>) -> View {
|
||||
let text = Text::new(text.into());
|
||||
Node::Text(text)
|
||||
View::Text(text)
|
||||
}
|
||||
|
||||
macro_rules! generate_html_tags {
|
||||
|
@ -722,7 +721,7 @@ impl<El: IntoElement> HtmlElement<El> {
|
|||
let child = child.into_child(cx);
|
||||
cfg_if! {
|
||||
if #[cfg(all(target_arch = "wasm32", feature = "web"))] {
|
||||
mount_child(MountKind::Append(self.element.get_element()), &child.into_node(cx))
|
||||
mount_child(MountKind::Append(self.element.get_element()), &child.into_view(cx))
|
||||
}
|
||||
else {
|
||||
self.children.push(Box::new(move |cx| child.into_node(cx)));
|
||||
|
|
|
@ -42,10 +42,10 @@ static COMMENT: LazyCell<web_sys::Node> =
|
|||
static RANGE: LazyCell<web_sys::Range> =
|
||||
LazyCell::new(|| web_sys::Range::new().unwrap());
|
||||
|
||||
/// Converts the value into a [`Node`].
|
||||
pub trait IntoNode {
|
||||
/// Converts the value into [`Node`].
|
||||
fn into_node(self, cx: Scope) -> Node;
|
||||
/// Converts the value into a [`View`].
|
||||
pub trait IntoView {
|
||||
/// Converts the value into [`View`].
|
||||
fn into_view(self, cx: Scope) -> View;
|
||||
}
|
||||
|
||||
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
||||
|
@ -63,44 +63,44 @@ trait Mountable {
|
|||
fn get_opening_node(&self) -> web_sys::Node;
|
||||
}
|
||||
|
||||
impl IntoNode for () {
|
||||
impl IntoView for () {
|
||||
#[cfg_attr(
|
||||
debug_assertions,
|
||||
instrument(level = "trace", name = "<() />", skip_all)
|
||||
)]
|
||||
fn into_node(self, cx: Scope) -> Node {
|
||||
Unit.into_node(cx)
|
||||
fn into_view(self, cx: Scope) -> View {
|
||||
Unit.into_view(cx)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> IntoNode for Option<T>
|
||||
impl<T> IntoView for Option<T>
|
||||
where
|
||||
T: IntoNode,
|
||||
T: IntoView,
|
||||
{
|
||||
#[cfg_attr(
|
||||
debug_assertions,
|
||||
instrument(level = "trace", name = "Option<T>", skip_all)
|
||||
)]
|
||||
fn into_node(self, cx: Scope) -> Node {
|
||||
fn into_view(self, cx: Scope) -> View {
|
||||
if let Some(t) = self {
|
||||
t.into_node(cx)
|
||||
t.into_view(cx)
|
||||
} else {
|
||||
Unit.into_node(cx)
|
||||
Unit.into_view(cx)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<F, N> IntoNode for F
|
||||
impl<F, N> IntoView for F
|
||||
where
|
||||
F: Fn() -> N + 'static,
|
||||
N: IntoNode,
|
||||
N: IntoView,
|
||||
{
|
||||
#[cfg_attr(
|
||||
debug_assertions,
|
||||
instrument(level = "trace", name = "Fn() -> N", skip_all)
|
||||
)]
|
||||
fn into_node(self, cx: Scope) -> Node {
|
||||
DynChild::new(self).into_node(cx)
|
||||
fn into_view(self, cx: Scope) -> View {
|
||||
DynChild::new(self).into_view(cx)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -120,15 +120,15 @@ cfg_if! {
|
|||
name: Cow<'static, str>,
|
||||
is_void: bool,
|
||||
attrs: SmallVec<[(Cow<'static, str>, Cow<'static, str>); 4]>,
|
||||
children: Vec<Node>,
|
||||
children: Vec<View>,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoNode for Element {
|
||||
impl IntoView for Element {
|
||||
#[cfg_attr(debug_assertions, instrument(level = "trace", name = "<Element />", skip_all, fields(tag = %self.name)))]
|
||||
fn into_node(self, _: Scope) -> Node {
|
||||
Node::Element(self)
|
||||
fn into_view(self, _: Scope) -> View {
|
||||
View::Element(self)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -191,10 +191,10 @@ pub struct Text {
|
|||
content: Cow<'static, str>,
|
||||
}
|
||||
|
||||
impl IntoNode for Text {
|
||||
impl IntoView for Text {
|
||||
#[cfg_attr(debug_assertions, instrument(level = "trace", name = "#text", skip_all, fields(content = %self.content)))]
|
||||
fn into_node(self, _: Scope) -> Node {
|
||||
Node::Text(self)
|
||||
fn into_view(self, _: Scope) -> View {
|
||||
View::Text(self)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -213,9 +213,9 @@ impl Text {
|
|||
}
|
||||
}
|
||||
|
||||
/// A leptos Node.
|
||||
/// A leptos view which can be mounted to the DOM.
|
||||
#[derive(Debug)]
|
||||
pub enum Node {
|
||||
pub enum View {
|
||||
/// HTML element node.
|
||||
Element(Element),
|
||||
/// HTML text node.
|
||||
|
@ -226,42 +226,42 @@ pub enum Node {
|
|||
CoreComponent(CoreComponent),
|
||||
}
|
||||
|
||||
/// The default [`Node`] is the [`Unit`] core-component.
|
||||
impl Default for Node {
|
||||
/// The default [`View`] is the [`Unit`] core-component.
|
||||
impl Default for View {
|
||||
fn default() -> Self {
|
||||
Self::CoreComponent(Default::default())
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoNode for Node {
|
||||
impl IntoView for View {
|
||||
#[cfg_attr(debug_assertions, instrument(level = "trace", name = "Node", skip_all, fields(kind = self.kind_name())))]
|
||||
fn into_node(self, _: Scope) -> Node {
|
||||
fn into_view(self, _: Scope) -> View {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoNode for Vec<Node> {
|
||||
impl IntoView for Vec<View> {
|
||||
#[cfg_attr(
|
||||
debug_assertions,
|
||||
instrument(level = "trace", name = "Vec<Node>", skip_all)
|
||||
)]
|
||||
fn into_node(self, cx: Scope) -> Node {
|
||||
Fragment::new(self).into_node(cx)
|
||||
fn into_view(self, cx: Scope) -> View {
|
||||
Fragment::new(self).into_view(cx)
|
||||
}
|
||||
}
|
||||
|
||||
impl<const N: usize> IntoNode for [Node; N] {
|
||||
impl<const N: usize> IntoView for [View; N] {
|
||||
#[cfg_attr(
|
||||
debug_assertions,
|
||||
instrument(level = "trace", name = "[Node; N]", skip_all)
|
||||
)]
|
||||
fn into_node(self, cx: Scope) -> Node {
|
||||
Fragment::new(self.into_iter().collect()).into_node(cx)
|
||||
fn into_view(self, cx: Scope) -> View {
|
||||
Fragment::new(self.into_iter().collect()).into_view(cx)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
||||
impl Mountable for Node {
|
||||
impl Mountable for View {
|
||||
fn get_mountable_node(&self) -> web_sys::Node {
|
||||
match self {
|
||||
Self::Element(element) => {
|
||||
|
@ -291,7 +291,7 @@ impl Mountable for Node {
|
|||
}
|
||||
}
|
||||
|
||||
impl Node {
|
||||
impl View {
|
||||
fn kind_name(&self) -> &'static str {
|
||||
match self {
|
||||
Self::Component(..) => "Component",
|
||||
|
@ -359,7 +359,7 @@ enum MountKind<'a> {
|
|||
pub fn mount_to_body<F, N>(f: F)
|
||||
where
|
||||
F: FnOnce(Scope) -> N + 'static,
|
||||
N: IntoNode,
|
||||
N: IntoView,
|
||||
{
|
||||
mount_to(crate::document().body().expect("body element to exist"), f)
|
||||
}
|
||||
|
@ -369,12 +369,12 @@ where
|
|||
pub fn mount_to<F, N>(parent: web_sys::HtmlElement, f: F)
|
||||
where
|
||||
F: FnOnce(Scope) -> N + 'static,
|
||||
N: IntoNode,
|
||||
N: IntoView,
|
||||
{
|
||||
let disposer = leptos_reactive::create_scope(
|
||||
leptos_reactive::create_runtime(),
|
||||
move |cx| {
|
||||
let node = f(cx).into_node(cx);
|
||||
let node = f(cx).into_view(cx);
|
||||
|
||||
parent.append_child(&node.get_mountable_node()).unwrap();
|
||||
|
||||
|
|
|
@ -1,62 +1,70 @@
|
|||
use std::{cell::{OnceCell, RefCell}, hash::Hash, rc::Rc};
|
||||
use crate::{
|
||||
text, Component, ComponentRepr, DynChild, EachKey, Element, Fragment,
|
||||
HtmlElement, IntoElement, IntoView, Text, Unit, View,
|
||||
};
|
||||
use cfg_if::cfg_if;
|
||||
use leptos_reactive::{Scope, create_effect};
|
||||
use crate::{IntoNode, ComponentRepr, EachKey, Node, HtmlElement, Text, Element, Fragment, Unit, text, DynChild, IntoElement, Component};
|
||||
use leptos_reactive::{create_effect, Scope};
|
||||
use std::{
|
||||
cell::{OnceCell, RefCell},
|
||||
hash::Hash,
|
||||
rc::Rc,
|
||||
};
|
||||
|
||||
pub enum Child {
|
||||
/// A (presumably reactive) function, which will be run inside an effect to do targeted updates to the node.
|
||||
Fn(Box<RefCell<dyn FnMut() -> Child>>),
|
||||
/// Content for a text node.
|
||||
Text(String),
|
||||
/// A generic node (a text node, comment, or element.)
|
||||
Node(Node),
|
||||
/// Nothing
|
||||
Unit
|
||||
/// A (presumably reactive) function, which will be run inside an effect to do targeted updates to the node.
|
||||
Fn(Box<RefCell<dyn FnMut() -> Child>>),
|
||||
/// Content for a text node.
|
||||
Text(String),
|
||||
/// A generic node (a text node, comment, or element.)
|
||||
Node(View),
|
||||
/// Nothing
|
||||
Unit,
|
||||
}
|
||||
|
||||
impl IntoNode for Child {
|
||||
fn into_node(self, cx: Scope) -> Node {
|
||||
match self {
|
||||
Child::Node(node) => node,
|
||||
Child::Unit => Unit.into_node(cx),
|
||||
Child::Text(data) => text(data),
|
||||
Child::Fn(f) => DynChild::new(move || {
|
||||
let mut value = (f.borrow_mut())();
|
||||
while let Child::Fn(f) = value {
|
||||
value = (f.borrow_mut())();
|
||||
}
|
||||
value.into_node(cx)
|
||||
}).into_node(cx)
|
||||
}
|
||||
impl IntoView for Child {
|
||||
fn into_view(self, cx: Scope) -> View {
|
||||
match self {
|
||||
Child::Node(node) => node,
|
||||
Child::Unit => Unit.into_view(cx),
|
||||
Child::Text(data) => text(data),
|
||||
Child::Fn(f) => DynChild::new(move || {
|
||||
let mut value = (f.borrow_mut())();
|
||||
while let Child::Fn(f) = value {
|
||||
value = (f.borrow_mut())();
|
||||
}
|
||||
value.into_view(cx)
|
||||
})
|
||||
.into_view(cx),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub trait IntoChild {
|
||||
fn into_child(self, cx: Scope) -> Child;
|
||||
fn into_child(self, cx: Scope) -> Child;
|
||||
}
|
||||
|
||||
impl IntoChild for Node {
|
||||
fn into_child(self, _cx: Scope) -> Child {
|
||||
Child::Node(self)
|
||||
}
|
||||
impl IntoChild for View {
|
||||
fn into_child(self, _cx: Scope) -> Child {
|
||||
Child::Node(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoChild for String {
|
||||
fn into_child(self, _cx: Scope) -> Child {
|
||||
Child::Text(self)
|
||||
}
|
||||
fn into_child(self, _cx: Scope) -> Child {
|
||||
Child::Text(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> IntoChild for Option<T>
|
||||
where
|
||||
T: IntoChild,
|
||||
T: IntoChild,
|
||||
{
|
||||
fn into_child(self, cx: Scope) -> Child {
|
||||
match self {
|
||||
Some(val) => val.into_child(cx),
|
||||
None => Child::Unit,
|
||||
}
|
||||
fn into_child(self, cx: Scope) -> Child {
|
||||
match self {
|
||||
Some(val) => val.into_child(cx),
|
||||
None => Child::Unit,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<IF, I, T, EF, N, KF, K> IntoChild for EachKey<IF, I, T, EF, N, KF, K>
|
||||
|
@ -64,68 +72,67 @@ where
|
|||
IF: Fn() -> I + 'static,
|
||||
I: IntoIterator<Item = T>,
|
||||
EF: Fn(T) -> N + 'static,
|
||||
N: IntoNode,
|
||||
N: IntoView,
|
||||
KF: Fn(&T) -> K + 'static,
|
||||
K: Eq + Hash + 'static,
|
||||
T: 'static,
|
||||
{
|
||||
fn into_child(self, cx: Scope) -> Child {
|
||||
Child::Node(self.into_node(cx))
|
||||
}
|
||||
{
|
||||
fn into_child(self, cx: Scope) -> Child {
|
||||
Child::Node(self.into_view(cx))
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, U> IntoChild for T
|
||||
where
|
||||
T: FnMut() -> U + 'static,
|
||||
U: IntoChild,
|
||||
T: FnMut() -> U + 'static,
|
||||
U: IntoChild,
|
||||
{
|
||||
fn into_child(mut self, cx: Scope) -> Child {
|
||||
let modified_fn = Box::new(RefCell::new(move || (self)().into_child(cx)));
|
||||
Child::Fn(modified_fn)
|
||||
}
|
||||
fn into_child(mut self, cx: Scope) -> Child {
|
||||
let modified_fn = Box::new(RefCell::new(move || (self)().into_child(cx)));
|
||||
Child::Fn(modified_fn)
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! node_type {
|
||||
($child_type:ty) => {
|
||||
impl IntoChild for $child_type {
|
||||
fn into_child(self, cx: Scope) -> Child {
|
||||
Child::Node(self.into_node(cx))
|
||||
}
|
||||
}
|
||||
};
|
||||
($child_type:ty) => {
|
||||
impl IntoChild for $child_type {
|
||||
fn into_child(self, cx: Scope) -> Child {
|
||||
Child::Node(self.into_view(cx))
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
node_type!(());
|
||||
node_type!(Element);
|
||||
node_type!(Text);
|
||||
node_type!(Vec<Node>);
|
||||
node_type!(Vec<View>);
|
||||
node_type!(Fragment);
|
||||
node_type!(ComponentRepr);
|
||||
|
||||
|
||||
impl<El: IntoElement> IntoChild for HtmlElement<El> {
|
||||
fn into_child(self, cx: Scope) -> Child {
|
||||
Child::Node(self.into_node(cx))
|
||||
}
|
||||
fn into_child(self, cx: Scope) -> Child {
|
||||
Child::Node(self.into_view(cx))
|
||||
}
|
||||
}
|
||||
|
||||
impl<F> IntoChild for Component<F>
|
||||
where
|
||||
F: FnOnce(Scope) -> Node,
|
||||
F: FnOnce(Scope) -> View,
|
||||
{
|
||||
fn into_child(self, cx: Scope) -> Child {
|
||||
Child::Node(self.into_node(cx))
|
||||
}
|
||||
fn into_child(self, cx: Scope) -> Child {
|
||||
Child::Node(self.into_view(cx))
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! text_type {
|
||||
($child_type:ty) => {
|
||||
impl IntoChild for $child_type {
|
||||
fn into_child(self, cx: Scope) -> Child {
|
||||
Child::Text(self.to_string().into())
|
||||
}
|
||||
}
|
||||
};
|
||||
($child_type:ty) => {
|
||||
impl IntoChild for $child_type {
|
||||
fn into_child(self, cx: Scope) -> Child {
|
||||
Child::Text(self.to_string().into())
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
text_type!(&String);
|
||||
|
@ -145,4 +152,4 @@ text_type!(i128);
|
|||
text_type!(f32);
|
||||
text_type!(f64);
|
||||
text_type!(char);
|
||||
text_type!(bool);
|
||||
text_type!(bool);
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
use leptos_reactive::{
|
||||
create_rw_signal, RwSignal, Scope
|
||||
};
|
||||
use leptos_reactive::{create_rw_signal, RwSignal, Scope};
|
||||
|
||||
/// Contains a shared reference to a DOM node creating while using the [view](leptos::view)
|
||||
/// Contains a shared reference to a DOM node creating while using the `view`
|
||||
/// macro to create your UI.
|
||||
///
|
||||
/// ```
|
||||
|
@ -34,27 +32,27 @@ use leptos_reactive::{
|
|||
pub struct NodeRef(RwSignal<Option<web_sys::Element>>);
|
||||
|
||||
impl NodeRef {
|
||||
/// Creates an empty reference.
|
||||
pub fn new(cx: Scope) -> Self {
|
||||
Self(create_rw_signal(cx, None))
|
||||
}
|
||||
/// Creates an empty reference.
|
||||
pub fn new(cx: Scope) -> Self {
|
||||
Self(create_rw_signal(cx, None))
|
||||
}
|
||||
|
||||
/// Gets the element that is currently stored in the reference.
|
||||
///
|
||||
/// This tracks reactively, so that node references can be used in effects.
|
||||
/// Initially, the value will be `None`, but once it is loaded the effect
|
||||
/// will rerun and its value will be `Some(Element)`.
|
||||
pub fn get(&self) -> Option<web_sys::Element> {
|
||||
self.0.get()
|
||||
}
|
||||
/// Gets the element that is currently stored in the reference.
|
||||
///
|
||||
/// This tracks reactively, so that node references can be used in effects.
|
||||
/// Initially, the value will be `None`, but once it is loaded the effect
|
||||
/// will rerun and its value will be `Some(Element)`.
|
||||
pub fn get(&self) -> Option<web_sys::Element> {
|
||||
self.0.get()
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
/// Loads an element into the reference. This tracks reactively,
|
||||
/// so that effects that use the node reference will rerun once it is loaded,
|
||||
/// i.e., effects can be forward-declared.
|
||||
pub fn load(&self, node: &web_sys::Element) {
|
||||
self.0.set(Some(node.clone()))
|
||||
}
|
||||
#[doc(hidden)]
|
||||
/// Loads an element into the reference. This tracks reactively,
|
||||
/// so that effects that use the node reference will rerun once it is loaded,
|
||||
/// i.e., effects can be forward-declared.
|
||||
pub fn load(&self, node: &web_sys::Element) {
|
||||
self.0.set(Some(node.clone()))
|
||||
}
|
||||
}
|
||||
|
||||
cfg_if::cfg_if! {
|
||||
|
|
Loading…
Reference in a new issue