mirror of
https://github.com/leptos-rs/leptos
synced 2024-11-10 06:44:17 +00:00
Sorting out all sorts of feature flags etc. so everything will build and test
This commit is contained in:
parent
51142ad894
commit
db69145fd9
23 changed files with 133 additions and 165 deletions
|
@ -20,7 +20,6 @@ members = [
|
|||
"examples/counters",
|
||||
"examples/counters-stable",
|
||||
"examples/fetch",
|
||||
"examples/gtk",
|
||||
"examples/hackernews/hackernews-app",
|
||||
"examples/hackernews/hackernews-client",
|
||||
"examples/hackernews/hackernews-server",
|
||||
|
@ -31,11 +30,13 @@ members = [
|
|||
"examples/todomvc-ssr/todomvc-ssr-server",
|
||||
]
|
||||
exclude = [
|
||||
"benchmarks"
|
||||
"benchmarks",
|
||||
# not gonna lie, this is because my arm64 mac fails when linking a GTK binary
|
||||
"examples/gtk",
|
||||
]
|
||||
|
||||
|
||||
[profile.release]
|
||||
codegen-units = 1
|
||||
lto = true
|
||||
opt-level = 'z'
|
||||
opt-level = 'z'
|
||||
|
|
|
@ -6,12 +6,14 @@ edition = "2021"
|
|||
[dependencies]
|
||||
anyhow = "1"
|
||||
console_log = "0.2"
|
||||
leptos = { path = "../../../leptos", default-features = false, features = ["serde"] }
|
||||
leptos = { path = "../../../leptos", default-features = false, features = [
|
||||
"serde",
|
||||
] }
|
||||
leptos_meta = { path = "../../../meta", default-features = false }
|
||||
leptos_router = { path = "../../../router", default-features = false }
|
||||
log = "0.4"
|
||||
gloo-net = { version = "0.2", features = ["http"] }
|
||||
reqwest = { version = "0.11", features = ["json"], optional = true }
|
||||
reqwest = { version = "0.11", features = ["json"] }
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
serde_json = "1"
|
||||
console_error_panic_hook = "0.1.7"
|
||||
|
@ -21,4 +23,4 @@ console_error_panic_hook = "0.1.7"
|
|||
default = ["csr"]
|
||||
csr = ["leptos/csr", "leptos_meta/csr", "leptos_router/csr"]
|
||||
hydrate = ["leptos/hydrate", "leptos_meta/hydrate", "leptos_router/hydrate"]
|
||||
ssr = ["leptos/ssr", "leptos_meta/ssr", "leptos_router/ssr", "dep:reqwest"]
|
||||
ssr = ["leptos/ssr", "leptos_meta/ssr", "leptos_router/ssr"]
|
||||
|
|
|
@ -123,15 +123,3 @@ pub use leptos_server;
|
|||
pub use leptos_server::*;
|
||||
|
||||
pub use leptos_reactive::debug_warn;
|
||||
|
||||
#[cfg(not(any(feature = "csr", feature = "ssr", feature = "hydrate")))]
|
||||
compile_error!("set one of the following feature flags: 'csr', 'ssr' or 'hydrate'");
|
||||
|
||||
#[cfg(all(feature = "csr", feature = "ssr"))]
|
||||
compile_error!("leptos features 'csr' and feature 'ssr' cannot be enabled at the same time");
|
||||
|
||||
#[cfg(all(feature = "csr", feature = "hydrate"))]
|
||||
compile_error!("leptos features 'csr' and feature 'hydrate' cannot be enabled at the same time");
|
||||
|
||||
#[cfg(all(feature = "hydrate", feature = "ssr"))]
|
||||
compile_error!("leptos features 'hydrate' and feature 'ssr' cannot be enabled at the same time");
|
||||
|
|
|
@ -1,15 +1,9 @@
|
|||
#[cfg(any(feature = "csr", feature = "hydrate", feature = "ssr"))]
|
||||
mod for_component;
|
||||
#[cfg(any(feature = "csr", feature = "hydrate", feature = "ssr"))]
|
||||
mod map;
|
||||
#[cfg(any(feature = "csr", feature = "hydrate", feature = "ssr"))]
|
||||
mod suspense;
|
||||
|
||||
#[cfg(any(feature = "csr", feature = "hydrate", feature = "ssr"))]
|
||||
pub use for_component::*;
|
||||
#[cfg(any(feature = "csr", feature = "hydrate", feature = "ssr"))]
|
||||
pub use map::*;
|
||||
#[cfg(any(feature = "csr", feature = "hydrate", feature = "ssr"))]
|
||||
pub use suspense::*;
|
||||
|
||||
pub trait Prop {
|
||||
|
|
|
@ -15,7 +15,6 @@ where
|
|||
}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
#[cfg(any(feature = "csr", feature = "hydrate", feature = "ssr"))]
|
||||
pub fn Suspense<F, E, G>(cx: Scope, props: SuspenseProps<F, E, G>) -> impl Fn() -> Child
|
||||
where
|
||||
F: IntoChild + Clone,
|
||||
|
@ -32,17 +31,7 @@ where
|
|||
render_suspense(cx, context, props.fallback.clone(), child)
|
||||
}
|
||||
|
||||
#[cfg(not(any(feature = "csr", feature = "hydrate", feature = "ssr")))]
|
||||
pub fn Suspense<F, E, G>(cx: Scope, props: SuspenseProps<F, E, G>) -> impl Fn() -> Child
|
||||
where
|
||||
F: IntoChild + Clone,
|
||||
E: IntoChild,
|
||||
G: Fn() -> E + 'static,
|
||||
{
|
||||
compile_error!("<Suspense/> can only be used when one of the following features is set on the `leptos` package: 'csr', 'ssr', or 'hydrate'");
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "ssr"))]
|
||||
#[cfg(any(feature = "csr", feature = "hydrate"))]
|
||||
fn render_suspense<'a, F, E, G>(
|
||||
cx: Scope,
|
||||
context: SuspenseContext,
|
||||
|
@ -69,7 +58,7 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "ssr")]
|
||||
#[cfg(not(any(feature = "csr", feature = "hydrate")))]
|
||||
fn render_suspense<'a, F, E, G>(
|
||||
cx: Scope,
|
||||
context: SuspenseContext,
|
||||
|
|
|
@ -177,19 +177,19 @@ cfg_if! {
|
|||
if #[cfg(feature = "stable")] {
|
||||
use leptos_reactive::{Memo, ReadSignal, RwSignal};
|
||||
|
||||
impl IntoChild for Memo<Vec<Element>> {
|
||||
impl IntoChild for Memo<Vec<crate::Element>> {
|
||||
fn into_child(self, cx: Scope) -> Child {
|
||||
(move || self.get()).into_child(cx)
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoChild for ReadSignal<Vec<Element>> {
|
||||
impl IntoChild for ReadSignal<Vec<crate::Element>> {
|
||||
fn into_child(self, cx: Scope) -> Child {
|
||||
(move || self.get()).into_child(cx)
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoChild for RwSignal<Vec<Element>> {
|
||||
impl IntoChild for RwSignal<Vec<crate::Element>> {
|
||||
fn into_child(self, cx: Scope) -> Child {
|
||||
(move || self.get()).into_child(cx)
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ pub mod child;
|
|||
pub mod class;
|
||||
pub mod event_delegation;
|
||||
pub mod logging;
|
||||
pub mod mount;
|
||||
pub mod operations;
|
||||
pub mod property;
|
||||
|
||||
|
@ -21,11 +22,9 @@ cfg_if! {
|
|||
pub type Element = web_sys::Element;
|
||||
pub type Node = web_sys::Node;
|
||||
|
||||
pub mod mount;
|
||||
pub mod reconcile;
|
||||
pub mod render;
|
||||
|
||||
pub use mount::*;
|
||||
pub use reconcile::*;
|
||||
pub use render::*;
|
||||
}
|
||||
|
@ -35,6 +34,7 @@ pub use attribute::*;
|
|||
pub use child::*;
|
||||
pub use class::*;
|
||||
pub use logging::*;
|
||||
pub use mount::*;
|
||||
pub use operations::*;
|
||||
pub use property::*;
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use crate::{document, Element};
|
||||
use cfg_if::cfg_if;
|
||||
use leptos_reactive::Scope;
|
||||
use wasm_bindgen::UnwrapThrowExt;
|
||||
|
||||
|
@ -8,14 +9,22 @@ pub trait Mountable {
|
|||
|
||||
impl Mountable for Element {
|
||||
fn mount(&self, parent: &web_sys::Element) {
|
||||
parent.append_child(self).unwrap_throw();
|
||||
cfg_if! {
|
||||
if #[cfg(any(feature = "csr", feature = "hydrate"))] {
|
||||
parent.append_child(self).unwrap_throw();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Mountable for Vec<Element> {
|
||||
fn mount(&self, parent: &web_sys::Element) {
|
||||
for element in self {
|
||||
parent.append_child(element).unwrap_throw();
|
||||
cfg_if! {
|
||||
if #[cfg(any(feature = "csr", feature = "hydrate"))] {
|
||||
for element in self {
|
||||
parent.append_child(element).unwrap_throw();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -84,7 +84,6 @@ impl SharedContext {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "ssr")]
|
||||
pub fn current_fragment_key(&self) -> String {
|
||||
if let Some(context) = &self.context {
|
||||
format!("{}{}f", context.id, context.count)
|
||||
|
|
|
@ -561,7 +561,6 @@ where
|
|||
});
|
||||
}
|
||||
|
||||
#[cfg(feature = "ssr")]
|
||||
pub fn resource_to_serialization_resolver(
|
||||
&self,
|
||||
id: ResourceId,
|
||||
|
@ -585,7 +584,6 @@ pub(crate) enum AnyResource {
|
|||
pub(crate) trait SerializableResource {
|
||||
fn as_any(&self) -> &dyn Any;
|
||||
|
||||
#[cfg(feature = "ssr")]
|
||||
fn to_serialization_resolver(
|
||||
&self,
|
||||
id: ResourceId,
|
||||
|
@ -601,7 +599,6 @@ where
|
|||
self
|
||||
}
|
||||
|
||||
#[cfg(feature = "ssr")]
|
||||
fn to_serialization_resolver(
|
||||
&self,
|
||||
id: ResourceId,
|
||||
|
|
|
@ -3,25 +3,20 @@ use crate::{
|
|||
EffectId, Memo, ReadSignal, ResourceId, ResourceState, RwSignal, Scope, ScopeDisposer, ScopeId,
|
||||
ScopeProperty, SignalId, WriteSignal,
|
||||
};
|
||||
use cfg_if::cfg_if;
|
||||
use futures::stream::FuturesUnordered;
|
||||
use slotmap::{SecondaryMap, SlotMap, SparseSecondaryMap};
|
||||
use std::{
|
||||
any::{Any, TypeId},
|
||||
cell::{Cell, RefCell},
|
||||
collections::{HashMap, HashSet},
|
||||
fmt::Debug,
|
||||
future::Future,
|
||||
marker::PhantomData,
|
||||
pin::Pin,
|
||||
rc::Rc,
|
||||
};
|
||||
|
||||
cfg_if! {
|
||||
if #[cfg(feature = "ssr")] {
|
||||
use std::{future::Future, pin::Pin};
|
||||
use futures::stream::FuturesUnordered;
|
||||
|
||||
pub(crate) type PinnedFuture<T> = Pin<Box<dyn Future<Output = T>>>;
|
||||
}
|
||||
}
|
||||
pub(crate) type PinnedFuture<T> = Pin<Box<dyn Future<Output = T>>>;
|
||||
|
||||
#[derive(Default)]
|
||||
pub(crate) struct Runtime {
|
||||
|
@ -255,7 +250,6 @@ impl Runtime {
|
|||
.collect()
|
||||
}
|
||||
|
||||
#[cfg(feature = "ssr")]
|
||||
pub(crate) fn serialization_resolvers(
|
||||
&self,
|
||||
) -> FuturesUnordered<PinnedFuture<(ResourceId, String)>> {
|
||||
|
|
|
@ -1,15 +1,11 @@
|
|||
use cfg_if::cfg_if;
|
||||
|
||||
use crate::{hydration::SharedContext, EffectId, ResourceId, Runtime, SignalId};
|
||||
use crate::{PinnedFuture, SuspenseContext};
|
||||
use futures::stream::FuturesUnordered;
|
||||
use std::collections::HashMap;
|
||||
use std::fmt::Debug;
|
||||
|
||||
cfg_if! {
|
||||
if #[cfg(feature = "ssr")] {
|
||||
use crate::{PinnedFuture, SuspenseContext};
|
||||
use futures::stream::FuturesUnordered;
|
||||
use std::{collections::HashMap, future::Future, pin::Pin};
|
||||
}
|
||||
}
|
||||
use std::{future::Future, pin::Pin};
|
||||
|
||||
#[must_use = "Scope will leak memory if the disposer function is never called"]
|
||||
/// Creates a child reactive scope and runs the function within it. This is useful for applications
|
||||
|
@ -333,58 +329,54 @@ impl Scope {
|
|||
self.runtime.all_resources()
|
||||
}
|
||||
|
||||
cfg_if! {
|
||||
if #[cfg(feature = "ssr")] {
|
||||
/// Returns IDs for all [Resource](crate::Resource)s found on any scope.
|
||||
pub fn serialization_resolvers(&self) -> FuturesUnordered<PinnedFuture<(ResourceId, String)>> {
|
||||
self.runtime.serialization_resolvers()
|
||||
}
|
||||
pub fn current_fragment_key(&self) -> String {
|
||||
self.runtime
|
||||
.shared_context
|
||||
.borrow()
|
||||
.as_ref()
|
||||
.map(|context| context.current_fragment_key())
|
||||
.unwrap_or_else(|| String::from("0f"))
|
||||
}
|
||||
|
||||
pub fn current_fragment_key(&self) -> String {
|
||||
self.runtime
|
||||
.shared_context
|
||||
.borrow()
|
||||
.as_ref()
|
||||
.map(|context| context.current_fragment_key())
|
||||
.unwrap_or_else(|| String::from("0f"))
|
||||
}
|
||||
/// Returns IDs for all [Resource](crate::Resource)s found on any scope.
|
||||
pub fn serialization_resolvers(&self) -> FuturesUnordered<PinnedFuture<(ResourceId, String)>> {
|
||||
self.runtime.serialization_resolvers()
|
||||
}
|
||||
|
||||
pub fn register_suspense(
|
||||
&self,
|
||||
context: SuspenseContext,
|
||||
key: &str,
|
||||
resolver: impl FnOnce() -> String + 'static,
|
||||
) {
|
||||
use crate::create_isomorphic_effect;
|
||||
use futures::StreamExt;
|
||||
pub fn register_suspense(
|
||||
&self,
|
||||
context: SuspenseContext,
|
||||
key: &str,
|
||||
resolver: impl FnOnce() -> String + 'static,
|
||||
) {
|
||||
use crate::create_isomorphic_effect;
|
||||
use futures::StreamExt;
|
||||
|
||||
if let Some(ref mut shared_context) = *self.runtime.shared_context.borrow_mut() {
|
||||
let (mut tx, mut rx) = futures::channel::mpsc::channel::<()>(1);
|
||||
if let Some(ref mut shared_context) = *self.runtime.shared_context.borrow_mut() {
|
||||
let (mut tx, mut rx) = futures::channel::mpsc::channel::<()>(1);
|
||||
|
||||
create_isomorphic_effect(*self, move |_| {
|
||||
let pending = context.pending_resources.try_with(|n| *n).unwrap_or(0);
|
||||
if pending == 0 {
|
||||
_ = tx.try_send(());
|
||||
}
|
||||
});
|
||||
|
||||
shared_context.pending_fragments.insert(
|
||||
key.to_string(),
|
||||
Box::pin(async move {
|
||||
rx.next().await;
|
||||
resolver()
|
||||
}),
|
||||
);
|
||||
create_isomorphic_effect(*self, move |_| {
|
||||
let pending = context.pending_resources.try_with(|n| *n).unwrap_or(0);
|
||||
if pending == 0 {
|
||||
_ = tx.try_send(());
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
pub fn pending_fragments(&self) -> HashMap<String, Pin<Box<dyn Future<Output = String>>>> {
|
||||
if let Some(ref mut shared_context) = *self.runtime.shared_context.borrow_mut() {
|
||||
std::mem::take(&mut shared_context.pending_fragments)
|
||||
} else {
|
||||
HashMap::new()
|
||||
}
|
||||
}
|
||||
shared_context.pending_fragments.insert(
|
||||
key.to_string(),
|
||||
Box::pin(async move {
|
||||
rx.next().await;
|
||||
resolver()
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn pending_fragments(&self) -> HashMap<String, Pin<Box<dyn Future<Output = String>>>> {
|
||||
if let Some(ref mut shared_context) = *self.runtime.shared_context.borrow_mut() {
|
||||
std::mem::take(&mut shared_context.pending_fragments)
|
||||
} else {
|
||||
HashMap::new()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,14 +7,14 @@ edition = "2021"
|
|||
leptos_dom = { path = "../leptos_dom", default-features = false, version = "0.0.11" }
|
||||
leptos_reactive = { path = "../leptos_reactive", default-features = false, version = "0.0.11" }
|
||||
form_urlencoded = "1"
|
||||
gloo-net = { version = "0.2", optional = true }
|
||||
gloo-net = "0.2"
|
||||
lazy_static = "1"
|
||||
linear-map = "1"
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
thiserror = "1"
|
||||
|
||||
[features]
|
||||
csr = ["leptos_dom/csr", "leptos_reactive/csr", "dep:gloo-net"]
|
||||
hydrate = ["leptos_dom/hydrate", "leptos_reactive/hydrate", "dep:gloo-net"]
|
||||
csr = ["leptos_dom/csr", "leptos_reactive/csr"]
|
||||
hydrate = ["leptos_dom/hydrate", "leptos_reactive/hydrate"]
|
||||
ssr = ["leptos_dom/ssr", "leptos_reactive/ssr"]
|
||||
stable = ["leptos_dom/stable", "leptos_reactive/stable"]
|
||||
|
|
|
@ -69,7 +69,7 @@
|
|||
|
||||
pub use form_urlencoded;
|
||||
use leptos_reactive::*;
|
||||
use serde::{de::DeserializeOwned, Deserialize, Serialize};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::{future::Future, pin::Pin, rc::Rc};
|
||||
use thiserror::Error;
|
||||
|
||||
|
@ -174,7 +174,7 @@ pub enum ServerFnError {
|
|||
MissingArg(String),
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "csr", feature = "hydrate"))]
|
||||
#[cfg(not(feature = "ssr"))]
|
||||
pub async fn call_server_fn<T>(url: &str, args: impl ServerFn) -> Result<T, ServerFnError>
|
||||
where
|
||||
T: Serializable + Sized,
|
||||
|
|
|
@ -9,6 +9,7 @@ description = "Router for the Leptos web framework."
|
|||
|
||||
[dependencies]
|
||||
leptos = { path = "../leptos", version = "0.0", default-features = false }
|
||||
cfg-if = "1"
|
||||
common_macros = "0.1"
|
||||
gloo-net = "0.2"
|
||||
itertools = "0.10"
|
||||
|
@ -21,9 +22,9 @@ url = { version = "2", optional = true }
|
|||
urlencoding = "2"
|
||||
thiserror = "1"
|
||||
typed-builder = "0.10"
|
||||
js-sys = { version = "0.3", optional = true }
|
||||
wasm-bindgen = { version = "0.2", optional = true }
|
||||
wasm-bindgen-futures = { version = "0.4", optional = true }
|
||||
js-sys = { version = "0.3" }
|
||||
wasm-bindgen = { version = "0.2" }
|
||||
wasm-bindgen-futures = { version = "0.4" }
|
||||
|
||||
[dependencies.web-sys]
|
||||
version = "0.3"
|
||||
|
@ -51,12 +52,7 @@ features = [
|
|||
]
|
||||
|
||||
[features]
|
||||
default = ["csr"]
|
||||
csr = ["leptos/csr", "dep:js-sys", "dep:wasm-bindgen"]
|
||||
hydrate = [
|
||||
"leptos/hydrate",
|
||||
"dep:js-sys",
|
||||
"dep:wasm-bindgen",
|
||||
"dep:wasm-bindgen-futures",
|
||||
]
|
||||
default = []
|
||||
csr = ["leptos/csr"]
|
||||
hydrate = ["leptos/hydrate"]
|
||||
ssr = ["leptos/ssr", "dep:url", "dep:regex"]
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
use cfg_if::cfg_if;
|
||||
use leptos::leptos_dom::IntoChild;
|
||||
use leptos::*;
|
||||
use typed_builder::TypedBuilder;
|
||||
|
@ -89,14 +90,27 @@ where
|
|||
}
|
||||
let child = children.remove(0);
|
||||
|
||||
view! { cx,
|
||||
<a
|
||||
href=move || href().unwrap_or_default()
|
||||
prop:state={props.state.map(|s| s.to_js_value())}
|
||||
prop:replace={props.replace}
|
||||
aria-current=move || if is_active() { Some("page") } else { None }
|
||||
>
|
||||
{child}
|
||||
</a>
|
||||
cfg_if! {
|
||||
if #[cfg(any(feature = "csr", feature = "hydrate"))] {
|
||||
view! { cx,
|
||||
<a
|
||||
href=move || href().unwrap_or_default()
|
||||
prop:state={props.state.map(|s| s.to_js_value())}
|
||||
prop:replace={props.replace}
|
||||
aria-current=move || if is_active() { Some("page") } else { None }
|
||||
>
|
||||
{child}
|
||||
</a>
|
||||
}
|
||||
} else {
|
||||
view! { cx,
|
||||
<a
|
||||
href=move || href().unwrap_or_default()
|
||||
aria-current=move || if is_active() { Some("page") } else { None }
|
||||
>
|
||||
{child}
|
||||
</a>
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
use cfg_if::cfg_if;
|
||||
use std::ops::IndexMut;
|
||||
use std::{cell::RefCell, rc::Rc};
|
||||
|
||||
|
@ -72,11 +73,14 @@ impl std::fmt::Debug for RouterContextInner {
|
|||
|
||||
impl RouterContext {
|
||||
pub fn new(cx: Scope, base: Option<&'static str>, fallback: Option<fn() -> Element>) -> Self {
|
||||
#[cfg(any(feature = "csr", feature = "hydrate"))]
|
||||
let history = use_context::<RouterIntegrationContext>(cx)
|
||||
.unwrap_or_else(|| RouterIntegrationContext(Rc::new(crate::BrowserIntegration {})));
|
||||
#[cfg(not(any(feature = "csr", feature = "hydrate")))]
|
||||
let history = use_context::<RouterIntegrationContext>(cx).expect("You must call provide_context::<RouterIntegrationContext>(cx, ...) somewhere above the <Router/>.");
|
||||
cfg_if! {
|
||||
if #[cfg(any(feature = "csr", feature = "hydrate"))] {
|
||||
let history = use_context::<RouterIntegrationContext>(cx)
|
||||
.unwrap_or_else(|| RouterIntegrationContext(Rc::new(crate::BrowserIntegration {})));
|
||||
} else {
|
||||
let history = use_context::<RouterIntegrationContext>(cx).expect("You must call provide_context::<RouterIntegrationContext>(cx, ...) somewhere above the <Router/>.");
|
||||
}
|
||||
};
|
||||
|
||||
// Any `History` type gives a way to get a reactive signal of the current location
|
||||
// in the browser context, this is drawn from the `popstate` event
|
||||
|
@ -143,7 +147,7 @@ impl RouterContext {
|
|||
});
|
||||
|
||||
// handle all click events on anchor tags
|
||||
#[cfg(any(feature = "csr", feature = "hydrate"))]
|
||||
#[cfg(not(feature = "ssr"))]
|
||||
leptos_dom::window_event_listener("click", {
|
||||
let inner = Rc::clone(&inner);
|
||||
move |ev| inner.clone().handle_anchor_click(ev)
|
||||
|
@ -253,7 +257,7 @@ impl RouterContextInner {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "csr", feature = "hydrate"))]
|
||||
#[cfg(not(feature = "ssr"))]
|
||||
pub(crate) fn handle_anchor_click(self: Rc<Self>, ev: web_sys::Event) {
|
||||
let ev = ev.unchecked_into::<web_sys::MouseEvent>();
|
||||
if ev.default_prevented()
|
||||
|
|
|
@ -184,7 +184,7 @@ impl std::fmt::Debug for Loader {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "ssr")]
|
||||
#[cfg(all(feature = "ssr", not(feature = "hydrate")))]
|
||||
pub async fn loader_to_json(view: impl Fn(Scope) -> String + 'static) -> Option<String> {
|
||||
let (data, _, disposer) = run_scope_undisposed(move |cx| async move {
|
||||
let _shell = view(cx);
|
||||
|
|
|
@ -24,11 +24,9 @@ pub trait History {
|
|||
fn navigate(&self, loc: &LocationChange);
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "csr", feature = "hydrate"))]
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
|
||||
pub struct BrowserIntegration {}
|
||||
|
||||
#[cfg(any(feature = "csr", feature = "hydrate"))]
|
||||
impl BrowserIntegration {
|
||||
fn current() -> LocationChange {
|
||||
let loc = leptos_dom::location();
|
||||
|
@ -43,7 +41,6 @@ impl BrowserIntegration {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "csr", feature = "hydrate"))]
|
||||
impl History for BrowserIntegration {
|
||||
fn location(&self, cx: Scope) -> ReadSignal<LocationChange> {
|
||||
use crate::{NavigateOptions, RouterContext};
|
||||
|
|
|
@ -1,16 +1,9 @@
|
|||
#[cfg(not(feature = "ssr"))]
|
||||
use leptos::wasm_bindgen::JsValue;
|
||||
|
||||
#[derive(Debug, Clone, Default, PartialEq)]
|
||||
#[cfg(not(feature = "ssr"))]
|
||||
pub struct State(pub Option<JsValue>);
|
||||
|
||||
#[derive(Debug, Clone, Default, PartialEq)]
|
||||
#[cfg(feature = "ssr")]
|
||||
pub struct State(pub Option<()>);
|
||||
|
||||
impl State {
|
||||
#[cfg(not(feature = "ssr"))]
|
||||
pub fn to_js_value(&self) -> JsValue {
|
||||
match &self.0 {
|
||||
Some(v) => v.clone(),
|
||||
|
@ -19,7 +12,6 @@ impl State {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "ssr"))]
|
||||
impl<T> From<T> for State
|
||||
where
|
||||
T: Into<JsValue>,
|
||||
|
|
|
@ -36,7 +36,7 @@ pub fn unescape(s: &str) -> String {
|
|||
.replace('+', " ")
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "csr", feature = "hydrate"))]
|
||||
#[cfg(not(feature = "ssr"))]
|
||||
pub fn unescape(s: &str) -> String {
|
||||
js_sys::decode_uri(s).unwrap().into()
|
||||
}
|
||||
|
@ -46,12 +46,12 @@ pub fn escape(s: &str) -> String {
|
|||
urlencoding::encode(s).into()
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "csr", feature = "hydrate"))]
|
||||
#[cfg(not(feature = "ssr"))]
|
||||
pub fn escape(s: &str) -> String {
|
||||
js_sys::encode_uri(s).as_string().unwrap()
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "csr", feature = "hydrate"))]
|
||||
#[cfg(not(feature = "ssr"))]
|
||||
impl TryFrom<&str> for Url {
|
||||
type Error = String;
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use std::borrow::Cow;
|
||||
|
||||
#[doc(hidden)]
|
||||
#[cfg(any(feature = "csr", feature = "hydrate"))]
|
||||
#[cfg(not(feature = "ssr"))]
|
||||
pub fn expand_optionals(pattern: &str) -> Vec<Cow<str>> {
|
||||
use wasm_bindgen::JsValue;
|
||||
|
||||
|
|
|
@ -44,7 +44,7 @@ fn has_scheme(path: &str) -> bool {
|
|||
HAS_SCHEME_RE.is_match(path)
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "csr", feature = "hydrate"))]
|
||||
#[cfg(not(feature = "ssr"))]
|
||||
fn has_scheme(path: &str) -> bool {
|
||||
let re = js_sys::RegExp::new(HAS_SCHEME, "");
|
||||
re.test(path)
|
||||
|
@ -75,7 +75,7 @@ const BEGINS_WITH_QUERY_OR_HASH: &str = r#"^[?#]"#;
|
|||
const HAS_SCHEME: &str = r#"^(?:[a-z0-9]+:)?//"#;
|
||||
const QUERY: &str = r#"/*(\*.*)?$"#;
|
||||
|
||||
#[cfg(any(feature = "csr", feature = "hydrate"))]
|
||||
#[cfg(not(feature = "ssr"))]
|
||||
fn replace_trim_path<'a>(text: &'a str, replace: &str) -> Cow<'a, str> {
|
||||
let re = js_sys::RegExp::new(TRIM_PATH, "g");
|
||||
js_sys::JsString::from(text)
|
||||
|
@ -85,13 +85,13 @@ fn replace_trim_path<'a>(text: &'a str, replace: &str) -> Cow<'a, str> {
|
|||
.into()
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "csr", feature = "hydrate"))]
|
||||
#[cfg(not(feature = "ssr"))]
|
||||
fn begins_with_query_or_hash(text: &str) -> bool {
|
||||
let re = js_sys::RegExp::new(BEGINS_WITH_QUERY_OR_HASH, "");
|
||||
re.test(text)
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "csr", feature = "hydrate"))]
|
||||
#[cfg(not(feature = "ssr"))]
|
||||
fn replace_query(text: &str) -> String {
|
||||
let re = js_sys::RegExp::new(QUERY, "g");
|
||||
js_sys::JsString::from(text)
|
||||
|
|
Loading…
Reference in a new issue