Compare commits

..

15 Commits

Author SHA1 Message Date
Greg Johnston
bbf5bf9170 chore: publish patch releases 2025-09-29 15:21:22 -04:00
Greg Johnston
a453b7d1bd fix: correctly poll all out-of-order streaming chunks (closes #4326) (#4333)
* fix: correctly poll all out-of-order streaming chunks (closes #4326)

* [autofix.ci] apply automated fixes

* [autofix.ci] apply automated fixes (attempt 2/3)

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2025-09-26 07:45:41 -04:00
Greg Johnston
3b9ccdf57e Merge pull request #4334 from leptos-rs/4324
Correctly manage path stack during back navigation
2025-09-26 07:45:25 -04:00
Greg Johnston
27cd423ebc fix: correctly update path stack when navigating backwards (closes #4324) 2025-09-24 19:39:31 -04:00
Greg Johnston
b3907baf49 test: add regression test for #4324 2025-09-24 19:23:20 -04:00
Greg Johnston
9a8bb7eb75 test: add regression test for #4251 2025-09-24 19:23:13 -04:00
Greg Johnston
95db8c939e chore: add missing attributes (#4308)
* chore: add missing `dirname` attribute to `input` element

* chore: add missing `exportparts` global attribute
2025-09-24 17:05:38 -04:00
zakstucke
2bfa9952af feat: allow accessing a parent owner from a child (#4325) 2025-09-24 17:04:26 -04:00
Greg Johnston
4e445f43d6 fix: correctly import scoped slots (closes #4311) (#4318) 2025-09-24 17:01:25 -04:00
dependabot[bot]
5f544f67ae chore(deps): bump the rust-dependencies group across 1 directory with 11 updates (#4319)
Bumps the rust-dependencies group with 3 updates in the / directory: [anyhow](https://github.com/dtolnay/anyhow), [subsecond](https://github.com/dioxuslabs/dioxus) and [libloading](https://github.com/nagisa/rust_libloading).


Updates `anyhow` from 1.0.99 to 1.0.100
- [Release notes](https://github.com/dtolnay/anyhow/releases)
- [Commits](https://github.com/dtolnay/anyhow/compare/1.0.99...1.0.100)

Updates `subsecond` from `eef4db6` to `2e7e069`
- [Release notes](https://github.com/dioxuslabs/dioxus/releases)
- [Commits](eef4db67b1...2e7e0696a3)

Updates `dioxus-cli-config` from `eef4db6` to `2e7e069`
- [Release notes](https://github.com/dioxuslabs/dioxus/releases)
- [Commits](eef4db67b1...2e7e0696a3)

Updates `dioxus-devtools` from `eef4db6` to `2e7e069`
- [Release notes](https://github.com/dioxuslabs/dioxus/releases)
- [Commits](eef4db67b1...2e7e0696a3)

Updates `dioxus-core` from `eef4db6` to `2e7e069`
- [Release notes](https://github.com/DioxusLabs/dioxus/releases)
- [Commits](https://github.com/DioxusLabs/dioxus/commits)

Updates `dioxus-core-types` from `eef4db6` to `2e7e069`
- [Release notes](https://github.com/DioxusLabs/dioxus/releases)
- [Commits](https://github.com/DioxusLabs/dioxus/commits)

Updates `dioxus-devtools-types` from `eef4db6` to `2e7e069`
- [Release notes](https://github.com/DioxusLabs/dioxus/releases)
- [Commits](https://github.com/DioxusLabs/dioxus/commits)

Updates `dioxus-signals` from `eef4db6` to `2e7e069`
- [Release notes](https://github.com/DioxusLabs/dioxus/releases)
- [Commits](https://github.com/DioxusLabs/dioxus/commits)

Updates `generational-box` from `eef4db6` to `2e7e069`
- [Release notes](https://github.com/DioxusLabs/dioxus/releases)
- [Commits](https://github.com/DioxusLabs/dioxus/commits)

Updates `libloading` from 0.8.8 to 0.8.9
- [Commits](https://github.com/nagisa/rust_libloading/compare/0.8.8...0.8.9)

Updates `subsecond-types` from `eef4db6` to `2e7e069`
- [Release notes](https://github.com/DioxusLabs/dioxus/releases)
- [Commits](https://github.com/DioxusLabs/dioxus/commits)

---
updated-dependencies:
- dependency-name: anyhow
  dependency-version: 1.0.100
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: rust-dependencies
- dependency-name: subsecond
  dependency-version: 2e7e0696a320a2a98a07e405603f59c8296b0b42
  dependency-type: direct:production
  dependency-group: rust-dependencies
- dependency-name: dioxus-cli-config
  dependency-version: 2e7e0696a320a2a98a07e405603f59c8296b0b42
  dependency-type: direct:production
  dependency-group: rust-dependencies
- dependency-name: dioxus-devtools
  dependency-version: 2e7e0696a320a2a98a07e405603f59c8296b0b42
  dependency-type: direct:production
  dependency-group: rust-dependencies
- dependency-name: dioxus-core
  dependency-version: 2e7e0696a320a2a98a07e405603f59c8296b0b42
  dependency-type: indirect
  dependency-group: rust-dependencies
- dependency-name: dioxus-core-types
  dependency-version: 2e7e0696a320a2a98a07e405603f59c8296b0b42
  dependency-type: indirect
  dependency-group: rust-dependencies
- dependency-name: dioxus-devtools-types
  dependency-version: 2e7e0696a320a2a98a07e405603f59c8296b0b42
  dependency-type: indirect
  dependency-group: rust-dependencies
- dependency-name: dioxus-signals
  dependency-version: 2e7e0696a320a2a98a07e405603f59c8296b0b42
  dependency-type: indirect
  dependency-group: rust-dependencies
- dependency-name: generational-box
  dependency-version: 2e7e0696a320a2a98a07e405603f59c8296b0b42
  dependency-type: indirect
  dependency-group: rust-dependencies
- dependency-name: libloading
  dependency-version: 0.8.9
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: rust-dependencies
- dependency-name: subsecond-types
  dependency-version: 2e7e0696a320a2a98a07e405603f59c8296b0b42
  dependency-type: indirect
  dependency-group: rust-dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-24 17:01:08 -04:00
Greg Johnston
68477d2b76 fix: preload correct __wasm_split.*.js file (closes #4322) (#4327) 2025-09-24 17:00:55 -04:00
Greg Johnston
5bd9469b93 fix: remove event listeners correctly when dropping handles (closes #4313) (#4314) 2025-09-23 10:59:04 -04:00
Greg Johnston
4bca70dc2f chore: specify Tailwind version in Trunk.toml (closes #4315) (#4317) 2025-09-21 14:38:13 -04:00
Adam Doyle
b92a14228c chore: add missing exportparts global attribute 2025-09-20 08:40:17 -04:00
Adam Doyle
68967fdad3 chore: add missing dirname attribute to input element 2025-09-19 16:00:05 -04:00
31 changed files with 286 additions and 81 deletions

59
Cargo.lock generated
View File

@@ -279,9 +279,9 @@ dependencies = [
[[package]]
name = "anyhow"
version = "1.0.99"
version = "1.0.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b0674a1ddeecb70197781e945de4b3b8ffb61fa939a5597bcf48503737663100"
checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61"
[[package]]
name = "async-executor"
@@ -903,12 +903,14 @@ dependencies = [
[[package]]
name = "dioxus-cli-config"
version = "0.7.0-rc.0"
source = "git+https://github.com/dioxuslabs/dioxus#eef4db67b1164934eb29b7ac4d4bcd693bba25a5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b8cec511d8a05ed60071bb0088f07ec40325faf27a608fa19d65befdd842b57f"
[[package]]
name = "dioxus-core"
version = "0.7.0-rc.0"
source = "git+https://github.com/dioxuslabs/dioxus#eef4db67b1164934eb29b7ac4d4bcd693bba25a5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "07b55eccaa5c4f35f1755ea18a5716fe8ecba60ff1f25c52be6ceda2e6a52eb6"
dependencies = [
"const_format",
"dioxus-core-types",
@@ -929,12 +931,14 @@ dependencies = [
[[package]]
name = "dioxus-core-types"
version = "0.7.0-rc.0"
source = "git+https://github.com/dioxuslabs/dioxus#eef4db67b1164934eb29b7ac4d4bcd693bba25a5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f0ef2a94b4ceb8f7a39f56a539d07e82b0358a49a0b95028ad48635975df29d7"
[[package]]
name = "dioxus-devtools"
version = "0.7.0-rc.0"
source = "git+https://github.com/dioxuslabs/dioxus#eef4db67b1164934eb29b7ac4d4bcd693bba25a5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "60af4e129968ab1713471ed0b29c3eefa4e8e09252429487d7a581e93c7ecfe5"
dependencies = [
"dioxus-cli-config",
"dioxus-core",
@@ -952,7 +956,8 @@ dependencies = [
[[package]]
name = "dioxus-devtools-types"
version = "0.7.0-rc.0"
source = "git+https://github.com/dioxuslabs/dioxus#eef4db67b1164934eb29b7ac4d4bcd693bba25a5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "64274704b6a8d018112473cdce0b3db1dcccfa79bde445223592fe4e396ff5ef"
dependencies = [
"dioxus-core",
"serde",
@@ -962,7 +967,8 @@ dependencies = [
[[package]]
name = "dioxus-signals"
version = "0.7.0-rc.0"
source = "git+https://github.com/dioxuslabs/dioxus#eef4db67b1164934eb29b7ac4d4bcd693bba25a5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d1d0e70a8da969c0404f5ef8cf6f47042bea55608b582079f3ea3d9fff46125c"
dependencies = [
"dioxus-core",
"futures-channel",
@@ -1051,7 +1057,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb"
dependencies = [
"libc",
"windows-sys 0.61.0",
"windows-sys 0.52.0",
]
[[package]]
@@ -1239,7 +1245,8 @@ dependencies = [
[[package]]
name = "generational-box"
version = "0.7.0-rc.0"
source = "git+https://github.com/dioxuslabs/dioxus#eef4db67b1164934eb29b7ac4d4bcd693bba25a5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cb058e0358ff765e719ab3e61629c5090fedb6a6ccf66479de21440a33d7f084"
dependencies = [
"parking_lot",
"tracing",
@@ -1873,7 +1880,7 @@ checksum = "d4345964bb142484797b161f473a503a434de77149dd8c7427788c6e13379388"
[[package]]
name = "leptos"
version = "0.8.9"
version = "0.8.10"
dependencies = [
"any_spawner",
"base64",
@@ -1994,7 +2001,7 @@ dependencies = [
[[package]]
name = "leptos_dom"
version = "0.8.6"
version = "0.8.7"
dependencies = [
"js-sys",
"leptos",
@@ -2027,7 +2034,7 @@ dependencies = [
[[package]]
name = "leptos_integration_utils"
version = "0.8.5"
version = "0.8.6"
dependencies = [
"futures",
"hydration_context",
@@ -2040,7 +2047,7 @@ dependencies = [
[[package]]
name = "leptos_macro"
version = "0.8.8"
version = "0.8.9"
dependencies = [
"attribute-derive",
"cfg-if",
@@ -2084,7 +2091,7 @@ dependencies = [
[[package]]
name = "leptos_router"
version = "0.8.7"
version = "0.8.8"
dependencies = [
"any_spawner",
"either_of",
@@ -2148,12 +2155,12 @@ checksum = "6a82ae493e598baaea5209805c49bbf2ea7de956d50d7da0da1164f9c6d28543"
[[package]]
name = "libloading"
version = "0.8.8"
version = "0.8.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "07033963ba89ebaf1584d767badaa2e8fcec21aedea6b8c0346d487d49c28667"
checksum = "d7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55"
dependencies = [
"cfg-if",
"windows-targets 0.53.3",
"windows-link 0.2.0",
]
[[package]]
@@ -2868,7 +2875,7 @@ dependencies = [
[[package]]
name = "reactive_graph"
version = "0.2.7"
version = "0.2.8"
dependencies = [
"any_spawner",
"async-lock",
@@ -3137,7 +3144,7 @@ dependencies = [
"errno",
"libc",
"linux-raw-sys",
"windows-sys 0.61.0",
"windows-sys 0.52.0",
]
[[package]]
@@ -3638,7 +3645,8 @@ checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
[[package]]
name = "subsecond"
version = "0.7.0-rc.0"
source = "git+https://github.com/dioxuslabs/dioxus#eef4db67b1164934eb29b7ac4d4bcd693bba25a5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b14ed4d86ab065ffbfdb994fd3e44daf5244b02cb643bd52949d74b703f36605"
dependencies = [
"js-sys",
"libc",
@@ -3656,7 +3664,8 @@ dependencies = [
[[package]]
name = "subsecond-types"
version = "0.7.0-rc.0"
source = "git+https://github.com/dioxuslabs/dioxus#eef4db67b1164934eb29b7ac4d4bcd693bba25a5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "275920a8a5634e47e12253971db85946798795bbe4d9dfc1debf23533d823983"
dependencies = [
"serde",
]
@@ -3735,7 +3744,7 @@ dependencies = [
[[package]]
name = "tachys"
version = "0.2.8"
version = "0.2.9"
dependencies = [
"any_spawner",
"async-trait",
@@ -3804,7 +3813,7 @@ dependencies = [
"getrandom 0.3.3",
"once_cell",
"rustix",
"windows-sys 0.61.0",
"windows-sys 0.52.0",
]
[[package]]
@@ -4611,7 +4620,7 @@ version = "0.1.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22"
dependencies = [
"windows-sys 0.61.0",
"windows-sys 0.52.0",
]
[[package]]

View File

@@ -50,26 +50,26 @@ any_spawner = { path = "./any_spawner/", version = "0.3.0" }
const_str_slice_concat = { path = "./const_str_slice_concat", version = "0.1" }
either_of = { path = "./either_of/", version = "0.1.6" }
hydration_context = { path = "./hydration_context", version = "0.3.0" }
leptos = { path = "./leptos", version = "0.8.9" }
leptos = { path = "./leptos", version = "0.8.10" }
leptos_config = { path = "./leptos_config", version = "0.8.7" }
leptos_dom = { path = "./leptos_dom", version = "0.8.6" }
leptos_dom = { path = "./leptos_dom", version = "0.8.7" }
leptos_hot_reload = { path = "./leptos_hot_reload", version = "0.8.5" }
leptos_integration_utils = { path = "./integrations/utils", version = "0.8.5" }
leptos_macro = { path = "./leptos_macro", version = "0.8.8" }
leptos_router = { path = "./router", version = "0.8.7" }
leptos_integration_utils = { path = "./integrations/utils", version = "0.8.6" }
leptos_macro = { path = "./leptos_macro", version = "0.8.9" }
leptos_router = { path = "./router", version = "0.8.8" }
leptos_router_macro = { path = "./router_macro", version = "0.8.5" }
leptos_server = { path = "./leptos_server", version = "0.8.5" }
leptos_meta = { path = "./meta", version = "0.8.5" }
next_tuple = { path = "./next_tuple", version = "0.1.0" }
oco_ref = { path = "./oco", version = "0.2.1" }
or_poisoned = { path = "./or_poisoned", version = "0.1.0" }
reactive_graph = { path = "./reactive_graph", version = "0.2.7" }
reactive_graph = { path = "./reactive_graph", version = "0.2.8" }
reactive_stores = { path = "./reactive_stores", version = "0.2.5" }
reactive_stores_macro = { path = "./reactive_stores_macro", version = "0.2.6" }
server_fn = { path = "./server_fn", version = "0.8.7" }
server_fn_macro = { path = "./server_fn_macro", version = "0.8.7" }
server_fn_macro_default = { path = "./server_fn/server_fn_macro_default", version = "0.8.5" }
tachys = { path = "./tachys", version = "0.2.8" }
tachys = { path = "./tachys", version = "0.2.9" }
wasm_split_helpers = { path = "./wasm_split", version = "0.1.2" }
wasm_split_macros = { path = "./wasm_split_macros", version = "0.1.3" }
@@ -125,7 +125,7 @@ glib = { default-features = false, version = "0.20.12" }
async-trait = { default-features = false, version = "0.1.89" }
typed-builder-macro = { default-features = false, version = "0.21.0" }
linear-map = { default-features = false, version = "1.2.0" }
anyhow = { default-features = false, version = "1.0.99" }
anyhow = { default-features = false, version = "1.0.100" }
walkdir = { default-features = false, version = "2.5.0" }
actix-ws = { default-features = false, version = "0.3.0" }
tower-http = { default-features = false, version = "0.6.4" }
@@ -170,9 +170,9 @@ async-lock = { default-features = false, version = "3.4.1" }
base16 = { default-features = false, version = "0.2.1" }
digest = { default-features = false, version = "0.10.7" }
sha2 = { default-features = false, version = "0.10.8" }
subsecond = { default-features = false, git = "https://github.com/dioxuslabs/dioxus" }
dioxus-cli-config = { default-features = false, git = "https://github.com/dioxuslabs/dioxus" }
dioxus-devtools = { default-features = false, git = "https://github.com/dioxuslabs/dioxus" }
subsecond = { default-features = false, version = "0.7.0-rc.0" }
dioxus-cli-config = { default-features = false, version = "0.7.0-rc.0" }
dioxus-devtools = { default-features = false, version = "0.7.0-rc.0" }
[profile.release]
codegen-units = 1

View File

@@ -0,0 +1,13 @@
@check_issue_4251
Feature: Check that issue 4251 does not reappear
Scenario: Clicking a link to the same page youre currently on should not add the page to the history stack.
Given I see the app
And I can access regression test 4324
When I select the link This page
And I select the link This page
And I select the link This page
Then I see the result is the string Issue4324
When I press the back button
And I select the link 4324
Then I see the result is the string Issue4324

View File

@@ -0,0 +1,11 @@
@check_issue_4324
Feature: Check that issue 4324 does not reappear
Scenario: Navigating to the same page after clicking "Back" should set the URL correctly
Given I see the app
And I can access regression test 4324
Then I see the path is /4324/
When I press the back button
Then I see the path is /
When I select the link 4324
Then I see the path is /4324/

View File

@@ -43,3 +43,13 @@ pub async fn element_value_is(
assert_eq!(value.as_deref(), Some(expected));
Ok(())
}
pub async fn path_is(client: &Client, expected_path: &str) -> Result<()> {
let url = client
.current_url()
.await
.expect("could not access current URL");
let path = url.path();
assert_eq!(expected_path, path);
Ok(())
}

View File

@@ -45,3 +45,12 @@ async fn i_refresh_the_browser(world: &mut AppWorld) -> Result<()> {
Ok(())
}
#[given(regex = "^I press the back button$")]
#[when(regex = "^I press the back button$")]
async fn i_go_back(world: &mut AppWorld) -> Result<()> {
let client = &world.client;
client.back().await?;
Ok(())
}

View File

@@ -43,3 +43,10 @@ async fn i_see_the_value(
check::element_value_is(client, &id, &value).await?;
Ok(())
}
#[then(regex = r"^I see the path is (.*)$")]
async fn i_see_the_path(world: &mut AppWorld, path: String) -> Result<()> {
let client = &world.client;
check::path_is(client, &path).await?;
Ok(())
}

View File

@@ -1,7 +1,7 @@
use crate::{
issue_4005::Routes4005, issue_4088::Routes4088, issue_4217::Routes4217,
issue_4285::Routes4285, issue_4296::Routes4296, pr_4015::Routes4015,
pr_4091::Routes4091,
issue_4285::Routes4285, issue_4296::Routes4296, issue_4324::Routes4324,
pr_4015::Routes4015, pr_4091::Routes4091,
};
use leptos::prelude::*;
use leptos_meta::{MetaTags, *};
@@ -47,6 +47,7 @@ pub fn App() -> impl IntoView {
<Routes4005/>
<Routes4285/>
<Routes4296/>
<Routes4324/>
</Routes>
</main>
</Router>
@@ -73,6 +74,7 @@ fn HomePage() -> impl IntoView {
<li><a href="/4005/">"4005"</a></li>
<li><a href="/4285/">"4285"</a></li>
<li><a href="/4296/">"4296"</a></li>
<li><a href="/4324/">"4324"</a></li>
</ul>
</nav>
}

View File

@@ -0,0 +1,21 @@
use leptos::prelude::*;
#[allow(unused_imports)]
use leptos_router::{
components::Route, path, Lazy, MatchNestedRoutes, NavigateOptions,
};
#[component]
pub fn Routes4324() -> impl MatchNestedRoutes + Clone {
view! {
<Route path=path!("4324") view=Issue4324/>
}
.into_inner()
}
#[component]
pub fn Issue4324() -> impl IntoView {
view! {
<a href="/4324/">"This page"</a>
<p id="result">"Issue4324"</p>
}
}

View File

@@ -4,6 +4,7 @@ mod issue_4088;
mod issue_4217;
mod issue_4285;
mod issue_4296;
mod issue_4324;
mod pr_4015;
mod pr_4091;

View File

@@ -0,0 +1,3 @@
[tools]
tailwindcss = "4.1.13"

View File

@@ -4,7 +4,7 @@ authors = ["Greg Johnston"]
license = "MIT"
repository = "https://github.com/leptos-rs/leptos"
description = "Utilities to help build server integrations for the Leptos web framework."
version = "0.8.5"
version = "0.8.6"
rust-version.workspace = true
edition.workspace = true

View File

@@ -68,7 +68,8 @@ pub trait ExtendResponse: Sized {
let nonce =
use_nonce().map(|n| n.to_string()).unwrap_or_default();
if let Some(manifest) = use_context::<WasmSplitManifest>() {
let (pkg_path, manifest) = &*manifest.0.read_value();
let (pkg_path, manifest, wasm_split_file) =
&*manifest.0.read_value();
let prefetches = prefetches.0.read_value();
let all_prefetches = prefetches.iter().flat_map(|key| {
@@ -90,7 +91,7 @@ pub trait ExtendResponse: Sized {
.to_html();
}
_ = view! {
<Link rel="modulepreload" href=format!("{pkg_path}/__wasm_split.js") crossorigin=nonce/>
<Link rel="modulepreload" href=format!("{pkg_path}/{wasm_split_file}") crossorigin=nonce/>
}
.to_html();
}

View File

@@ -1,6 +1,6 @@
[package]
name = "leptos"
version = "0.8.9"
version = "0.8.10"
authors = ["Greg Johnston"]
license = "MIT"
repository = "https://github.com/leptos-rs/leptos"

View File

@@ -65,16 +65,56 @@ pub fn HydrationScripts(
if let Some(splits) = SPLIT_MANIFEST.get_or_init(|| {
let root = root.clone().unwrap_or_default();
let (wasm_split_js, wasm_split_manifest) = if options.hash_files {
let hash_path = std::env::current_exe()
.map(|path| {
path.parent().map(|p| p.to_path_buf()).unwrap_or_default()
})
.unwrap_or_default()
.join(options.hash_file.as_ref());
let hashes = std::fs::read_to_string(&hash_path)
.expect("failed to read hash file");
let mut split =
"__wasm_split.______________________.js".to_string();
let mut manifest = "__wasm_split_manifest.json".to_string();
for line in hashes.lines() {
let line = line.trim();
if !line.is_empty() {
if let Some((file, hash)) = line.split_once(':') {
if file == "manifest" {
manifest.clear();
manifest.push_str("__wasm_split_manifest.");
manifest.push_str(hash.trim());
manifest.push_str(".json");
}
if file == "split" {
split.clear();
split.push_str("__wasm_split.");
split.push_str(hash.trim());
split.push_str(".js");
}
}
}
}
(split, manifest)
} else {
(
"__wasm_split.______________________.js".to_string(),
"__wasm_split_manifest.json".to_string(),
)
};
let site_dir = &options.site_root;
let pkg_dir = &options.site_pkg_dir;
let path = PathBuf::from(site_dir.to_string());
let path = path
.join(pkg_dir.to_string())
.join("__wasm_split_manifest.json");
let path = path.join(pkg_dir.to_string()).join(wasm_split_manifest);
let file = std::fs::read_to_string(path).ok()?;
let manifest = WasmSplitManifest(ArcStoredValue::new((
format!("{root}/{pkg_dir}"),
serde_json::from_str(&file).expect("could not read manifest file"),
wasm_split_js,
)));
Some(manifest)

View File

@@ -395,7 +395,8 @@ pub fn prefetch_lazy_fn_on_server(id: &'static str) {
#[derive(Clone, Debug, Default)]
pub struct WasmSplitManifest(
pub reactive_graph::owner::ArcStoredValue<(
String,
std::collections::HashMap<String, Vec<String>>,
String, // the pkg root
std::collections::HashMap<String, Vec<String>>, // preloads
String, // the name of the __wasm_split.js file
)>,
);

View File

@@ -1,6 +1,6 @@
[package]
name = "leptos_dom"
version = "0.8.6"
version = "0.8.7"
authors = ["Greg Johnston"]
license = "MIT"
repository = "https://github.com/leptos-rs/leptos"

View File

@@ -1,6 +1,6 @@
[package]
name = "leptos_macro"
version = "0.8.8"
version = "0.8.9"
authors = ["Greg Johnston"]
license = "MIT"
repository = "https://github.com/leptos-rs/leptos"

View File

@@ -25,9 +25,8 @@ use std::{
use syn::{
punctuated::Pair::{End, Punctuated},
spanned::Spanned,
Expr,
Expr::Tuple,
ExprArray, ExprLit, ExprRange, Lit, LitStr, RangeLimits, Stmt,
Expr::{self, Tuple},
ExprArray, ExprLit, ExprPath, ExprRange, Lit, LitStr, RangeLimits, Stmt,
};
#[derive(Clone, Copy, PartialEq, Eq)]
@@ -1871,6 +1870,28 @@ pub(crate) fn ident_from_tag_name(tag_name: &NodeName) -> Ident {
}
}
pub(crate) fn full_path_from_tag_name(tag_name: &NodeName) -> Option<ExprPath> {
match tag_name {
NodeName::Path(path) => Some(path.clone()),
NodeName::Block(_) => {
let span = tag_name.span();
proc_macro_error2::emit_error!(
span,
"blocks not allowed in tag-name position"
);
None
}
_ => {
let span = tag_name.span();
proc_macro_error2::emit_error!(
span,
"punctuated names not allowed in slots"
);
None
}
}
}
pub(crate) fn directive_call_from_attribute_node(
attr: &KeyedAttribute,
directive_name: &str,

View File

@@ -1,6 +1,6 @@
use super::{
component_builder::maybe_optimised_component_children,
convert_to_snake_case, ident_from_tag_name,
convert_to_snake_case, full_path_from_tag_name,
};
use crate::view::{fragment_to_tokens, utils::filter_prefixed_attrs, TagType};
use proc_macro2::{Ident, TokenStream, TokenTree};
@@ -24,7 +24,7 @@ pub(crate) fn slot_to_tokens(
node.name().to_string()
});
let component_name = ident_from_tag_name(node.name());
let component_path = full_path_from_tag_name(node.name());
let Some(parent_slots) = parent_slots else {
proc_macro_error2::emit_error!(
@@ -190,7 +190,7 @@ pub(crate) fn slot_to_tokens(
let slot = quote_spanned! {node.span()=>
{
let slot = #component_name::builder()
let slot = #component_path::builder()
#(#props)*
#(#slots)*
#children

View File

@@ -1,6 +1,6 @@
[package]
name = "reactive_graph"
version = "0.2.7"
version = "0.2.8"
authors = ["Greg Johnston"]
license = "MIT"
readme = "../README.md"

View File

@@ -209,6 +209,25 @@ impl Owner {
this
}
/// Returns the parent of this `Owner`, if any.
///
/// None when:
/// - This is a root owner
/// - The parent has been dropped
pub fn parent(&self) -> Option<Owner> {
self.inner
.read()
.or_poisoned()
.parent
.as_ref()
.and_then(|p| p.upgrade())
.map(|inner| Owner {
inner,
#[cfg(feature = "hydration")]
shared_context: self.shared_context.clone(),
})
}
/// Creates a new `Owner` that is the child of the current `Owner`, if any.
pub fn child(&self) -> Self {
let parent = Some(Arc::downgrade(&self.inner));

View File

@@ -1,6 +1,6 @@
[package]
name = "leptos_router"
version = "0.8.7"
version = "0.8.8"
authors = ["Greg Johnston", "Ben Wishovich"]
license = "MIT"
readme = "../README.md"

View File

@@ -185,11 +185,15 @@ impl LocationProvider for BrowserUrl {
let is_back = self.is_back.clone();
move || match Self::current() {
Ok(new_url) => {
let stack = path_stack.read_value();
let mut stack = path_stack.write_value();
let is_navigating_back = stack.len() == 1
|| (stack.len() >= 2
&& stack.get(stack.len() - 2) == Some(&new_url));
if is_navigating_back {
stack.pop();
}
is_back.set(is_navigating_back);
url.set(new_url);

View File

@@ -1,6 +1,6 @@
[package]
name = "tachys"
version = "0.2.8"
version = "0.2.9"
authors = ["Greg Johnston"]
license = "MIT"
readme = "../README.md"

View File

@@ -205,6 +205,14 @@ where
self.add_any_attr(enterkeyhint(value))
}
/// The `exportparts` attribute enables the sharing of parts of an element's shadow DOM with a containing document.
fn exportparts(
self,
value: V,
) -> <Self as AddAnyAttr>::Output<Attr<Exportparts, V>> {
self.add_any_attr(exportparts(value))
}
/// The `hidden` global attribute is a Boolean attribute indicating that the element is not yet, or is no longer, relevant.
fn hidden(self, value: V) -> <Self as AddAnyAttr>::Output<Attr<Hidden, V>> {
self.add_any_attr(hidden(value))

View File

@@ -212,7 +212,7 @@ html_self_closing_elements! {
/// The `<img>` HTML element embeds an image into the document.
img HtmlImageElement [alt, attributionsrc, crossorigin, decoding, elementtiming, fetchpriority, height, ismap, loading, referrerpolicy, sizes, src, srcset, usemap, width] true,
/// The `<input>` HTML element is used to create interactive controls for web-based forms in order to accept data from the user; a wide variety of types of input data and control widgets are available, depending on the device and user agent. The `<input>` element is one of the most powerful and complex in all of HTML due to the sheer number of combinations of input types and attributes.
input HtmlInputElement [accept, alt, autocomplete, capture, checked, disabled, form, formaction, formenctype, formmethod, formnovalidate, formtarget, height, list, max, maxlength, min, minlength, multiple, name, pattern, placeholder, popovertarget, popovertargetaction, readonly, required, size, src, step, r#type, value, width] true,
input HtmlInputElement [accept, alt, autocomplete, capture, checked, dirname, disabled, form, formaction, formenctype, formmethod, formnovalidate, formtarget, height, list, max, maxlength, min, minlength, multiple, name, pattern, placeholder, popovertarget, popovertargetaction, readonly, required, size, src, step, r#type, value, width] true,
/// The `<link>` HTML element specifies relationships between the current document and an external resource. This element is most commonly used to link to CSS, but is also used to establish site icons (both "favicon" style icons and icons for the home screen and apps on mobile devices) among other things.
link HtmlLinkElement [r#as, blocking, crossorigin, fetchpriority, href, hreflang, imagesizes, imagesrcset, integrity, media, rel, referrerpolicy, sizes, r#type] true,
/// The `<meta>` HTML element represents Metadata that cannot be represented by other HTML meta-related elements, like base, link, script, style or title.

View File

@@ -323,7 +323,9 @@ where
fn rebuild(self, state: &mut Self::State) {
let (el, prev_cleanup) = state;
if let Some(prev) = prev_cleanup.take() {
(prev.into_inner())(el);
if let Some(remove) = prev.into_inner() {
remove();
}
}
*prev_cleanup = Some(if E::CAPTURE {
self.attach_capture(el)

View File

@@ -258,7 +258,9 @@ where
prop(self.key(), signal).rebuild(attr_state);
if let Some(prev) = prev_cleanup.take() {
(prev.into_inner())(el);
if let Some(remove) = prev.into_inner() {
remove();
}
}
*prev_cleanup = Some(self.attach(el));
}

View File

@@ -296,19 +296,20 @@ impl Dom {
// return the remover
RemoveEventHandler::new({
let name = name.to_owned();
let el = el.clone();
// safe to construct this here, because it will only run in the browser
// so it will always be accessed or dropped from the main thread
let cb = send_wrapper::SendWrapper::new(cb);
move |el: &Element| {
let cb = send_wrapper::SendWrapper::new(move || {
or_debug!(
el.remove_event_listener_with_callback(
intern(&name),
cb.as_ref().unchecked_ref()
),
el,
&el,
"removeEventListener"
)
}
});
move || cb()
})
}
@@ -334,20 +335,21 @@ impl Dom {
// return the remover
RemoveEventHandler::new({
let name = name.to_owned();
let el = el.clone();
// safe to construct this here, because it will only run in the browser
// so it will always be accessed or dropped from the main thread
let cb = send_wrapper::SendWrapper::new(cb);
move |el: &Element| {
let cb = send_wrapper::SendWrapper::new(move || {
or_debug!(
el.remove_event_listener_with_callback_and_bool(
intern(&name),
cb.as_ref().unchecked_ref(),
true
),
el,
&el,
"removeEventListener"
)
}
});
move || cb()
})
}
@@ -448,17 +450,19 @@ impl Dom {
// return the remover
RemoveEventHandler::new({
let key = key.to_owned();
let el = el.clone();
// safe to construct this here, because it will only run in the browser
// so it will always be accessed or dropped from the main thread
let cb = send_wrapper::SendWrapper::new(cb);
move |el: &Element| {
drop(cb.take());
let el_cb = send_wrapper::SendWrapper::new((el, cb));
move || {
let (el, cb) = el_cb.take();
drop(cb);
or_debug!(
js_sys::Reflect::delete_property(
el,
&el,
&JsValue::from_str(&key)
),
el,
&el,
"delete property"
);
}

View File

@@ -1,5 +1,5 @@
use crate::view::{Mountable, ToTemplate};
use std::{borrow::Cow, fmt::Debug};
use std::{borrow::Cow, fmt::Debug, marker::PhantomData};
use wasm_bindgen::JsValue;
/// A DOM renderer.
@@ -120,16 +120,33 @@ pub trait Renderer: Send + Sized + Debug + 'static {
should store it in some other data structure to clean it up \
later to avoid dropping it immediately, or leak it with \
std::mem::forget() to never drop it."]
pub struct RemoveEventHandler<T>(Box<dyn FnOnce(&T) + Send + Sync>);
#[allow(clippy::type_complexity)]
pub struct RemoveEventHandler<T>(
Option<Box<dyn FnOnce() + Send + Sync>>,
// only here to keep the generic, removing which would be a breaking change
// TODO remove generic in 0.9
PhantomData<fn() -> T>,
);
impl<T> RemoveEventHandler<T> {
/// Creates a new container with a function that will be called when it is dropped.
pub(crate) fn new(remove: impl FnOnce(&T) + Send + Sync + 'static) -> Self {
Self(Box::new(remove))
pub(crate) fn new(remove: impl FnOnce() + Send + Sync + 'static) -> Self {
Self(Some(Box::new(remove)), PhantomData)
}
pub(crate) fn into_inner(self) -> Box<dyn FnOnce(&T) + Send + Sync> {
self.0
#[allow(clippy::type_complexity)]
pub(crate) fn into_inner(
mut self,
) -> Option<Box<dyn FnOnce() + Send + Sync>> {
self.0.take()
}
}
impl<T> Drop for RemoveEventHandler<T> {
fn drop(&mut self) {
if let Some(cb) = self.0.take() {
cb()
}
}
}