Merge branch 'leptos_dom_v2' of https://github.com/jquesada2016/leptos into leptos_dom_v2
This commit is contained in:
commit
4a9f906571
|
@ -12,6 +12,7 @@ pub use fragment::*;
|
||||||
use leptos_reactive::Scope;
|
use leptos_reactive::Scope;
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
pub use unit::*;
|
pub use unit::*;
|
||||||
|
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
||||||
use wasm_bindgen::JsCast;
|
use wasm_bindgen::JsCast;
|
||||||
|
|
||||||
/// The core foundational leptos components.
|
/// The core foundational leptos components.
|
||||||
|
|
|
@ -1,8 +1,11 @@
|
||||||
use crate::{hydration::HydrationCtx, Comment, IntoView, View};
|
use crate::{hydration::HydrationCtx, Comment, IntoView, View};
|
||||||
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
||||||
use crate::{mount_child, MountKind, Mountable};
|
use crate::{mount_child, MountKind, Mountable};
|
||||||
use leptos_reactive::{create_effect, Scope, ScopeDisposer};
|
use leptos_reactive::Scope;
|
||||||
|
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
||||||
|
use leptos_reactive::{create_effect, ScopeDisposer};
|
||||||
use std::{borrow::Cow, cell::RefCell, rc::Rc};
|
use std::{borrow::Cow, cell::RefCell, rc::Rc};
|
||||||
|
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
||||||
use wasm_bindgen::JsCast;
|
use wasm_bindgen::JsCast;
|
||||||
|
|
||||||
/// The internal representation of the [`DynChild`] core-component.
|
/// The internal representation of the [`DynChild`] core-component.
|
||||||
|
|
|
@ -1,18 +1,20 @@
|
||||||
use crate::{hydration::HydrationCtx, Comment, CoreComponent, IntoView, View};
|
use crate::{hydration::HydrationCtx, Comment, CoreComponent, IntoView, View};
|
||||||
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
||||||
use crate::{mount_child, MountKind, Mountable, RANGE};
|
use crate::{mount_child, MountKind, Mountable, RANGE};
|
||||||
use leptos_reactive::{create_effect, Scope};
|
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
||||||
|
use leptos_reactive::create_effect;
|
||||||
|
use leptos_reactive::Scope;
|
||||||
|
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
||||||
use rustc_hash::FxHasher;
|
use rustc_hash::FxHasher;
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
use std::{
|
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
||||||
borrow::Cow,
|
use std::hash::BuildHasherDefault;
|
||||||
cell::RefCell,
|
use std::{borrow::Cow, cell::RefCell, hash::Hash, rc::Rc};
|
||||||
hash::{BuildHasherDefault, Hash},
|
|
||||||
rc::Rc,
|
|
||||||
};
|
|
||||||
use typed_builder::TypedBuilder;
|
use typed_builder::TypedBuilder;
|
||||||
|
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
||||||
use wasm_bindgen::JsCast;
|
use wasm_bindgen::JsCast;
|
||||||
|
|
||||||
|
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
||||||
type FxIndexSet<T> = indexmap::IndexSet<T, BuildHasherDefault<FxHasher>>;
|
type FxIndexSet<T> = indexmap::IndexSet<T, BuildHasherDefault<FxHasher>>;
|
||||||
|
|
||||||
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
||||||
|
@ -269,12 +271,14 @@ where
|
||||||
key_fn,
|
key_fn,
|
||||||
} = self;
|
} = self;
|
||||||
|
|
||||||
|
#[cfg(not(all(target_arch = "wasm32", feature = "web")))]
|
||||||
|
let _ = key_fn;
|
||||||
|
|
||||||
let component = EachRepr::default();
|
let component = EachRepr::default();
|
||||||
|
|
||||||
let children = component.children.clone();
|
|
||||||
|
|
||||||
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
||||||
let closing = component.closing.node.clone();
|
let (children, closing) =
|
||||||
|
(component.children.clone(), component.closing.node.clone());
|
||||||
|
|
||||||
cfg_if::cfg_if! {
|
cfg_if::cfg_if! {
|
||||||
if #[cfg(all(target_arch = "wasm32", feature = "web"))] {
|
if #[cfg(all(target_arch = "wasm32", feature = "web"))] {
|
||||||
|
@ -341,6 +345,7 @@ where
|
||||||
struct HashRun<T>(#[educe(Debug(ignore))] T);
|
struct HashRun<T>(#[educe(Debug(ignore))] T);
|
||||||
|
|
||||||
/// Calculates the operations need to get from `a` to `b`.
|
/// Calculates the operations need to get from `a` to `b`.
|
||||||
|
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
||||||
fn diff<K: Eq + Hash>(from: &FxIndexSet<K>, to: &FxIndexSet<K>) -> Diff {
|
fn diff<K: Eq + Hash>(from: &FxIndexSet<K>, to: &FxIndexSet<K>) -> Diff {
|
||||||
if from.is_empty() && to.is_empty() {
|
if from.is_empty() && to.is_empty() {
|
||||||
return Diff::default();
|
return Diff::default();
|
||||||
|
@ -428,6 +433,7 @@ fn diff<K: Eq + Hash>(from: &FxIndexSet<K>, to: &FxIndexSet<K>) -> Diff {
|
||||||
diffs
|
diffs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
||||||
fn apply_opts<K: Eq + Hash>(
|
fn apply_opts<K: Eq + Hash>(
|
||||||
from: &FxIndexSet<K>,
|
from: &FxIndexSet<K>,
|
||||||
to: &FxIndexSet<K>,
|
to: &FxIndexSet<K>,
|
||||||
|
@ -463,6 +469,7 @@ fn apply_opts<K: Eq + Hash>(
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
|
#[allow(unused)]
|
||||||
struct Diff {
|
struct Diff {
|
||||||
removed: SmallVec<[DiffOpRemove; 8]>,
|
removed: SmallVec<[DiffOpRemove; 8]>,
|
||||||
moved: SmallVec<[DiffOpMove; 8]>,
|
moved: SmallVec<[DiffOpMove; 8]>,
|
||||||
|
@ -471,6 +478,7 @@ struct Diff {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
#[allow(unused)]
|
||||||
struct DiffOpMove {
|
struct DiffOpMove {
|
||||||
from: usize,
|
from: usize,
|
||||||
to: usize,
|
to: usize,
|
||||||
|
@ -478,17 +486,20 @@ struct DiffOpMove {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
#[allow(unused)]
|
||||||
struct DiffOpAdd {
|
struct DiffOpAdd {
|
||||||
at: usize,
|
at: usize,
|
||||||
mode: DiffOpAddMode,
|
mode: DiffOpAddMode,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
#[allow(unused)]
|
||||||
struct DiffOpRemove {
|
struct DiffOpRemove {
|
||||||
at: usize,
|
at: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default, Debug)]
|
#[derive(Default, Debug)]
|
||||||
|
#[allow(unused)]
|
||||||
enum DiffOpAddMode {
|
enum DiffOpAddMode {
|
||||||
#[default]
|
#[default]
|
||||||
Normal,
|
Normal,
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
||||||
use crate::Mountable;
|
use crate::Mountable;
|
||||||
use crate::{hydration::HydrationCtx, Comment, CoreComponent, IntoView, View};
|
use crate::{hydration::HydrationCtx, Comment, CoreComponent, IntoView, View};
|
||||||
|
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
||||||
use wasm_bindgen::JsCast;
|
use wasm_bindgen::JsCast;
|
||||||
|
|
||||||
/// The internal representation of the [`Unit`] core-component.
|
/// The internal representation of the [`Unit`] core-component.
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
pub mod typed;
|
pub mod typed;
|
||||||
|
|
||||||
|
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
||||||
use crate::window;
|
use crate::window;
|
||||||
use std::{borrow::Cow, cell::RefCell, collections::HashSet};
|
use std::{borrow::Cow, cell::RefCell, collections::HashSet};
|
||||||
|
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
||||||
use wasm_bindgen::{
|
use wasm_bindgen::{
|
||||||
closure::Closure, convert::FromWasmAbi, intern, JsCast, JsValue,
|
convert::FromWasmAbi, intern, prelude::Closure, JsCast, JsValue,
|
||||||
UnwrapThrowExt,
|
UnwrapThrowExt,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -12,6 +14,7 @@ thread_local! {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Adds an event listener to the `Window`.
|
/// Adds an event listener to the `Window`.
|
||||||
|
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
||||||
pub fn window_event_listener(
|
pub fn window_event_listener(
|
||||||
event_name: &str,
|
event_name: &str,
|
||||||
cb: impl Fn(web_sys::Event) + 'static,
|
cb: impl Fn(web_sys::Event) + 'static,
|
||||||
|
@ -23,6 +26,7 @@ pub fn window_event_listener(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Adds an event listener to the target DOM element using implicit event delegation.
|
/// Adds an event listener to the target DOM element using implicit event delegation.
|
||||||
|
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
||||||
pub fn add_event_listener<E>(
|
pub fn add_event_listener<E>(
|
||||||
target: &web_sys::Element,
|
target: &web_sys::Element,
|
||||||
event_name: Cow<'static, str>,
|
event_name: Cow<'static, str>,
|
||||||
|
@ -37,6 +41,7 @@ pub fn add_event_listener<E>(
|
||||||
}
|
}
|
||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
|
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
||||||
pub fn add_event_listener_undelegated<E>(
|
pub fn add_event_listener_undelegated<E>(
|
||||||
target: &web_sys::Element,
|
target: &web_sys::Element,
|
||||||
event_name: &str,
|
event_name: &str,
|
||||||
|
@ -50,6 +55,7 @@ pub fn add_event_listener_undelegated<E>(
|
||||||
}
|
}
|
||||||
|
|
||||||
// cf eventHandler in ryansolid/dom-expressions
|
// cf eventHandler in ryansolid/dom-expressions
|
||||||
|
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
||||||
pub(crate) fn add_delegated_event_listener(event_name: Cow<'static, str>) {
|
pub(crate) fn add_delegated_event_listener(event_name: Cow<'static, str>) {
|
||||||
GLOBAL_EVENTS.with(|global_events| {
|
GLOBAL_EVENTS.with(|global_events| {
|
||||||
let mut events = global_events.borrow_mut();
|
let mut events = global_events.borrow_mut();
|
||||||
|
@ -113,6 +119,7 @@ pub(crate) fn add_delegated_event_listener(event_name: Cow<'static, str>) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
||||||
pub(crate) fn event_delegation_key(event_name: &str) -> String {
|
pub(crate) fn event_delegation_key(event_name: &str) -> String {
|
||||||
let event_name = intern(event_name);
|
let event_name = intern(event_name);
|
||||||
let mut n = String::from("$$$");
|
let mut n = String::from("$$$");
|
||||||
|
|
|
@ -1,11 +1,16 @@
|
||||||
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
||||||
use crate::events::*;
|
use crate::events::*;
|
||||||
|
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
||||||
|
use crate::macro_helpers::Property;
|
||||||
|
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
||||||
|
use crate::macro_helpers::{
|
||||||
|
attribute_expression, class_expression, property_expression,
|
||||||
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
ev::EventDescriptor,
|
ev::EventDescriptor,
|
||||||
hydration::HydrationCtx,
|
hydration::HydrationCtx,
|
||||||
macro_helpers::{
|
macro_helpers::{
|
||||||
attribute_expression, class_expression, property_expression, Attribute,
|
Attribute, Class, IntoAttribute, IntoChild, IntoClass, IntoProperty,
|
||||||
Class, IntoAttribute, IntoChild, IntoClass, IntoProperty, Property,
|
|
||||||
},
|
},
|
||||||
Element, Fragment, IntoView, NodeRef, Text, View,
|
Element, Fragment, IntoView, NodeRef, Text, View,
|
||||||
};
|
};
|
||||||
|
@ -15,10 +20,15 @@ use crate::{mount_child, MountKind};
|
||||||
use std::cell::OnceCell;
|
use std::cell::OnceCell;
|
||||||
|
|
||||||
use cfg_if::cfg_if;
|
use cfg_if::cfg_if;
|
||||||
use leptos_reactive::{create_render_effect, Scope};
|
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
||||||
|
use leptos_reactive::create_render_effect;
|
||||||
|
use leptos_reactive::Scope;
|
||||||
#[cfg(not(all(target_arch = "wasm32", feature = "web")))]
|
#[cfg(not(all(target_arch = "wasm32", feature = "web")))]
|
||||||
use smallvec::{smallvec, SmallVec};
|
use smallvec::{smallvec, SmallVec};
|
||||||
use std::{borrow::Cow, cell::LazyCell, fmt, ops::Deref};
|
use std::{borrow::Cow, fmt};
|
||||||
|
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
||||||
|
use std::{cell::LazyCell, ops::Deref};
|
||||||
|
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
||||||
use wasm_bindgen::JsCast;
|
use wasm_bindgen::JsCast;
|
||||||
|
|
||||||
/// Trait alias for the trait bounts on [`IntoElement`].
|
/// Trait alias for the trait bounts on [`IntoElement`].
|
||||||
|
@ -61,14 +71,45 @@ pub trait IntoElement: IntoElementBounds {
|
||||||
fn hydration_id(&self) -> usize;
|
fn hydration_id(&self) -> usize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Trait for converting [`web_sys::Element`] to [`HtmlElement`].
|
||||||
|
pub trait ToHtmlElement {
|
||||||
|
/// Converts the type to [`HtmlElement`].
|
||||||
|
fn to_leptos_element(self, cx: Scope) -> HtmlElement<AnyElement>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> ToHtmlElement for T
|
||||||
|
where
|
||||||
|
T: AsRef<web_sys::Element>,
|
||||||
|
{
|
||||||
|
fn to_leptos_element(self, cx: Scope) -> HtmlElement<AnyElement> {
|
||||||
|
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
||||||
|
{
|
||||||
|
let el = self.as_ref().clone().unchecked_into();
|
||||||
|
|
||||||
|
let element = AnyElement {
|
||||||
|
name: "".into(),
|
||||||
|
is_void: false,
|
||||||
|
element: el,
|
||||||
|
};
|
||||||
|
|
||||||
|
HtmlElement { cx, element }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(all(target_arch = "wasm32", feature = "web")))]
|
||||||
|
{
|
||||||
|
let _ = cx;
|
||||||
|
|
||||||
|
unreachable!();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Represents potentially any element.
|
/// Represents potentially any element.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
#[cfg_attr(all(target_arch = "wasm32", feature = "web"), derive(educe::Educe))]
|
#[cfg_attr(all(target_arch = "wasm32", feature = "web"), derive(educe::Educe))]
|
||||||
#[cfg_attr(all(target_arch = "wasm32", feature = "web"), educe(Deref))]
|
#[cfg_attr(all(target_arch = "wasm32", feature = "web"), educe(Deref))]
|
||||||
pub struct AnyElement {
|
pub struct AnyElement {
|
||||||
name: Cow<'static, str>,
|
name: Cow<'static, str>,
|
||||||
#[cfg(not(all(target_arch = "wasm32", feature = "web")))]
|
|
||||||
dynamic: bool,
|
|
||||||
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
||||||
#[educe(Deref)]
|
#[educe(Deref)]
|
||||||
element: web_sys::HtmlElement,
|
element: web_sys::HtmlElement,
|
||||||
|
@ -151,7 +192,6 @@ cfg_if! {
|
||||||
pub(crate) cx: Scope,
|
pub(crate) cx: Scope,
|
||||||
pub(crate) element: El,
|
pub(crate) element: El,
|
||||||
pub(crate) id: OnceCell<Cow<'static, str>>,
|
pub(crate) id: OnceCell<Cow<'static, str>>,
|
||||||
pub(crate) dynamic: bool,
|
|
||||||
#[educe(Debug(ignore))]
|
#[educe(Debug(ignore))]
|
||||||
pub(crate) attrs: SmallVec<[(Cow<'static, str>, Cow<'static, str>); 4]>,
|
pub(crate) attrs: SmallVec<[(Cow<'static, str>, Cow<'static, str>); 4]>,
|
||||||
#[educe(Debug(ignore))]
|
#[educe(Debug(ignore))]
|
||||||
|
@ -173,7 +213,6 @@ impl<El: IntoElement> HtmlElement<El> {
|
||||||
Self {
|
Self {
|
||||||
cx,
|
cx,
|
||||||
id: Default::default(),
|
id: Default::default(),
|
||||||
dynamic: false,
|
|
||||||
attrs: smallvec![],
|
attrs: smallvec![],
|
||||||
children: smallvec![],
|
children: smallvec![],
|
||||||
element,
|
element,
|
||||||
|
@ -203,7 +242,6 @@ impl<El: IntoElement> HtmlElement<El> {
|
||||||
let Self {
|
let Self {
|
||||||
cx,
|
cx,
|
||||||
id,
|
id,
|
||||||
dynamic,
|
|
||||||
attrs,
|
attrs,
|
||||||
children,
|
children,
|
||||||
element,
|
element,
|
||||||
|
@ -212,12 +250,10 @@ impl<El: IntoElement> HtmlElement<El> {
|
||||||
HtmlElement {
|
HtmlElement {
|
||||||
cx,
|
cx,
|
||||||
id,
|
id,
|
||||||
dynamic,
|
|
||||||
attrs,
|
attrs,
|
||||||
children,
|
children,
|
||||||
element: AnyElement {
|
element: AnyElement {
|
||||||
name: element.name(),
|
name: element.name(),
|
||||||
dynamic,
|
|
||||||
is_void: element.is_void(),
|
is_void: element.is_void(),
|
||||||
id: element.hydration_id(),
|
id: element.hydration_id(),
|
||||||
},
|
},
|
||||||
|
@ -257,6 +293,9 @@ impl<El: IntoElement> HtmlElement<El> {
|
||||||
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
||||||
node_ref.load(&self);
|
node_ref.load(&self);
|
||||||
|
|
||||||
|
#[cfg(not(all(target_arch = "wasm32", feature = "web")))]
|
||||||
|
let _ = node_ref;
|
||||||
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -295,7 +334,6 @@ impl<El: IntoElement> HtmlElement<El> {
|
||||||
|
|
||||||
let mut attr = attr.into_attribute(this.cx);
|
let mut attr = attr.into_attribute(this.cx);
|
||||||
while let Attribute::Fn(_, f) = attr {
|
while let Attribute::Fn(_, f) = attr {
|
||||||
this.dynamic = true;
|
|
||||||
attr = f();
|
attr = f();
|
||||||
}
|
}
|
||||||
match attr {
|
match attr {
|
||||||
|
@ -357,10 +395,7 @@ impl<El: IntoElement> HtmlElement<El> {
|
||||||
|
|
||||||
let include = match class {
|
let include = match class {
|
||||||
Class::Value(include) => include,
|
Class::Value(include) => include,
|
||||||
Class::Fn(_, f) => {
|
Class::Fn(_, f) => f(),
|
||||||
this.dynamic = true;
|
|
||||||
f()
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if include {
|
if include {
|
||||||
|
@ -408,17 +443,15 @@ impl<El: IntoElement> HtmlElement<El> {
|
||||||
property_expression(el, prop_name, value)
|
property_expression(el, prop_name, value)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
self
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(all(target_arch = "wasm32", feature = "web")))]
|
#[cfg(not(all(target_arch = "wasm32", feature = "web")))]
|
||||||
{
|
{
|
||||||
let mut this = self;
|
let _ = name;
|
||||||
|
let _ = value;
|
||||||
this.dynamic = true;
|
|
||||||
|
|
||||||
this
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Adds an event listener to this element.
|
/// Adds an event listener to this element.
|
||||||
|
@ -451,13 +484,10 @@ impl<El: IntoElement> HtmlElement<El> {
|
||||||
|
|
||||||
#[cfg(not(all(target_arch = "wasm32", feature = "web")))]
|
#[cfg(not(all(target_arch = "wasm32", feature = "web")))]
|
||||||
{
|
{
|
||||||
let mut this = self;
|
|
||||||
|
|
||||||
this.dynamic = true;
|
|
||||||
_ = event;
|
_ = event;
|
||||||
_ = event_handler;
|
_ = event_handler;
|
||||||
|
|
||||||
this
|
self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -499,7 +529,6 @@ impl<El: IntoElement> IntoView for HtmlElement<El> {
|
||||||
element,
|
element,
|
||||||
mut attrs,
|
mut attrs,
|
||||||
children,
|
children,
|
||||||
dynamic,
|
|
||||||
..
|
..
|
||||||
} = self;
|
} = self;
|
||||||
|
|
||||||
|
@ -514,7 +543,6 @@ impl<El: IntoElement> IntoView for HtmlElement<El> {
|
||||||
attrs.push(("id".into(), format!("_{}", id).into()));
|
attrs.push(("id".into(), format!("_{}", id).into()));
|
||||||
}
|
}
|
||||||
|
|
||||||
element.dynamic = dynamic;
|
|
||||||
element.attrs = attrs;
|
element.attrs = attrs;
|
||||||
element.children.extend(children);
|
element.children.extend(children);
|
||||||
|
|
||||||
|
@ -572,6 +600,7 @@ macro_rules! generate_html_tags {
|
||||||
),* $(,)?) => {
|
),* $(,)?) => {
|
||||||
paste::paste! {
|
paste::paste! {
|
||||||
$(
|
$(
|
||||||
|
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
||||||
#[thread_local]
|
#[thread_local]
|
||||||
static [<$tag:upper>]: LazyCell<web_sys::HtmlElement> = LazyCell::new(|| {
|
static [<$tag:upper>]: LazyCell<web_sys::HtmlElement> = LazyCell::new(|| {
|
||||||
crate::document()
|
crate::document()
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
|
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
||||||
use std::cell::LazyCell;
|
use std::cell::LazyCell;
|
||||||
|
|
||||||
/// We can tell if we start in hydration mode by checking to see if the
|
/// We can tell if we start in hydration mode by checking to see if the
|
||||||
/// id "_0" is present in the DOM. If it is, we know we are hydrating from
|
/// id "_0" is present in the DOM. If it is, we know we are hydrating from
|
||||||
/// the server, if not, we are starting off in CSR
|
/// the server, if not, we are starting off in CSR
|
||||||
|
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
||||||
#[thread_local]
|
#[thread_local]
|
||||||
static mut IS_HYDRATING: LazyCell<bool> = LazyCell::new(|| {
|
static mut IS_HYDRATING: LazyCell<bool> = LazyCell::new(|| {
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
|
@ -35,12 +37,14 @@ impl HydrationCtx {
|
||||||
unsafe { ID = 0 };
|
unsafe { ID = 0 };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
||||||
pub(crate) fn stop_hydrating() {
|
pub(crate) fn stop_hydrating() {
|
||||||
unsafe {
|
unsafe {
|
||||||
std::mem::take(&mut IS_HYDRATING);
|
std::mem::take(&mut IS_HYDRATING);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
||||||
pub(crate) fn is_hydrating() -> bool {
|
pub(crate) fn is_hydrating() -> bool {
|
||||||
unsafe { *IS_HYDRATING }
|
unsafe { *IS_HYDRATING }
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,11 +29,16 @@ pub use logging::*;
|
||||||
pub use node_ref::*;
|
pub use node_ref::*;
|
||||||
#[cfg(not(all(target_arch = "wasm32", feature = "web")))]
|
#[cfg(not(all(target_arch = "wasm32", feature = "web")))]
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
use std::{borrow::Cow, cell::LazyCell, fmt};
|
use std::borrow::Cow;
|
||||||
|
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
||||||
|
use std::{cell::LazyCell, fmt};
|
||||||
pub use wasm_bindgen;
|
pub use wasm_bindgen;
|
||||||
use wasm_bindgen::{JsCast, UnwrapThrowExt};
|
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
||||||
|
use wasm_bindgen::JsCast;
|
||||||
|
use wasm_bindgen::UnwrapThrowExt;
|
||||||
pub use web_sys;
|
pub use web_sys;
|
||||||
|
|
||||||
|
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
||||||
#[thread_local]
|
#[thread_local]
|
||||||
static COMMENT: LazyCell<web_sys::Node> =
|
static COMMENT: LazyCell<web_sys::Node> =
|
||||||
LazyCell::new(|| document().create_comment("").unchecked_into());
|
LazyCell::new(|| document().create_comment("").unchecked_into());
|
||||||
|
@ -128,7 +133,6 @@ cfg_if! {
|
||||||
pub struct Element {
|
pub struct Element {
|
||||||
name: Cow<'static, str>,
|
name: Cow<'static, str>,
|
||||||
is_void: bool,
|
is_void: bool,
|
||||||
dynamic: bool,
|
|
||||||
attrs: SmallVec<[(Cow<'static, str>, Cow<'static, str>); 4]>,
|
attrs: SmallVec<[(Cow<'static, str>, Cow<'static, str>); 4]>,
|
||||||
children: Vec<View>,
|
children: Vec<View>,
|
||||||
id: usize,
|
id: usize,
|
||||||
|
@ -158,7 +162,6 @@ impl Element {
|
||||||
Self {
|
Self {
|
||||||
name: el.name(),
|
name: el.name(),
|
||||||
is_void: el.is_void(),
|
is_void: el.is_void(),
|
||||||
dynamic: false,
|
|
||||||
attrs: Default::default(),
|
attrs: Default::default(),
|
||||||
children: Default::default(),
|
children: Default::default(),
|
||||||
id: el.hydration_id(),
|
id: el.hydration_id(),
|
||||||
|
@ -183,6 +186,12 @@ impl Comment {
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let content = content.into();
|
let content = content.into();
|
||||||
|
|
||||||
|
#[cfg(not(all(target_arch = "wasm32", feature = "web")))]
|
||||||
|
{
|
||||||
|
let _ = id;
|
||||||
|
let _ = closing;
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
||||||
let node = COMMENT.clone_node().unwrap();
|
let node = COMMENT.clone_node().unwrap();
|
||||||
|
|
||||||
|
@ -339,6 +348,7 @@ impl View {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
||||||
fn get_text(&self) -> Option<&Text> {
|
fn get_text(&self) -> Option<&Text> {
|
||||||
if let Self::Text(t) = self {
|
if let Self::Text(t) = self {
|
||||||
Some(t)
|
Some(t)
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
use leptos_reactive::Scope;
|
use leptos_reactive::Scope;
|
||||||
|
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
||||||
use wasm_bindgen::UnwrapThrowExt;
|
use wasm_bindgen::UnwrapThrowExt;
|
||||||
|
|
||||||
/// Represents the different possible values an attribute node could have.
|
/// Represents the different possible values an attribute node could have.
|
||||||
|
@ -146,6 +147,7 @@ attr_type!(f32);
|
||||||
attr_type!(f64);
|
attr_type!(f64);
|
||||||
attr_type!(char);
|
attr_type!(char);
|
||||||
|
|
||||||
|
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
||||||
pub fn attribute_expression(
|
pub fn attribute_expression(
|
||||||
el: &web_sys::Element,
|
el: &web_sys::Element,
|
||||||
attr_name: &str,
|
attr_name: &str,
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
use leptos_reactive::Scope;
|
use leptos_reactive::Scope;
|
||||||
|
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
||||||
use wasm_bindgen::UnwrapThrowExt;
|
use wasm_bindgen::UnwrapThrowExt;
|
||||||
|
|
||||||
/// Represents the different possible values a single class on an element could have,
|
/// Represents the different possible values a single class on an element could have,
|
||||||
|
@ -65,6 +66,7 @@ impl<T: IntoClass> IntoClass for (Scope, T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
||||||
pub fn class_expression(
|
pub fn class_expression(
|
||||||
class_list: &web_sys::DomTokenList,
|
class_list: &web_sys::DomTokenList,
|
||||||
class_name: &str,
|
class_name: &str,
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
use leptos_reactive::Scope;
|
use leptos_reactive::Scope;
|
||||||
use wasm_bindgen::{JsValue, UnwrapThrowExt};
|
use wasm_bindgen::JsValue;
|
||||||
|
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
||||||
|
use wasm_bindgen::UnwrapThrowExt;
|
||||||
|
|
||||||
/// Represents the different possible values an element property could have,
|
/// Represents the different possible values an element property could have,
|
||||||
/// allowing you to do fine-grained updates to single fields.
|
/// allowing you to do fine-grained updates to single fields.
|
||||||
|
@ -74,6 +76,7 @@ prop_type!(f32);
|
||||||
prop_type!(f64);
|
prop_type!(f64);
|
||||||
prop_type!(bool);
|
prop_type!(bool);
|
||||||
|
|
||||||
|
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
||||||
pub fn property_expression(
|
pub fn property_expression(
|
||||||
el: &web_sys::Element,
|
el: &web_sys::Element,
|
||||||
prop_name: &str,
|
prop_name: &str,
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
use crate::{CoreComponent, HydrationCtx, View};
|
use crate::{CoreComponent, HydrationCtx, View};
|
||||||
use cfg_if::cfg_if;
|
use cfg_if::cfg_if;
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use std::{borrow::Cow, fmt::Display};
|
use std::borrow::Cow;
|
||||||
|
|
||||||
impl View {
|
impl View {
|
||||||
/// Consumes the node and renders it into an HTML string.
|
/// Consumes the node and renders it into an HTML string.
|
||||||
|
@ -123,17 +123,14 @@ impl View {
|
||||||
}
|
}
|
||||||
View::Element(el) => {
|
View::Element(el) => {
|
||||||
let tag_name = el.name;
|
let tag_name = el.name;
|
||||||
let mut has_id = false;
|
|
||||||
let mut attrs = el
|
let attrs = el
|
||||||
.attrs
|
.attrs
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|(name, value)| -> Cow<'static, str> {
|
.map(|(name, value)| -> Cow<'static, str> {
|
||||||
if value.is_empty() {
|
if value.is_empty() {
|
||||||
format!(" {name}").into()
|
format!(" {name}").into()
|
||||||
} else {
|
} else {
|
||||||
if name == "id" {
|
|
||||||
has_id = true;
|
|
||||||
}
|
|
||||||
format!(
|
format!(
|
||||||
" {name}=\"{}\"",
|
" {name}=\"{}\"",
|
||||||
html_escape::encode_double_quoted_attribute(&value)
|
html_escape::encode_double_quoted_attribute(&value)
|
||||||
|
@ -143,10 +140,6 @@ impl View {
|
||||||
})
|
})
|
||||||
.join("");
|
.join("");
|
||||||
|
|
||||||
if !has_id && el.dynamic {
|
|
||||||
attrs.push_str(&format!(" id=\"_{}\"", el.id));
|
|
||||||
}
|
|
||||||
|
|
||||||
if el.is_void {
|
if el.is_void {
|
||||||
format!("<{tag_name}{attrs}/>").into()
|
format!("<{tag_name}{attrs}/>").into()
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Reference in New Issue