From 34bd6d20ce5c0addc23b9ccb3becf0328493b612 Mon Sep 17 00:00:00 2001 From: Nico Burns Date: Thu, 20 Aug 2026 13:12:08 +0000 Subject: [PATCH 1/2] Migrate dioxus-native and dioxus-native-dom to latest Dioxus main - Pin all dioxus workspace dependencies to dioxus main rev 24f6a829d (0.8.0-alpha.1) - Port mutation_writer to the new stack-machine WriteMutations API, keeping Blitz-specific behavior (event handler counts, mounted event queueing, data-dioxus-id, subdocument/custom-widget attachment) - Use DioxusState::writer() and ElementId::from_raw in dioxus_document - Add convert_before_input_data to the HtmlEventConverter impl - Update dioxus-native prelude for the new html element vocabulary (dioxus_html::html + elements::prelude::*) - Mark #[store(pub)] extension methods pub per new visibility rules - Replace removed dioxus_elements paths in examples --- Cargo.lock | 215 +++---- Cargo.toml | 26 +- apps/browser/src/browser_history.rs | 6 +- apps/browser/src/tab.rs | 16 +- examples/transforms.rs | 12 +- .../dioxus-native-dom/src/dioxus_document.rs | 8 +- packages/dioxus-native-dom/src/events.rs | 12 +- .../dioxus-native-dom/src/mutation_writer.rs | 566 ++++++++++-------- packages/dioxus-native/src/prelude.rs | 6 +- tests/blitz-tests/tests/stale_node_mapping.rs | 2 +- 10 files changed, 473 insertions(+), 396 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fc2d9cd696..696039513f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1611,40 +1611,18 @@ dependencies = [ [[package]] name = "const-serialize" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad7154afa56de2f290e3c82c2c6dc4f5b282b6870903f56ef3509aba95866edc" +version = "0.8.0-alpha.1" +source = "git+https://github.com/DioxusLabs/dioxus?rev=24f6a829df0dfa203961a98ea4cae21c2ff27e28#24f6a829df0dfa203961a98ea4cae21c2ff27e28" dependencies = [ - "const-serialize-macro 0.7.2", -] - -[[package]] -name = "const-serialize" -version = "0.8.0-alpha.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e42cd5aabba86f128b3763da1fec1491c0f728ce99245062cd49b6f9e6d235b" -dependencies = [ - "const-serialize 0.7.2", - "const-serialize-macro 0.8.0-alpha.0", + "const-serialize-macro", + "dioxus-const-vec", "serde", ] [[package]] name = "const-serialize-macro" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f160aad86b4343e8d4e261fee9965c3005b2fd6bc117d172ab65948779e4acf" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "const-serialize-macro" -version = "0.8.0-alpha.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42571ed01eb46d2e1adcf99c8ca576f081e46f2623d13500eba70d1d99a4c439" +version = "0.8.0-alpha.1" +source = "git+https://github.com/DioxusLabs/dioxus?rev=24f6a829df0dfa203961a98ea4cae21c2ff27e28#24f6a829df0dfa203961a98ea4cae21c2ff27e28" dependencies = [ "proc-macro2", "quote", @@ -2104,9 +2082,8 @@ dependencies = [ [[package]] name = "dioxus" -version = "0.7.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c01ecf7ddbae18a419ad3d83c486101a85ffc5740ea09cdd0f09a30dc12170d" +version = "0.8.0-alpha.1" +source = "git+https://github.com/DioxusLabs/dioxus?rev=24f6a829df0dfa203961a98ea4cae21c2ff27e28#24f6a829df0dfa203961a98ea4cae21c2ff27e28" dependencies = [ "dioxus-asset-resolver", "dioxus-cli-config", @@ -2130,9 +2107,8 @@ dependencies = [ [[package]] name = "dioxus-asset-resolver" -version = "0.7.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69387edbbc60c7cb93ad96d8cc7a22b49a76e21643380b89b1c49a78d347ff60" +version = "0.8.0-alpha.1" +source = "git+https://github.com/DioxusLabs/dioxus?rev=24f6a829df0dfa203961a98ea4cae21c2ff27e28#24f6a829df0dfa203961a98ea4cae21c2ff27e28" dependencies = [ "dioxus-cli-config", "http", @@ -2148,18 +2124,16 @@ dependencies = [ [[package]] name = "dioxus-cli-config" -version = "0.7.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c000f584ddf608e2b272b3074bf11512a474eeeb2eb85a1915f276ce5c4a8615" +version = "0.8.0-alpha.1" +source = "git+https://github.com/DioxusLabs/dioxus?rev=24f6a829df0dfa203961a98ea4cae21c2ff27e28#24f6a829df0dfa203961a98ea4cae21c2ff27e28" dependencies = [ "wasm-bindgen", ] [[package]] name = "dioxus-config-macro" -version = "0.7.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7637091592978fbfdb45a16b26bd99fd97fb1bd7e31c6a963530e00c022af321" +version = "0.8.0-alpha.1" +source = "git+https://github.com/DioxusLabs/dioxus?rev=24f6a829df0dfa203961a98ea4cae21c2ff27e28#24f6a829df0dfa203961a98ea4cae21c2ff27e28" dependencies = [ "proc-macro2", "quote", @@ -2167,18 +2141,24 @@ dependencies = [ [[package]] name = "dioxus-config-macros" -version = "0.7.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54f9ed8fc1a215ad34bb8dbae42a4ea54efbcd26ca9006bbe5cca78e511bf25f" +version = "0.8.0-alpha.1" +source = "git+https://github.com/DioxusLabs/dioxus?rev=24f6a829df0dfa203961a98ea4cae21c2ff27e28#24f6a829df0dfa203961a98ea4cae21c2ff27e28" + +[[package]] +name = "dioxus-const-vec" +version = "0.8.0-alpha.1" +source = "git+https://github.com/DioxusLabs/dioxus?rev=24f6a829df0dfa203961a98ea4cae21c2ff27e28#24f6a829df0dfa203961a98ea4cae21c2ff27e28" [[package]] name = "dioxus-core" -version = "0.7.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45887100ff0cf89abeb8b659808294fda48cd53f3b424e36407dedffcfea830b" +version = "0.8.0-alpha.1" +source = "git+https://github.com/DioxusLabs/dioxus?rev=24f6a829df0dfa203961a98ea4cae21c2ff27e28#24f6a829df0dfa203961a98ea4cae21c2ff27e28" dependencies = [ "anyhow", "const_format", + "dioxus-const-vec", + "dioxus-core-macro", + "dioxus-core-template", "dioxus-core-types", "futures-channel", "futures-util", @@ -2191,13 +2171,13 @@ dependencies = [ "slotmap", "subsecond", "tracing", + "xxhash-rust", ] [[package]] name = "dioxus-core-macro" -version = "0.7.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "370c63663dff0f24df5dfea643ca239283542c6b228a302f69b32e1d36762b7f" +version = "0.8.0-alpha.1" +source = "git+https://github.com/DioxusLabs/dioxus?rev=24f6a829df0dfa203961a98ea4cae21c2ff27e28#24f6a829df0dfa203961a98ea4cae21c2ff27e28" dependencies = [ "convert_case 0.8.0", "dioxus-rsx", @@ -2206,17 +2186,25 @@ dependencies = [ "syn", ] +[[package]] +name = "dioxus-core-template" +version = "0.8.0-alpha.1" +source = "git+https://github.com/DioxusLabs/dioxus?rev=24f6a829df0dfa203961a98ea4cae21c2ff27e28#24f6a829df0dfa203961a98ea4cae21c2ff27e28" +dependencies = [ + "dioxus-const-vec", + "serde", + "xxhash-rust", +] + [[package]] name = "dioxus-core-types" -version = "0.7.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36963eab106b169737762f9cd5ee5fd97f585989dcb2d8e30a596e97a6999009" +version = "0.8.0-alpha.1" +source = "git+https://github.com/DioxusLabs/dioxus?rev=24f6a829df0dfa203961a98ea4cae21c2ff27e28#24f6a829df0dfa203961a98ea4cae21c2ff27e28" [[package]] name = "dioxus-devtools" -version = "0.7.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2349cedbdf1b429df1f1bea61fdee0ad3dae7b2548eedfbeca82710122a57da0" +version = "0.8.0-alpha.1" +source = "git+https://github.com/DioxusLabs/dioxus?rev=24f6a829df0dfa203961a98ea4cae21c2ff27e28#24f6a829df0dfa203961a98ea4cae21c2ff27e28" dependencies = [ "dioxus-cli-config", "dioxus-core", @@ -2232,9 +2220,8 @@ dependencies = [ [[package]] name = "dioxus-devtools-types" -version = "0.7.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ab9b0f7565d1916b70915f59b89ea8054ef0a9d67a364a32bbee68ef5f3818d" +version = "0.8.0-alpha.1" +source = "git+https://github.com/DioxusLabs/dioxus?rev=24f6a829df0dfa203961a98ea4cae21c2ff27e28#24f6a829df0dfa203961a98ea4cae21c2ff27e28" dependencies = [ "dioxus-core", "serde", @@ -2243,9 +2230,8 @@ dependencies = [ [[package]] name = "dioxus-document" -version = "0.7.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37e3a5bec7ffc999ff23446a487eb5cd86111d1574a23533dd3f8b3c69a53a22" +version = "0.8.0-alpha.1" +source = "git+https://github.com/DioxusLabs/dioxus?rev=24f6a829df0dfa203961a98ea4cae21c2ff27e28#24f6a829df0dfa203961a98ea4cae21c2ff27e28" dependencies = [ "dioxus-core", "dioxus-core-macro", @@ -2262,9 +2248,8 @@ dependencies = [ [[package]] name = "dioxus-history" -version = "0.7.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a15232302d1933015fcf2d6fe9e286ad36f6e9c205a546089a0f326023bb0d2" +version = "0.8.0-alpha.1" +source = "git+https://github.com/DioxusLabs/dioxus?rev=24f6a829df0dfa203961a98ea4cae21c2ff27e28#24f6a829df0dfa203961a98ea4cae21c2ff27e28" dependencies = [ "dioxus-core", "tracing", @@ -2272,9 +2257,8 @@ dependencies = [ [[package]] name = "dioxus-hooks" -version = "0.7.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4534f91cf6305204b948bdec130076ac9ecc7c22faab29475b76870558bf73ea" +version = "0.8.0-alpha.1" +source = "git+https://github.com/DioxusLabs/dioxus?rev=24f6a829df0dfa203961a98ea4cae21c2ff27e28#24f6a829df0dfa203961a98ea4cae21c2ff27e28" dependencies = [ "dioxus-core", "dioxus-signals", @@ -2288,9 +2272,8 @@ dependencies = [ [[package]] name = "dioxus-html" -version = "0.7.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e03d6ad4040b667f2b2eefcb678840e630938c09bf9ec39b04ea4d1d96d90d44" +version = "0.8.0-alpha.1" +source = "git+https://github.com/DioxusLabs/dioxus?rev=24f6a829df0dfa203961a98ea4cae21c2ff27e28#24f6a829df0dfa203961a98ea4cae21c2ff27e28" dependencies = [ "async-trait", "bytes", @@ -2315,9 +2298,8 @@ dependencies = [ [[package]] name = "dioxus-html-internal-macro" -version = "0.7.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "584e2772127ab00f0d5e1d4d9795f39fecebc828ece0b7a02349d438bc1b1ce7" +version = "0.8.0-alpha.1" +source = "git+https://github.com/DioxusLabs/dioxus?rev=24f6a829df0dfa203961a98ea4cae21c2ff27e28#24f6a829df0dfa203961a98ea4cae21c2ff27e28" dependencies = [ "convert_case 0.8.0", "proc-macro2", @@ -2327,9 +2309,8 @@ dependencies = [ [[package]] name = "dioxus-interpreter-js" -version = "0.7.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11999d6eb5bb179a9512dad30e5de408aab66f2cb65de9098c9fbe02927e2978" +version = "0.8.0-alpha.1" +source = "git+https://github.com/DioxusLabs/dioxus?rev=24f6a829df0dfa203961a98ea4cae21c2ff27e28#24f6a829df0dfa203961a98ea4cae21c2ff27e28" dependencies = [ "js-sys", "lazy-js-bundle", @@ -2343,9 +2324,8 @@ dependencies = [ [[package]] name = "dioxus-logger" -version = "0.7.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a28ccdfe36d2cb830a2784e40f7e6f7199805a2c6da99bd65b1ca308f11aed28" +version = "0.8.0-alpha.1" +source = "git+https://github.com/DioxusLabs/dioxus?rev=24f6a829df0dfa203961a98ea4cae21c2ff27e28#24f6a829df0dfa203961a98ea4cae21c2ff27e28" dependencies = [ "dioxus-cli-config", "tracing", @@ -2412,10 +2392,10 @@ dependencies = [ [[package]] name = "dioxus-rsx" -version = "0.7.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2106afda239a4c7c22ffa1ca19117011225fc1c735c139c0a5b765996aa8bb1d" +version = "0.8.0-alpha.1" +source = "git+https://github.com/DioxusLabs/dioxus?rev=24f6a829df0dfa203961a98ea4cae21c2ff27e28#24f6a829df0dfa203961a98ea4cae21c2ff27e28" dependencies = [ + "dioxus-core-template", "proc-macro2", "proc-macro2-diagnostics", "quote", @@ -2425,9 +2405,8 @@ dependencies = [ [[package]] name = "dioxus-signals" -version = "0.7.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3705754f5e043deec9fc7af0d159f18e5b21c02c47d255c7e477f31368f0b6d2" +version = "0.8.0-alpha.1" +source = "git+https://github.com/DioxusLabs/dioxus?rev=24f6a829df0dfa203961a98ea4cae21c2ff27e28#24f6a829df0dfa203961a98ea4cae21c2ff27e28" dependencies = [ "dioxus-core", "futures-channel", @@ -2441,9 +2420,8 @@ dependencies = [ [[package]] name = "dioxus-stores" -version = "0.7.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64bec7b21c86b1360ec965a07a53a2c96b7caee3465049e1c299a45024e87614" +version = "0.8.0-alpha.1" +source = "git+https://github.com/DioxusLabs/dioxus?rev=24f6a829df0dfa203961a98ea4cae21c2ff27e28#24f6a829df0dfa203961a98ea4cae21c2ff27e28" dependencies = [ "dioxus-core", "dioxus-signals", @@ -2453,9 +2431,8 @@ dependencies = [ [[package]] name = "dioxus-stores-macro" -version = "0.7.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40a5875e9f890f27b1cc3e5b56c1e23601211470315a1fb8627c4ca4f3b2be9a" +version = "0.8.0-alpha.1" +source = "git+https://github.com/DioxusLabs/dioxus?rev=24f6a829df0dfa203961a98ea4cae21c2ff27e28#24f6a829df0dfa203961a98ea4cae21c2ff27e28" dependencies = [ "convert_case 0.8.0", "proc-macro2", @@ -2465,9 +2442,8 @@ dependencies = [ [[package]] name = "dioxus-web" -version = "0.7.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc0a0be76b404e8242a597db0fb239d05f8dee4e7856bc1fc7144f7e244822fd" +version = "0.8.0-alpha.1" +source = "git+https://github.com/DioxusLabs/dioxus?rev=24f6a829df0dfa203961a98ea4cae21c2ff27e28#24f6a829df0dfa203961a98ea4cae21c2ff27e28" dependencies = [ "dioxus-cli-config", "dioxus-core", @@ -3170,9 +3146,8 @@ dependencies = [ [[package]] name = "generational-box" -version = "0.7.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cd0d825b8d339701ad330dbcd6399519ced4d143484954daf6e3185dace4f77" +version = "0.8.0-alpha.1" +source = "git+https://github.com/DioxusLabs/dioxus?rev=24f6a829df0dfa203961a98ea4cae21c2ff27e28#24f6a829df0dfa203961a98ea4cae21c2ff27e28" dependencies = [ "parking_lot", "tracing", @@ -4286,9 +4261,8 @@ dependencies = [ [[package]] name = "lazy-js-bundle" -version = "0.7.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccafada6c9541db44db758619236f2748f6e1bdaa84d04ded858567cd1e89321" +version = "0.8.0-alpha.1" +source = "git+https://github.com/DioxusLabs/dioxus?rev=24f6a829df0dfa203961a98ea4cae21c2ff27e28#24f6a829df0dfa203961a98ea4cae21c2ff27e28" [[package]] name = "lazy_static" @@ -4561,12 +4535,10 @@ dependencies = [ [[package]] name = "manganis" -version = "0.7.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bfcf56309de35b48b8780ea097ace5c3b773a617b52edc49dfc9a63a7d9dc43" +version = "0.8.0-alpha.1" +source = "git+https://github.com/DioxusLabs/dioxus?rev=24f6a829df0dfa203961a98ea4cae21c2ff27e28#24f6a829df0dfa203961a98ea4cae21c2ff27e28" dependencies = [ - "const-serialize 0.7.2", - "const-serialize 0.8.0-alpha.0", + "const-serialize", "jni 0.21.1", "manganis-core", "manganis-macro", @@ -4577,12 +4549,10 @@ dependencies = [ [[package]] name = "manganis-core" -version = "0.7.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a24d6be68f594495aea60850a284029d585d7b7839b26096c1b6d758f8518648" +version = "0.8.0-alpha.1" +source = "git+https://github.com/DioxusLabs/dioxus?rev=24f6a829df0dfa203961a98ea4cae21c2ff27e28#24f6a829df0dfa203961a98ea4cae21c2ff27e28" dependencies = [ - "const-serialize 0.7.2", - "const-serialize 0.8.0-alpha.0", + "const-serialize", "dioxus-cli-config", "dioxus-core-types", "serde", @@ -4591,9 +4561,8 @@ dependencies = [ [[package]] name = "manganis-macro" -version = "0.7.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e782a10318d707c0833e31876ded8acf91287eee0010af8392559af614c7226" +version = "0.8.0-alpha.1" +source = "git+https://github.com/DioxusLabs/dioxus?rev=24f6a829df0dfa203961a98ea4cae21c2ff27e28#24f6a829df0dfa203961a98ea4cae21c2ff27e28" dependencies = [ "dunce", "macro-string", @@ -5086,6 +5055,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3a12a8ed07aefc768292f076dc3ac8c48f3781c8f2d5851dd3d98950e8c5a89f" dependencies = [ "objc2-encode", + "objc2-exception-helper", ] [[package]] @@ -5239,6 +5209,15 @@ version = "4.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef25abbcd74fb2609453eb695bd2f860d389e457f67dc17cafc8b8cbc89d0c33" +[[package]] +name = "objc2-exception-helper" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7a1c5fbb72d7735b076bb47b578523aedc40f3c439bea6dfd595c089d79d98a" +dependencies = [ + "cc", +] + [[package]] name = "objc2-foundation" version = "0.2.2" @@ -7297,9 +7276,8 @@ dependencies = [ [[package]] name = "subsecond" -version = "0.7.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cc79674bd55726e6b123204403389400229a95fe4a3b2c5453dada70b06ca95" +version = "0.8.0-alpha.1" +source = "git+https://github.com/DioxusLabs/dioxus?rev=24f6a829df0dfa203961a98ea4cae21c2ff27e28#24f6a829df0dfa203961a98ea4cae21c2ff27e28" dependencies = [ "js-sys", "libc", @@ -7316,9 +7294,8 @@ dependencies = [ [[package]] name = "subsecond-types" -version = "0.7.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9798bfed58797aed51c672aa99810aac30a50d3120ecfdcf28c13784e9a8f1c" +version = "0.8.0-alpha.1" +source = "git+https://github.com/DioxusLabs/dioxus?rev=24f6a829df0dfa203961a98ea4cae21c2ff27e28#24f6a829df0dfa203961a98ea4cae21c2ff27e28" dependencies = [ "serde", ] diff --git a/Cargo.toml b/Cargo.toml index be4987b6bc..f1f0d5eac4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -77,23 +77,23 @@ smallvec = "1" thin-vec = "0.2" # DioxusLabs dependencies -dioxus = { version = "0.7.3" } -dioxus-core = { version = "0.7.3" } -dioxus-html = { version = "0.7.3" } -dioxus-hooks = { version = "0.7.3" } -dioxus-signals = { version = "0.7.3" } -dioxus-stores = { version = "0.7.3" } -dioxus-asset-resolver = { version = "0.7.3" } -manganis = { version = "0.7.3" } -dioxus-document = { version = "0.7.3" } -dioxus-history = { version = "0.7.3" } +dioxus = { git = "https://github.com/DioxusLabs/dioxus", rev = "24f6a829df0dfa203961a98ea4cae21c2ff27e28" } +dioxus-core = { git = "https://github.com/DioxusLabs/dioxus", rev = "24f6a829df0dfa203961a98ea4cae21c2ff27e28" } +dioxus-html = { git = "https://github.com/DioxusLabs/dioxus", rev = "24f6a829df0dfa203961a98ea4cae21c2ff27e28" } +dioxus-hooks = { git = "https://github.com/DioxusLabs/dioxus", rev = "24f6a829df0dfa203961a98ea4cae21c2ff27e28" } +dioxus-signals = { git = "https://github.com/DioxusLabs/dioxus", rev = "24f6a829df0dfa203961a98ea4cae21c2ff27e28" } +dioxus-stores = { git = "https://github.com/DioxusLabs/dioxus", rev = "24f6a829df0dfa203961a98ea4cae21c2ff27e28" } +dioxus-asset-resolver = { git = "https://github.com/DioxusLabs/dioxus", rev = "24f6a829df0dfa203961a98ea4cae21c2ff27e28" } +manganis = { git = "https://github.com/DioxusLabs/dioxus", rev = "24f6a829df0dfa203961a98ea4cae21c2ff27e28" } +dioxus-document = { git = "https://github.com/DioxusLabs/dioxus", rev = "24f6a829df0dfa203961a98ea4cae21c2ff27e28" } +dioxus-history = { git = "https://github.com/DioxusLabs/dioxus", rev = "24f6a829df0dfa203961a98ea4cae21c2ff27e28" } # Dioxus hot reload -dioxus-devtools = { version = "0.7.3" } -dioxus-cli-config = { version = "0.7.3" } +dioxus-devtools = { git = "https://github.com/DioxusLabs/dioxus", rev = "24f6a829df0dfa203961a98ea4cae21c2ff27e28" } +dioxus-cli-config = { git = "https://github.com/DioxusLabs/dioxus", rev = "24f6a829df0dfa203961a98ea4cae21c2ff27e28" } # Dioxus Prelude -dioxus-core-macro = { version = "0.7.3" } +dioxus-core-macro = { git = "https://github.com/DioxusLabs/dioxus", rev = "24f6a829df0dfa203961a98ea4cae21c2ff27e28" } # Taffy + Parley + Fontations taffy = { git = "https://github.com/DioxusLabs/taffy", rev = "4ae4219b34e0ad22fd907cb1a7fa9a68c1ea1621", default-features = false, features = [ diff --git a/apps/browser/src/browser_history.rs b/apps/browser/src/browser_history.rs index 3fc15b2b1a..b9cc26f0d9 100644 --- a/apps/browser/src/browser_history.rs +++ b/apps/browser/src/browser_history.rs @@ -26,21 +26,21 @@ impl BrowsingHistory { #[store(pub)] impl Store { - fn record_visit(&self, entry: HistoryEntry) -> HistoryEntryId + pub fn record_visit(&self, entry: HistoryEntry) -> HistoryEntryId where Lens: Writable, { record_visit_inner(&mut self.entries().write(), entry) } - fn set_favicon_by_id(&self, id: HistoryEntryId, favicon_url: Url) + pub fn set_favicon_by_id(&self, id: HistoryEntryId, favicon_url: Url) where Lens: Writable, { set_favicon_by_id_inner(&mut self.entries().write(), id, favicon_url); } - fn clear(&self) + pub fn clear(&self) where Lens: Writable, { diff --git a/apps/browser/src/tab.rs b/apps/browser/src/tab.rs index 0446611877..0486279684 100644 --- a/apps/browser/src/tab.rs +++ b/apps/browser/src/tab.rs @@ -38,34 +38,34 @@ pub struct Tab { #[store(pub)] impl Store { - fn nav_history(&self) -> SyncStore { + pub fn nav_history(&self) -> SyncStore { *self.history().read() } - fn loader_rc(&self) -> Rc { + pub fn loader_rc(&self) -> Rc { // `open_tab` always assigns Some(loader) immediately after pushing the // tab, so by the time any view code can call this the loader is set. #[allow(clippy::expect_used)] self.loader().cloned().expect("loader uninitialized") } - fn tab_id(&self) -> TabId { + pub fn tab_id(&self) -> TabId { *self.id().read() } - fn navigate(&self, req: Request) { + pub fn navigate(&self, req: Request) { self.nav_history().navigate(req); } - fn reload(&self) { + pub fn reload(&self) { self.loader_rc().reload(); } - fn go_back(&self) { + pub fn go_back(&self) { self.nav_history().go_back(); } - fn go_forward(&self) { + pub fn go_forward(&self) { self.nav_history().go_forward(); } @@ -73,7 +73,7 @@ impl Store { // through the document loader, so this is the only place their title is // set and the only place a stale favicon from a previous real page gets // cleared. - fn commit_about_chrome(&self, page: AboutPage) + pub fn commit_about_chrome(&self, page: AboutPage) where Lens: Writable, { diff --git a/examples/transforms.rs b/examples/transforms.rs index 50222a4707..b922907e94 100644 --- a/examples/transforms.rs +++ b/examples/transforms.rs @@ -60,7 +60,7 @@ fn app() -> Element { let coords = evt.client_coordinates(); if evt .held_buttons() - .contains(dioxus_elements::input_data::MouseButton::Auxiliary) + .contains(dioxus_html::input_data::MouseButton::Auxiliary) { active_pointer.set(true); last.set([coords.x as f32, coords.y as f32]); @@ -88,13 +88,9 @@ fn app() -> Element { let sensitivity = 0.001; let delta = match e.delta() { - dioxus_elements::geometry::WheelDelta::Pixels(data) => data.y as f32 * sensitivity, - dioxus_elements::geometry::WheelDelta::Lines(data) => { - data.y as f32 * sensitivity * 16.0 - } - dioxus_elements::geometry::WheelDelta::Pages(data) => { - data.y as f32 * sensitivity * 400.0 - } + dioxus_html::geometry::WheelDelta::Pixels(data) => data.y as f32 * sensitivity, + dioxus_html::geometry::WheelDelta::Lines(data) => data.y as f32 * sensitivity * 16.0, + dioxus_html::geometry::WheelDelta::Pages(data) => data.y as f32 * sensitivity * 400.0, }; let factor = (1.0 + delta).clamp(0.8, 1.2); diff --git a/packages/dioxus-native-dom/src/dioxus_document.rs b/packages/dioxus-native-dom/src/dioxus_document.rs index ab0ade88a5..e0909c37fa 100644 --- a/packages/dioxus-native-dom/src/dioxus_document.rs +++ b/packages/dioxus-native-dom/src/dioxus_document.rs @@ -4,7 +4,7 @@ use crate::events::{ BlitzKeyboardData, NativeConverter, NativeFocusData, NativeFormData, NativePointerData, NativeScrollData, NativeTouchData, NativeWheelData, NodeHandle, }; -use crate::mutation_writer::{DioxusState, MutationWriter}; +use crate::mutation_writer::DioxusState; use crate::qual_name; use blitz_dom::{ Attribute, BaseDocument, DEFAULT_CSS, DocGuard, DocGuardMut, Document, DocumentConfig, @@ -33,7 +33,7 @@ fn get_dioxus_id(node: &Node) -> Option { .iter() .find(|attr| *attr.name.local == *"data-dioxus-id") .and_then(|attr| attr.value.parse::().ok()) - .map(ElementId) + .map(ElementId::from_raw) } /// Integrates [`BaseDocument`] from [`blitz-dom`](blitz_dom) with [`VirtualDom`] from [`dioxus-core`](dioxus_core) @@ -145,7 +145,7 @@ impl DioxusDocument { /// Run an initial build of the Dioxus vdom pub fn initial_build(&mut self) { let mut inner = self.inner.borrow_mut(); - let mut writer = MutationWriter::new(&mut inner, &mut self.vdom_state); + let mut writer = self.vdom_state.writer(&mut inner); self.vdom.rebuild(&mut writer); drop(writer); drop(inner); @@ -241,7 +241,7 @@ impl Document for DioxusDocument { } let mut inner = self.inner.borrow_mut(); - let mut writer = MutationWriter::new(&mut inner, &mut self.vdom_state); + let mut writer = self.vdom_state.writer(&mut inner); self.vdom.render_immediate(&mut writer); drop(writer); drop(inner); diff --git a/packages/dioxus-native-dom/src/events.rs b/packages/dioxus-native-dom/src/events.rs index e20ce059a7..b93829961d 100644 --- a/packages/dioxus-native-dom/src/events.rs +++ b/packages/dioxus-native-dom/src/events.rs @@ -7,9 +7,9 @@ use blitz_traits::events::{ BlitzWheelEvent, MouseEventButton, }; use dioxus_html::{ - AnimationData, CancelData, ClipboardData, CompositionData, DragData, FocusData, FormData, - FormValue, HasFileData, HasFocusData, HasFormData, HasKeyboardData, HasMouseData, - HasPointerData, HasScrollData, HasTouchData, HasTouchPointData, HasWheelData, + AnimationData, BeforeInputData, CancelData, ClipboardData, CompositionData, DragData, + FocusData, FormData, FormValue, HasFileData, HasFocusData, HasFormData, HasKeyboardData, + HasMouseData, HasPointerData, HasScrollData, HasTouchData, HasTouchPointData, HasWheelData, HtmlEventConverter, ImageData, KeyboardData, MediaData, MountedData, MountedError, MountedResult, MouseData, PlatformEventData, PointerData, RenderedElementBacking, ResizeData, ScrollBehavior, ScrollData, ScrollLogicalPosition, ScrollToOptions, SelectionData, ToggleData, @@ -71,6 +71,12 @@ impl HtmlEventConverter for NativeConverter { unimplemented!("todo: convert_animation_data in dioxus-native. requires support in blitz") } + fn convert_before_input_data(&self, _event: &PlatformEventData) -> BeforeInputData { + unimplemented!( + "todo: convert_before_input_data in dioxus-native. requires support in blitz" + ) + } + fn convert_clipboard_data(&self, _event: &PlatformEventData) -> ClipboardData { unimplemented!("todo: convert_clipboard_data in dioxus-native. requires support in blitz") } diff --git a/packages/dioxus-native-dom/src/mutation_writer.rs b/packages/dioxus-native-dom/src/mutation_writer.rs index a8f2f9f7e1..995c70e9d5 100644 --- a/packages/dioxus-native-dom/src/mutation_writer.rs +++ b/packages/dioxus-native-dom/src/mutation_writer.rs @@ -2,23 +2,241 @@ use crate::{NodeId, qual_name, trace, write_once_attr::WriteOnceAttr}; use blitz_dom::{BaseDocument, Document, DocumentMutator, Widget}; use blitz_traits::events::DomEventKind; -use dioxus_core::{ - AttributeValue, ElementId, Template, TemplateAttribute, TemplateNode, WriteMutations, -}; -use rustc_hash::FxHashMap; +use dioxus_core::{AttributeValue, ElementId, WriteMutations}; use std::str::FromStr as _; +pub(crate) trait RealDom { + type NodeId: Copy; + + fn create_element(&mut self, tag: &str, ns: Option<&str>) -> Self::NodeId; + + fn create_text(&mut self, value: &str) -> Self::NodeId; + + fn deep_clone(&mut self, node: Self::NodeId) -> Self::NodeId; + + fn nth_child(&mut self, parent: Self::NodeId, index: usize) -> Self::NodeId; + + fn append_children(&mut self, parent: Self::NodeId, children: &[Self::NodeId]); + + fn insert_after(&mut self, anchor: Self::NodeId, nodes: &[Self::NodeId]); + + fn insert_before(&mut self, anchor: Self::NodeId, nodes: &[Self::NodeId]); + + fn replace(&mut self, target: Self::NodeId, replacements: &[Self::NodeId]); + + fn remove(&mut self, node: Self::NodeId); + + fn set_attribute( + &mut self, + node: Self::NodeId, + name: &str, + ns: Option<&str>, + value: &AttributeValue, + ); + + fn set_text(&mut self, node: Self::NodeId, value: &str); + + fn add_event_listener(&mut self, node: Self::NodeId, element_id: ElementId, name: &str); + + fn remove_event_listener(&mut self, node: Self::NodeId, element_id: ElementId, name: &str); +} + +#[derive(Clone, Copy, Debug)] +struct StackEntry { + node: N, + element_id: Option, +} + +#[derive(Debug)] +struct StackState { + stack: Vec>, + element_to_node: Vec>, +} + +impl StackState { + fn new(root: N) -> Self { + Self { + stack: vec![StackEntry { + node: root, + element_id: Some(ElementId::ROOT), + }], + element_to_node: vec![Some(root)], + } + } + + fn element_to_node(&self, id: ElementId) -> Option { + self.element_to_node.get(id.raw()).copied().flatten() + } + + fn lookup(&self, id: ElementId) -> N { + self.element_to_node(id) + .unwrap_or_else(|| panic!("renderer asked for unknown ElementId {}", id.raw())) + } + + fn set_mapping(&mut self, id: ElementId, node: N) { + let index = id.raw(); + if self.element_to_node.len() <= index { + self.element_to_node.resize(index + 1, None); + } + self.element_to_node[index] = Some(node); + } + + fn clear_mapping(&mut self, entry: StackEntry) { + if let Some(id) = entry.element_id + && let Some(slot) = self.element_to_node.get_mut(id.raw()) + { + *slot = None; + } + } + + fn push(&mut self, node: N, element_id: Option) { + self.stack.push(StackEntry { node, element_id }); + } + + fn pop_entry(&mut self) -> StackEntry { + self.stack.pop().expect("renderer stack unexpectedly empty") + } + + fn top(&self) -> StackEntry { + *self + .stack + .last() + .expect("renderer stack unexpectedly empty") + } + + fn replace_top(&mut self, node: N) { + *self + .stack + .last_mut() + .expect("renderer stack unexpectedly empty") = StackEntry { + node, + element_id: None, + }; + } + + fn pop_nodes(&mut self, m: usize) -> Vec { + let split = self.stack.len() - m; + self.stack + .split_off(split) + .into_iter() + .map(|entry| entry.node) + .collect() + } +} + +pub(crate) struct StackWriter<'a, R: RealDom> { + state: &'a mut StackState, + backend: R, +} + +impl<'a, R: RealDom> StackWriter<'a, R> { + fn new(state: &'a mut StackState, backend: R) -> Self { + Self { state, backend } + } +} + +impl WriteMutations for StackWriter<'_, R> { + fn push_id(&mut self, id: ElementId) { + let node = self.state.lookup(id); + self.state.push(node, Some(id)); + } + + fn set_id(&mut self, id: ElementId) { + let node = self.state.top().node; + self.state.set_mapping(id, node); + } + + fn child(&mut self, index: usize) { + let parent = self.state.top().node; + let child = self.backend.nth_child(parent, index); + self.state.replace_top(child); + } + + fn pop(&mut self) { + self.state.pop_entry(); + } + + fn create_element(&mut self, tag: &str, ns: Option<&str>) { + let node = self.backend.create_element(tag, ns); + self.state.push(node, None); + } + + fn create_text(&mut self, value: &str) { + let node = self.backend.create_text(value); + self.state.push(node, None); + } + + fn clone(&mut self) { + let node = self.state.top().node; + let cloned = self.backend.deep_clone(node); + self.state.replace_top(cloned); + } + + fn append_children(&mut self, m: usize) { + let children = self.state.pop_nodes(m); + let parent = self.state.top().node; + self.backend.append_children(parent, &children); + } + + fn replace_with(&mut self, m: usize) { + let replacements = self.state.pop_nodes(m); + let target = self.state.pop_entry(); + self.backend.replace(target.node, &replacements); + self.state.clear_mapping(target); + } + + fn insert_after(&mut self, m: usize) { + let nodes = self.state.pop_nodes(m); + let anchor = self.state.top().node; + self.backend.insert_after(anchor, &nodes); + } + + fn insert_before(&mut self, m: usize) { + let nodes = self.state.pop_nodes(m); + let anchor = self.state.top().node; + self.backend.insert_before(anchor, &nodes); + } + + fn set_attribute(&mut self, name: &str, ns: Option<&str>, value: &AttributeValue) { + let node = self.state.top().node; + self.backend.set_attribute(node, name, ns, value); + } + + fn set_text(&mut self, value: &str) { + let node = self.state.top().node; + self.backend.set_text(node, value); + } + + fn add_event_listener(&mut self, name: &str) { + let entry = self.state.top(); + let element_id = entry + .element_id + .expect("event listener target must be mapped to an ElementId"); + self.backend + .add_event_listener(entry.node, element_id, name); + } + + fn remove_event_listener(&mut self, name: &str) { + let entry = self.state.top(); + let element_id = entry + .element_id + .expect("event listener target must be mapped to an ElementId"); + self.backend + .remove_event_listener(entry.node, element_id, name); + } + + fn remove(&mut self) { + let entry = self.state.pop_entry(); + self.backend.remove(entry.node); + self.state.clear_mapping(entry); + } +} + /// The state of the Dioxus integration with the RealDom #[derive(Debug)] pub struct DioxusState { - /// Store of templates keyed by unique name - pub(crate) templates: FxHashMap>, /// Stack machine state for applying dioxus mutations - pub(crate) stack: Vec, - /// Mapping from vdom ElementId -> rdom NodeId - pub(crate) node_id_mapping: Vec>, - /// Reverse mapping from rdom NodeId -> vdom ElementId - pub(crate) element_id_mapping: FxHashMap, + stack: StackState, /// Count of each handler type (indexed by `DomEventKind` discriminant) pub(crate) event_handler_counts: [u32; 64], /// Mounted events queued as elements are mounted @@ -29,10 +247,7 @@ impl DioxusState { /// Initialize the DioxusState in the RealDom pub fn create(root_id: NodeId) -> Self { Self { - templates: FxHashMap::default(), - stack: vec![root_id], - node_id_mapping: vec![Some(root_id)], - element_id_mapping: FxHashMap::from_iter([(root_id, ElementId(0))]), + stack: StackState::new(root_id), event_handler_counts: [0; 64], queued_mounted_events: Vec::new(), } @@ -45,173 +260,145 @@ impl DioxusState { /// Attempt to convert an ElementId to a NodeId. This will return None if the ElementId is not in the RealDom. pub fn try_element_to_node_id(&self, element_id: ElementId) -> Option { - self.node_id_mapping.get(element_id.0).copied().flatten() + self.stack.element_to_node(element_id) } - pub(crate) fn anchor_and_nodes(&mut self, id: ElementId, m: usize) -> (NodeId, Vec) { - let anchor_node_id = self.element_to_node_id(id); - let new_nodes = self.m_stack_nodes(m); - (anchor_node_id, new_nodes) - } - - pub(crate) fn m_stack_nodes(&mut self, m: usize) -> Vec { - self.stack.split_off(self.stack.len() - m) - } - - pub(crate) fn queue_mount_event(&mut self, id: ElementId) { - self.queued_mounted_events.push(id); + /// Build a writer that applies dioxus mutations to `doc`, driving the blitz + /// backend from the local stack machine. + pub(crate) fn writer<'a>(&'a mut self, doc: &'a mut BaseDocument) -> MutationWriter<'a> { + let Self { + stack, + event_handler_counts, + queued_mounted_events, + } = self; + StackWriter::new( + stack, + BlitzBackend { + docm: doc.mutate(), + event_handler_counts, + queued_mounted_events, + }, + ) } } /// A writer for mutations that can be used with the RealDom. -pub struct MutationWriter<'a> { - /// The realdom associated with this writer - pub docm: DocumentMutator<'a>, - /// The state associated with this writer - pub state: &'a mut DioxusState, -} - -impl<'a> MutationWriter<'a> { - pub fn new(doc: &'a mut BaseDocument, state: &'a mut DioxusState) -> Self { - MutationWriter { - docm: doc.mutate(), - state, - } - } +/// +/// The stack-machine bookkeeping lives in [`StackWriter`]; this renderer only +/// supplies the real tree semantics via [`BlitzBackend`]. +pub(crate) type MutationWriter<'a> = StackWriter<'a, BlitzBackend<'a>>; + +/// The blitz-backed "real semantics" for the dioxus stack machine. +pub(crate) struct BlitzBackend<'a> { + /// The realdom mutation handle associated with this writer + docm: DocumentMutator<'a>, + /// Count of each handler type, kept so event dispatch can skip unused kinds + event_handler_counts: &'a mut [u32; 64], + /// Mounted events queued as elements are mounted + queued_mounted_events: &'a mut Vec, } -impl MutationWriter<'_> { - /// Update an ElementId -> NodeId mapping - fn set_id_mapping(&mut self, node_id: NodeId, element_id: ElementId) { - let element_id: usize = element_id.0; - - // Ensure node_id_mapping is large enough to contain element_id - if self.state.node_id_mapping.len() <= element_id { - self.state.node_id_mapping.resize(element_id + 1, None); - } +impl RealDom for BlitzBackend<'_> { + type NodeId = NodeId; - // Set the new mapping (and keep the reverse mapping in sync) - if let Some(old_node_id) = self.state.node_id_mapping[element_id].replace(node_id) - && self.state.element_id_mapping.get(&old_node_id) == Some(&ElementId(element_id)) - { - self.state.element_id_mapping.remove(&old_node_id); - } - self.state - .element_id_mapping - .insert(node_id, ElementId(element_id)); + fn create_element(&mut self, tag: &str, ns: Option<&str>) -> NodeId { + trace!("create_element tag:{tag} ns:{ns:?}"); + self.docm.create_element(qual_name(tag, ns), Vec::new()) } - /// Create a ElementId -> NodeId mapping and push the node to the stack - fn map_new_node(&mut self, node_id: NodeId, element_id: ElementId) { - self.set_id_mapping(node_id, element_id); - self.state.stack.push(node_id); + fn create_text(&mut self, value: &str) -> NodeId { + trace!("create_text text:{value}"); + self.docm.create_text_node(value) } - /// Find a child in the document by child index path - fn load_child(&self, path: &[u8]) -> NodeId { - let top_of_stack_node_id = *self.state.stack.last().unwrap(); - self.docm.node_at_path(top_of_stack_node_id, path) + fn deep_clone(&mut self, node: NodeId) -> NodeId { + trace!("clone node:{node}"); + self.docm.deep_clone_node(node) } -} -impl WriteMutations for MutationWriter<'_> { - fn assign_node_id(&mut self, path: &'static [u8], id: ElementId) { - trace!("assign_node_id path:{:?} id:{}", path, id.0); - - // If there is an existing node already mapped to that ID and it has no parent, then drop it. - // Dropping the node also drops all of its descendants, so clear the mappings of every - // dropped node to prevent them dangling and aliasing onto unrelated nodes when the - // underlying slab slots are reused. - // TODO: more automated GC/ref-counted semantics for node lifetimes - if let Some(node_id) = self.state.try_element_to_node_id(id) { - let state = &mut *self.state; - self.docm - .remove_node_if_unparented_with(node_id, &mut |dropped_node_id| { - if let Some(element_id) = state.element_id_mapping.remove(&dropped_node_id) - && state.node_id_mapping.get(element_id.0).copied().flatten() - == Some(dropped_node_id) - { - state.node_id_mapping[element_id.0] = None; - } - }); - } - - // Map the node at specified path - self.set_id_mapping(self.load_child(path), id); + fn nth_child(&mut self, parent: NodeId, index: usize) -> NodeId { + trace!("nth_child parent:{parent} index:{index}"); + self.docm.child_ids(parent)[index] } - fn create_placeholder(&mut self, id: ElementId) { - trace!("create_placeholder id:{}", id.0); - let node_id = self.docm.create_comment_node(""); - self.map_new_node(node_id, id); + fn append_children(&mut self, parent: NodeId, children: &[NodeId]) { + trace!("append_children parent:{parent} children:{children:?}"); + self.docm.append_children(parent, children); } - fn create_text_node(&mut self, value: &str, id: ElementId) { - trace!("create_text_node id:{} text:{}", id.0, value); - let node_id = self.docm.create_text_node(value); - self.map_new_node(node_id, id); + fn insert_after(&mut self, anchor: NodeId, nodes: &[NodeId]) { + trace!("insert_after anchor:{anchor} nodes:{nodes:?}"); + self.docm.insert_nodes_after(anchor, nodes); } - fn append_children(&mut self, id: ElementId, m: usize) { - trace!("append_children id:{} m:{}", id.0, m); - let (parent_id, child_node_ids) = self.state.anchor_and_nodes(id, m); - self.docm.append_children(parent_id, &child_node_ids); + fn insert_before(&mut self, anchor: NodeId, nodes: &[NodeId]) { + trace!("insert_before anchor:{anchor} nodes:{nodes:?}"); + self.docm.insert_nodes_before(anchor, nodes); } - fn insert_nodes_after(&mut self, id: ElementId, m: usize) { - trace!("insert_nodes_after id:{} m:{}", id.0, m); - let (anchor_node_id, new_node_ids) = self.state.anchor_and_nodes(id, m); - self.docm.insert_nodes_after(anchor_node_id, &new_node_ids); + fn replace(&mut self, target: NodeId, replacements: &[NodeId]) { + trace!("replace target:{target} replacements:{replacements:?}"); + self.docm.replace_node_with(target, replacements); } - fn insert_nodes_before(&mut self, id: ElementId, m: usize) { - trace!("insert_nodes_before id:{} m:{}", id.0, m); - let (anchor_node_id, new_node_ids) = self.state.anchor_and_nodes(id, m); - self.docm.insert_nodes_before(anchor_node_id, &new_node_ids); + fn remove(&mut self, node: NodeId) { + trace!("remove node:{node}"); + self.docm.remove_node(node); } - fn replace_node_with(&mut self, id: ElementId, m: usize) { - trace!("replace_node_with id:{} m:{}", id.0, m); - let (anchor_node_id, new_node_ids) = self.state.anchor_and_nodes(id, m); - self.docm.replace_node_with(anchor_node_id, &new_node_ids); + fn set_attribute( + &mut self, + node: NodeId, + name: &str, + ns: Option<&str>, + value: &AttributeValue, + ) { + self.set_attribute_impl(node, name, ns, value); } - fn replace_placeholder_with_nodes(&mut self, path: &'static [u8], m: usize) { - trace!("replace_placeholder_with_nodes path:{:?} m:{}", path, m); - // WARNING: DO NOT REORDER - // The order of the following two lines is very important as "m_stack_nodes" mutates - // the stack and then "load_child" reads from the top of the stack. - let new_node_ids = self.state.m_stack_nodes(m); - let anchor_node_id = self.load_child(path); - self.docm.replace_node_with(anchor_node_id, &new_node_ids); + fn set_text(&mut self, node: NodeId, value: &str) { + trace!("set_text node:{node} value:{value}"); + self.docm.set_node_text(node, value); } - fn remove_node(&mut self, id: ElementId) { - trace!("remove_node id:{}", id.0); - let node_id = self.state.element_to_node_id(id); - self.docm.remove_node(node_id); - } + fn add_event_listener(&mut self, node: NodeId, element_id: ElementId, name: &str) { + // Mounted events are fired immediately after the element is mounted. + if name == "mounted" { + self.queued_mounted_events.push(element_id); + return; + } + + // We're going to actually set the listener here as a placeholder - in JS this would also be a placeholder + // we might actually just want to attach the attribute to the root element (delegation) + let value = AttributeValue::Text("".into()); + self.set_attribute_impl(node, name, None, &value); + + // Also set the data-dioxus-id attribute so we can find the element later + let value = AttributeValue::Text(element_id.raw().to_string()); + self.set_attribute_impl(node, "data-dioxus-id", None, &value); - fn push_root(&mut self, id: ElementId) { - trace!("push_root id:{}", id.0); - let node_id = self.state.element_to_node_id(id); - self.state.stack.push(node_id); + if let Ok(kind) = DomEventKind::from_str(name) { + let idx = kind.discriminant() as usize; + self.event_handler_counts[idx] += 1; + } } - fn set_node_text(&mut self, value: &str, id: ElementId) { - trace!("set_node_text id:{} value:{}", id.0, value); - let node_id = self.state.element_to_node_id(id); - self.docm.set_node_text(node_id, value); + fn remove_event_listener(&mut self, _node: NodeId, _element_id: ElementId, name: &str) { + if let Ok(kind) = DomEventKind::from_str(name) { + let idx = kind.discriminant() as usize; + self.event_handler_counts[idx] -= 1; + } } +} - fn set_attribute( +impl BlitzBackend<'_> { + fn set_attribute_impl( &mut self, - local_name: &'static str, - ns: Option<&'static str>, + node_id: NodeId, + local_name: &str, + ns: Option<&str>, value: &AttributeValue, - id: ElementId, ) { - let node_id = self.state.element_to_node_id(id); fn is_falsy(val: &AttributeValue) -> bool { match val { AttributeValue::None => true, @@ -286,101 +473,12 @@ impl WriteMutations for MutationWriter<'_> { } }; } - - fn load_template(&mut self, template: Template, index: usize, id: ElementId) { - // TODO: proper template node support - let template_entry = self.state.templates.entry(template).or_insert_with(|| { - let template_root_ids: Vec = template - .roots - .iter() - .map(|root| create_template_node(&mut self.docm, root)) - .collect(); - - template_root_ids - }); - - let template_node_id = template_entry[index]; - let clone_id = self.docm.deep_clone_node(template_node_id); - - trace!("load_template template_node_id:{template_node_id} clone_id:{clone_id}"); - self.map_new_node(clone_id, id); - } - - fn create_event_listener(&mut self, name: &'static str, id: ElementId) { - // Mounted events are fired immediately after the element is mounted. - if name == "mounted" { - self.state.queue_mount_event(id); - return; - } - - // We're going to actually set the listener here as a placeholder - in JS this would also be a placeholder - // we might actually just want to attach the attribute to the root element (delegation) - let value = AttributeValue::Text("".into()); - self.set_attribute(name, None, &value, id); - - // Also set the data-dioxus-id attribute so we can find the element later - let value = AttributeValue::Text(id.0.to_string()); - self.set_attribute("data-dioxus-id", None, &value, id); - - // node.add_event_listener(name); - - if let Ok(kind) = DomEventKind::from_str(name) { - let idx = kind.discriminant() as usize; - self.state.event_handler_counts[idx] += 1; - } - } - - fn remove_event_listener(&mut self, name: &'static str, _id: ElementId) { - if let Ok(kind) = DomEventKind::from_str(name) { - let idx = kind.discriminant() as usize; - self.state.event_handler_counts[idx] -= 1; - } - } -} - -fn create_template_node(docm: &mut DocumentMutator<'_>, node: &TemplateNode) -> NodeId { - match node { - TemplateNode::Element { - tag, - namespace, - attrs, - children, - } => { - let name = qual_name(tag, *namespace); - // let attrs = attrs.iter().filter_map(map_template_attr).collect(); - let node_id = docm.create_element(name, Vec::new()); - - for attr in attrs.iter() { - let TemplateAttribute::Static { - name, - value, - namespace, - } = attr - else { - continue; - }; - let falsy = *value == "false"; - set_attribute_inner(docm, name, *namespace, Some(value), falsy, node_id); - } - - let child_ids: Vec = children - .iter() - .map(|child| create_template_node(docm, child)) - .collect(); - - docm.append_children(node_id, &child_ids); - - node_id - } - TemplateNode::Text { text } => docm.create_text_node(text), - TemplateNode::Dynamic { .. } => docm.create_comment_node(""), - } } fn set_attribute_inner( docm: &mut DocumentMutator<'_>, - local_name: &'static str, - ns: Option<&'static str>, + local_name: &str, + ns: Option<&str>, value: Option<&str>, is_falsy: bool, node_id: NodeId, diff --git a/packages/dioxus-native/src/prelude.rs b/packages/dioxus-native/src/prelude.rs index dbe278da6e..a96dec4990 100644 --- a/packages/dioxus-native/src/prelude.rs +++ b/packages/dioxus-native/src/prelude.rs @@ -8,11 +8,11 @@ pub use dioxus_core::{ }; #[allow(deprecated)] pub use dioxus_core_macro::{Props, component, rsx}; -pub use dioxus_html as dioxus_elements; +pub use dioxus_html::{self, html}; pub use dioxus_html::{Code, Key, Location, Modifiers}; pub use dioxus_html::{ - GlobalAttributesExtension, SvgAttributesExtension, events::*, extensions::*, global_attributes, - keyboard_types, svg_attributes, traits::*, + GlobalAttributesExtension, SvgAttributesExtension, elements::prelude::*, events::*, + extensions::*, keyboard_types, traits::*, }; // Assets diff --git a/tests/blitz-tests/tests/stale_node_mapping.rs b/tests/blitz-tests/tests/stale_node_mapping.rs index 0dbeb0f7c1..95ec98ad28 100644 --- a/tests/blitz-tests/tests/stale_node_mapping.rs +++ b/tests/blitz-tests/tests/stale_node_mapping.rs @@ -76,7 +76,7 @@ fn assert_no_stale_mappings(doc: &DioxusDocument, context: &str) { let inner = doc.inner.borrow(); let mut stale = Vec::new(); for raw_id in 0..4096 { - let element_id = dioxus_core::ElementId(raw_id); + let element_id = dioxus_core::ElementId::from_raw(raw_id); if let Some(node_id) = doc.vdom_state.try_element_to_node_id(element_id) && inner.get_node(node_id).is_none() { From 2496ce7734784669d2291f62f1867fb4aa401587 Mon Sep 17 00:00:00 2001 From: Nico Burns Date: Thu, 20 Aug 2026 13:32:27 +0000 Subject: [PATCH 2/2] Fix dioxus-stores visibility error in browser history store on latest stable --- apps/browser/src/history.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/browser/src/history.rs b/apps/browser/src/history.rs index 9dd344b265..83fd81d985 100644 --- a/apps/browser/src/history.rs +++ b/apps/browser/src/history.rs @@ -19,7 +19,7 @@ impl History { } } -#[store] +#[store(pub(self))] impl Store { fn current_idx(&self) -> usize { *self.current().read()