Merge branch 'master' into breaking
This commit is contained in:
29 files changed
+684
-258
No files matched your search
Generated
+71
-58
@@ -605,7 +605,7 @@ version = "0.5.3"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "41e7771d4ab6635cbd685ce8db215b29c78a468098126de77c57f3b2e6eb3757"
|
checksum = "41e7771d4ab6635cbd685ce8db215b29c78a468098126de77c57f3b2e6eb3757"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"dirs 5.0.1",
|
"dirs",
|
||||||
"git2",
|
"git2",
|
||||||
"terminal-prompt",
|
"terminal-prompt",
|
||||||
]
|
]
|
||||||
@@ -1075,7 +1075,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "bf4918709cc4dd777ad2b6303ed03cb37f3ca0ccede8c1b0d28ac6db8f4710e0"
|
checksum = "bf4918709cc4dd777ad2b6303ed03cb37f3ca0ccede8c1b0d28ac6db8f4710e0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"proc-macro-crate 2.0.1",
|
"proc-macro-crate 2.0.0",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.48",
|
"syn 2.0.48",
|
||||||
@@ -1250,9 +1250,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cargo-generate"
|
name = "cargo-generate"
|
||||||
version = "0.18.5"
|
version = "0.19.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8a2885ae054e000b117515ab33e91c10eca90c2788a7baec1b97ada1f1f51e57"
|
checksum = "92c1b6f44358912a9538fa3b6ac8d3aa3f585444f9dc32f12ed85d1545a9df9f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"auth-git2",
|
"auth-git2",
|
||||||
@@ -1284,7 +1284,7 @@ dependencies = [
|
|||||||
"serde",
|
"serde",
|
||||||
"tempfile",
|
"tempfile",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"toml 0.8.2",
|
"toml 0.8.8",
|
||||||
"walkdir",
|
"walkdir",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -1350,6 +1350,20 @@ dependencies = [
|
|||||||
"thiserror",
|
"thiserror",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cargo_metadata"
|
||||||
|
version = "0.18.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2d886547e41f740c616ae73108f6eb70afe6d940c7bc697cb30f13daec073037"
|
||||||
|
dependencies = [
|
||||||
|
"camino",
|
||||||
|
"cargo-platform",
|
||||||
|
"semver",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"thiserror",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cargo_toml"
|
name = "cargo_toml"
|
||||||
version = "0.16.3"
|
version = "0.16.3"
|
||||||
@@ -1357,7 +1371,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "e3f9629bc6c4388ea699781dc988c2b99766d7679b151c81990b4fa1208fafd3"
|
checksum = "e3f9629bc6c4388ea699781dc988c2b99766d7679b151c81990b4fa1208fafd3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
"toml 0.8.2",
|
"toml 0.8.8",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cargo_toml"
|
||||||
|
version = "0.18.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "802b755090e39835a4b0440fb0bbee0df7495a8b337f63db21e616f7821c7e8c"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
"toml 0.8.8",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -2370,8 +2394,8 @@ dependencies = [
|
|||||||
"axum 0.5.17",
|
"axum 0.5.17",
|
||||||
"axum-server",
|
"axum-server",
|
||||||
"cargo-generate",
|
"cargo-generate",
|
||||||
"cargo_metadata 0.15.4",
|
"cargo_metadata 0.18.1",
|
||||||
"cargo_toml",
|
"cargo_toml 0.18.0",
|
||||||
"chrono",
|
"chrono",
|
||||||
"clap 4.4.18",
|
"clap 4.4.18",
|
||||||
"colored 2.1.0",
|
"colored 2.1.0",
|
||||||
@@ -2383,11 +2407,11 @@ dependencies = [
|
|||||||
"dioxus-hot-reload",
|
"dioxus-hot-reload",
|
||||||
"dioxus-html",
|
"dioxus-html",
|
||||||
"dioxus-rsx",
|
"dioxus-rsx",
|
||||||
"dirs 4.0.0",
|
"dirs",
|
||||||
"fern",
|
"fern",
|
||||||
"flate2",
|
"flate2",
|
||||||
"fs_extra",
|
"fs_extra",
|
||||||
"futures",
|
"futures-util",
|
||||||
"gitignore",
|
"gitignore",
|
||||||
"headers 0.3.9",
|
"headers 0.3.9",
|
||||||
"html_parser",
|
"html_parser",
|
||||||
@@ -2406,14 +2430,13 @@ dependencies = [
|
|||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"subprocess",
|
"subprocess",
|
||||||
"syn 2.0.48",
|
|
||||||
"tar",
|
"tar",
|
||||||
"tauri-bundler",
|
"tauri-bundler",
|
||||||
"tauri-utils",
|
|
||||||
"tempfile",
|
"tempfile",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"tokio",
|
"tokio",
|
||||||
"toml_edit 0.19.15",
|
"toml 0.8.8",
|
||||||
|
"toml_edit 0.21.0",
|
||||||
"tower",
|
"tower",
|
||||||
"tower-http 0.2.5",
|
"tower-http 0.2.5",
|
||||||
"walkdir",
|
"walkdir",
|
||||||
@@ -2425,7 +2448,7 @@ dependencies = [
|
|||||||
name = "dioxus-cli-config"
|
name = "dioxus-cli-config"
|
||||||
version = "0.4.1"
|
version = "0.4.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cargo_toml",
|
"cargo_toml 0.16.3",
|
||||||
"clap 4.4.18",
|
"clap 4.4.18",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"serde",
|
"serde",
|
||||||
@@ -2962,22 +2985,13 @@ dependencies = [
|
|||||||
"syn 2.0.48",
|
"syn 2.0.48",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "dirs"
|
|
||||||
version = "4.0.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059"
|
|
||||||
dependencies = [
|
|
||||||
"dirs-sys 0.3.7",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "dirs"
|
name = "dirs"
|
||||||
version = "5.0.1"
|
version = "5.0.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225"
|
checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"dirs-sys 0.4.1",
|
"dirs-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -2990,17 +3004,6 @@ dependencies = [
|
|||||||
"dirs-sys-next",
|
"dirs-sys-next",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "dirs-sys"
|
|
||||||
version = "0.3.7"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6"
|
|
||||||
dependencies = [
|
|
||||||
"libc",
|
|
||||||
"redox_users",
|
|
||||||
"winapi",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "dirs-sys"
|
name = "dirs-sys"
|
||||||
version = "0.4.1"
|
version = "0.4.1"
|
||||||
@@ -3372,7 +3375,7 @@ dependencies = [
|
|||||||
"atomic 0.6.0",
|
"atomic 0.6.0",
|
||||||
"pear",
|
"pear",
|
||||||
"serde",
|
"serde",
|
||||||
"toml 0.8.2",
|
"toml 0.8.8",
|
||||||
"uncased",
|
"uncased",
|
||||||
"version_check",
|
"version_check",
|
||||||
]
|
]
|
||||||
@@ -3943,9 +3946,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gix-config"
|
name = "gix-config"
|
||||||
version = "0.31.0"
|
version = "0.32.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5cae98c6b4c66c09379bc35274b172587d6b0ac369a416c39128ad8c6454f9bb"
|
checksum = "0341471d55d8676e98b88e121d7065dfa4c9c5acea4b6d6ecdd2846e85cce0c3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bstr 1.9.0",
|
"bstr 1.9.0",
|
||||||
"gix-config-value",
|
"gix-config-value",
|
||||||
@@ -4045,9 +4048,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gix-object"
|
name = "gix-object"
|
||||||
version = "0.38.0"
|
version = "0.39.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "740f2a44267f58770a1cb3a3d01d14e67b089c7136c48d4bddbb3cfd2bf86a51"
|
checksum = "febf79c5825720c1c63fe974c7bbe695d0cb54aabad73f45671c60ce0e501e33"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bstr 1.9.0",
|
"bstr 1.9.0",
|
||||||
"btoi",
|
"btoi",
|
||||||
@@ -4077,9 +4080,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gix-ref"
|
name = "gix-ref"
|
||||||
version = "0.38.0"
|
version = "0.39.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0ec2f6d07ac88d2fb8007ee3fa3e801856fb9d82e7366ec0ca332eb2c9d74a52"
|
checksum = "3b2069adc212cf7f3317ef55f6444abd06c50f28479dbbac5a86acf3b05cbbfe"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"gix-actor",
|
"gix-actor",
|
||||||
"gix-date",
|
"gix-date",
|
||||||
@@ -4176,7 +4179,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "0bb0228f477c0900c880fd78c8759b95c7636dbd7842707f49e132378aa2acdc"
|
checksum = "0bb0228f477c0900c880fd78c8759b95c7636dbd7842707f49e132378aa2acdc"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"heck 0.4.1",
|
"heck 0.4.1",
|
||||||
"proc-macro-crate 2.0.1",
|
"proc-macro-crate 2.0.0",
|
||||||
"proc-macro-error",
|
"proc-macro-error",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@@ -5892,7 +5895,7 @@ dependencies = [
|
|||||||
"anyhow",
|
"anyhow",
|
||||||
"cargo-lock 9.0.0",
|
"cargo-lock 9.0.0",
|
||||||
"cargo_metadata 0.17.0",
|
"cargo_metadata 0.17.0",
|
||||||
"cargo_toml",
|
"cargo_toml 0.16.3",
|
||||||
"image",
|
"image",
|
||||||
"imagequant",
|
"imagequant",
|
||||||
"lightningcss",
|
"lightningcss",
|
||||||
@@ -6019,9 +6022,9 @@ checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "memmap2"
|
name = "memmap2"
|
||||||
version = "0.7.1"
|
version = "0.9.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f49388d20533534cd19360ad3d6a7dadc885944aa802ba3995040c5ec11288c6"
|
checksum = "fe751422e4a8caa417e13c3ea66452215d7d63e19e604f4980461212f3ae1322"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
@@ -6605,9 +6608,9 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "open"
|
name = "open"
|
||||||
version = "4.2.0"
|
version = "5.0.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3a083c0c7e5e4a8ec4176346cf61f67ac674e8bfb059d9226e1c54a96b377c12"
|
checksum = "90878fb664448b54c4e592455ad02831e23a3f7e157374a8b95654731aac7349"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"is-wsl",
|
"is-wsl",
|
||||||
"libc",
|
"libc",
|
||||||
@@ -7359,11 +7362,10 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro-crate"
|
name = "proc-macro-crate"
|
||||||
version = "2.0.1"
|
version = "2.0.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "97dc5fea232fc28d2f597b37c4876b348a40e33f3b02cc975c8d006d78d94b1a"
|
checksum = "7e8366a6159044a37876a2b9817124296703c586a5c92e2c53751fa06d8d43e8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"toml_datetime",
|
|
||||||
"toml_edit 0.20.2",
|
"toml_edit 0.20.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -8504,7 +8506,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "5fa50756ef995d410bb1968b403a1eca169b54c3c0eb4be4bcb1da8c7591cb7d"
|
checksum = "5fa50756ef995d410bb1968b403a1eca169b54c3c0eb4be4bcb1da8c7591cb7d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cruet",
|
"cruet",
|
||||||
"proc-macro-crate 2.0.1",
|
"proc-macro-crate 2.0.0",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"regex",
|
"regex",
|
||||||
@@ -9597,7 +9599,7 @@ dependencies = [
|
|||||||
"cfg-expr 0.15.6",
|
"cfg-expr 0.15.6",
|
||||||
"heck 0.4.1",
|
"heck 0.4.1",
|
||||||
"pkg-config",
|
"pkg-config",
|
||||||
"toml 0.8.2",
|
"toml 0.8.8",
|
||||||
"version-compare",
|
"version-compare",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -10086,22 +10088,22 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "toml"
|
name = "toml"
|
||||||
version = "0.8.2"
|
version = "0.8.8"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "185d8ab0dfbb35cf1399a6344d8484209c088f75f8f68230da55d48d95d43e3d"
|
checksum = "a1a195ec8c9da26928f773888e0742ca3ca1040c6cd859c919c9f59c1954ab35"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"indexmap 2.1.0",
|
"indexmap 2.1.0",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_spanned",
|
"serde_spanned",
|
||||||
"toml_datetime",
|
"toml_datetime",
|
||||||
"toml_edit 0.20.2",
|
"toml_edit 0.21.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "toml_datetime"
|
name = "toml_datetime"
|
||||||
version = "0.6.3"
|
version = "0.6.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b"
|
checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
@@ -10124,6 +10126,17 @@ name = "toml_edit"
|
|||||||
version = "0.20.2"
|
version = "0.20.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "396e4d48bbb2b7554c944bde63101b5ae446cff6ec4a24227428f15eb72ef338"
|
checksum = "396e4d48bbb2b7554c944bde63101b5ae446cff6ec4a24227428f15eb72ef338"
|
||||||
|
dependencies = [
|
||||||
|
"indexmap 2.1.0",
|
||||||
|
"toml_datetime",
|
||||||
|
"winnow",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "toml_edit"
|
||||||
|
version = "0.21.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d34d383cd00a163b4a5b85053df514d45bc330f6de7737edfe0a93311d1eaa03"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"indexmap 2.1.0",
|
"indexmap 2.1.0",
|
||||||
"serde",
|
"serde",
|
||||||
|
|||||||
@@ -42,7 +42,7 @@
|
|||||||
<span> | </span>
|
<span> | </span>
|
||||||
<a href="https://dioxuslabs.com/learn/0.4/guide"> Guide </a>
|
<a href="https://dioxuslabs.com/learn/0.4/guide"> Guide </a>
|
||||||
<span> | </span>
|
<span> | </span>
|
||||||
<a href="https://github.com/DioxusLabs/dioxus/blob/master/notes/README/ZH_CN.md"> 中文 </a>
|
<a href="https://github.com/DioxusLabs/dioxus/blob/master/translations/zh-cn/README.md"> 中文 </a>
|
||||||
<span> | </span>
|
<span> | </span>
|
||||||
<a href="https://github.com/DioxusLabs/dioxus/blob/master/translations/pt-br/README.md"> PT-BR </a>
|
<a href="https://github.com/DioxusLabs/dioxus/blob/master/translations/pt-br/README.md"> PT-BR </a>
|
||||||
<span> | </span>
|
<span> | </span>
|
||||||
|
|||||||
@@ -338,11 +338,9 @@ pub struct WebHttpsConfig {
|
|||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
pub struct CrateConfig {
|
pub struct CrateConfig {
|
||||||
pub out_dir: PathBuf,
|
|
||||||
pub crate_dir: PathBuf,
|
pub crate_dir: PathBuf,
|
||||||
pub workspace_dir: PathBuf,
|
pub workspace_dir: PathBuf,
|
||||||
pub target_dir: PathBuf,
|
pub target_dir: PathBuf,
|
||||||
pub asset_dir: PathBuf,
|
|
||||||
#[cfg(feature = "cli")]
|
#[cfg(feature = "cli")]
|
||||||
pub manifest: cargo_toml::Manifest<cargo_toml::Value>,
|
pub manifest: cargo_toml::Manifest<cargo_toml::Value>,
|
||||||
pub executable: ExecutableType,
|
pub executable: ExecutableType,
|
||||||
@@ -383,12 +381,8 @@ impl CrateConfig {
|
|||||||
let workspace_dir = meta.workspace_root;
|
let workspace_dir = meta.workspace_root;
|
||||||
let target_dir = meta.target_directory;
|
let target_dir = meta.target_directory;
|
||||||
|
|
||||||
let out_dir = crate_dir.join(&dioxus_config.application.out_dir);
|
|
||||||
|
|
||||||
let cargo_def = &crate_dir.join("Cargo.toml");
|
let cargo_def = &crate_dir.join("Cargo.toml");
|
||||||
|
|
||||||
let asset_dir = crate_dir.join(&dioxus_config.application.asset_dir);
|
|
||||||
|
|
||||||
let manifest = cargo_toml::Manifest::from_path(cargo_def).unwrap();
|
let manifest = cargo_toml::Manifest::from_path(cargo_def).unwrap();
|
||||||
|
|
||||||
let mut output_filename = String::from("dioxus_app");
|
let mut output_filename = String::from("dioxus_app");
|
||||||
@@ -414,6 +408,7 @@ impl CrateConfig {
|
|||||||
|
|
||||||
let release = false;
|
let release = false;
|
||||||
let hot_reload = false;
|
let hot_reload = false;
|
||||||
|
let cross_origin_policy = false;
|
||||||
let verbose = false;
|
let verbose = false;
|
||||||
let custom_profile = None;
|
let custom_profile = None;
|
||||||
let features = None;
|
let features = None;
|
||||||
@@ -421,26 +416,38 @@ impl CrateConfig {
|
|||||||
let cargo_args = vec![];
|
let cargo_args = vec![];
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
out_dir,
|
|
||||||
crate_dir,
|
crate_dir,
|
||||||
workspace_dir,
|
workspace_dir,
|
||||||
target_dir,
|
target_dir,
|
||||||
asset_dir,
|
|
||||||
#[cfg(feature = "cli")]
|
#[cfg(feature = "cli")]
|
||||||
manifest,
|
manifest,
|
||||||
executable,
|
executable,
|
||||||
release,
|
|
||||||
dioxus_config,
|
dioxus_config,
|
||||||
|
release,
|
||||||
hot_reload,
|
hot_reload,
|
||||||
cross_origin_policy: false,
|
cross_origin_policy,
|
||||||
|
verbose,
|
||||||
custom_profile,
|
custom_profile,
|
||||||
features,
|
features,
|
||||||
verbose,
|
|
||||||
target,
|
target,
|
||||||
cargo_args,
|
cargo_args,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Compose an asset directory. Represents the typical "public" directory
|
||||||
|
/// with publicly available resources (configurable in the `Dioxus.toml`).
|
||||||
|
pub fn asset_dir(&self) -> PathBuf {
|
||||||
|
self.crate_dir
|
||||||
|
.join(&self.dioxus_config.application.asset_dir)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Compose an out directory. Represents the typical "dist" directory that
|
||||||
|
/// is "distributed" after building an application (configurable in the
|
||||||
|
/// `Dioxus.toml`).
|
||||||
|
pub fn out_dir(&self) -> PathBuf {
|
||||||
|
self.crate_dir.join(&self.dioxus_config.application.out_dir)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn as_example(&mut self, example_name: String) -> &mut Self {
|
pub fn as_example(&mut self, example_name: String) -> &mut Self {
|
||||||
self.executable = ExecutableType::Example(example_name);
|
self.executable = ExecutableType::Example(example_name);
|
||||||
self
|
self
|
||||||
|
|||||||
@@ -21,12 +21,13 @@ log = "0.4.14"
|
|||||||
fern = { version = "0.6.0", features = ["colored"] }
|
fern = { version = "0.6.0", features = ["colored"] }
|
||||||
serde = { version = "1.0.136", features = ["derive"] }
|
serde = { version = "1.0.136", features = ["derive"] }
|
||||||
serde_json = "1.0.79"
|
serde_json = "1.0.79"
|
||||||
|
toml = "0.8.8"
|
||||||
fs_extra = "1.2.0"
|
fs_extra = "1.2.0"
|
||||||
cargo_toml = "0.16.0"
|
cargo_toml = "0.18.0"
|
||||||
futures = "0.3.21"
|
futures-util = { workspace = true }
|
||||||
notify = { version = "5.0.0-pre.16", features = ["serde"] }
|
notify = { version = "5.0.0-pre.16", features = ["serde"] }
|
||||||
html_parser = { workspace = true }
|
html_parser = { workspace = true }
|
||||||
cargo_metadata = "0.15.0"
|
cargo_metadata = "0.18.1"
|
||||||
tokio = { version = "1.16.1", features = ["fs", "sync", "rt", "macros"] }
|
tokio = { version = "1.16.1", features = ["fs", "sync", "rt", "macros"] }
|
||||||
atty = "0.2.14"
|
atty = "0.2.14"
|
||||||
chrono = "0.4.19"
|
chrono = "0.4.19"
|
||||||
@@ -44,7 +45,7 @@ headers = "0.3.7"
|
|||||||
walkdir = "2"
|
walkdir = "2"
|
||||||
|
|
||||||
# tools download
|
# tools download
|
||||||
dirs = "4.0.0"
|
dirs = "5.0.1"
|
||||||
reqwest = { version = "0.11", features = [
|
reqwest = { version = "0.11", features = [
|
||||||
"rustls-tls",
|
"rustls-tls",
|
||||||
"stream",
|
"stream",
|
||||||
@@ -55,7 +56,6 @@ flate2 = "1.0.22"
|
|||||||
tar = "0.4.38"
|
tar = "0.4.38"
|
||||||
zip = "0.6.2"
|
zip = "0.6.2"
|
||||||
tower = "0.4.12"
|
tower = "0.4.12"
|
||||||
syn = { version = "2.0", features = ["full", "extra-traits"] }
|
|
||||||
lazy_static = "1.4.0"
|
lazy_static = "1.4.0"
|
||||||
|
|
||||||
# plugin packages
|
# plugin packages
|
||||||
@@ -67,13 +67,12 @@ mlua = { version = "0.8.1", features = [
|
|||||||
"macros",
|
"macros",
|
||||||
], optional = true }
|
], optional = true }
|
||||||
ctrlc = "3.2.3"
|
ctrlc = "3.2.3"
|
||||||
open = "4.1.0"
|
open = "5.0.1"
|
||||||
cargo-generate = "0.18"
|
cargo-generate = "0.19.0"
|
||||||
toml_edit = "0.19.11"
|
toml_edit = "0.21.0"
|
||||||
|
|
||||||
# bundling
|
# bundling
|
||||||
tauri-bundler = { version = "=1.4.*", features = ["native-tls-vendored"] }
|
tauri-bundler = { version = "=1.4.*", features = ["native-tls-vendored"] }
|
||||||
tauri-utils = "=1.5.*"
|
|
||||||
|
|
||||||
manganis-cli-support = { workspace = true, features = ["webp", "html"] }
|
manganis-cli-support = { workspace = true, features = ["webp", "html"] }
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ pub fn asset_manifest(crate_config: &CrateConfig) -> AssetManifest {
|
|||||||
|
|
||||||
/// Create a head file that contains all of the imports for assets that the user project uses
|
/// Create a head file that contains all of the imports for assets that the user project uses
|
||||||
pub fn create_assets_head(config: &CrateConfig, manifest: &AssetManifest) -> Result<()> {
|
pub fn create_assets_head(config: &CrateConfig, manifest: &AssetManifest) -> Result<()> {
|
||||||
let mut file = File::create(config.out_dir.join("__assets_head.html"))?;
|
let mut file = File::create(config.out_dir().join("__assets_head.html"))?;
|
||||||
file.write_all(manifest.head().as_bytes())?;
|
file.write_all(manifest.head().as_bytes())?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -29,7 +29,7 @@ pub(crate) fn process_assets(config: &CrateConfig, manifest: &AssetManifest) ->
|
|||||||
.clone()
|
.clone()
|
||||||
.unwrap_or_default(),
|
.unwrap_or_default(),
|
||||||
);
|
);
|
||||||
let static_asset_output_dir = config.out_dir.join(static_asset_output_dir);
|
let static_asset_output_dir = config.out_dir().join(static_asset_output_dir);
|
||||||
|
|
||||||
manifest.copy_static_assets_to(static_asset_output_dir)?;
|
manifest.copy_static_assets_to(static_asset_output_dir)?;
|
||||||
|
|
||||||
|
|||||||
+21
-21
@@ -39,14 +39,14 @@ pub fn build(config: &CrateConfig, _: bool, skip_assets: bool) -> Result<BuildRe
|
|||||||
// [6] Link up the html page to the wasm module
|
// [6] Link up the html page to the wasm module
|
||||||
|
|
||||||
let CrateConfig {
|
let CrateConfig {
|
||||||
out_dir,
|
|
||||||
crate_dir,
|
crate_dir,
|
||||||
target_dir,
|
target_dir,
|
||||||
asset_dir,
|
|
||||||
executable,
|
executable,
|
||||||
dioxus_config,
|
dioxus_config,
|
||||||
..
|
..
|
||||||
} = config;
|
} = config;
|
||||||
|
let out_dir = config.out_dir();
|
||||||
|
let asset_dir = config.asset_dir();
|
||||||
|
|
||||||
let _guard = WebAssetConfigDropGuard::new();
|
let _guard = WebAssetConfigDropGuard::new();
|
||||||
let _manganis_support = ManganisSupportGuard::default();
|
let _manganis_support = ManganisSupportGuard::default();
|
||||||
@@ -251,15 +251,15 @@ pub fn build(config: &CrateConfig, _: bool, skip_assets: bool) -> Result<BuildRe
|
|||||||
if path.is_file() {
|
if path.is_file() {
|
||||||
std::fs::copy(&path, out_dir.join(path.file_name().unwrap()))?;
|
std::fs::copy(&path, out_dir.join(path.file_name().unwrap()))?;
|
||||||
} else {
|
} else {
|
||||||
match fs_extra::dir::copy(&path, out_dir, ©_options) {
|
match fs_extra::dir::copy(&path, &out_dir, ©_options) {
|
||||||
Ok(_) => {}
|
Ok(_) => {}
|
||||||
Err(_e) => {
|
Err(_e) => {
|
||||||
log::warn!("Error copying dir: {}", _e);
|
log::warn!("Error copying dir: {}", _e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for ignore in &ignore_files {
|
for ignore in &ignore_files {
|
||||||
let ignore = ignore.strip_prefix(&config.asset_dir).unwrap();
|
let ignore = ignore.strip_prefix(&config.asset_dir()).unwrap();
|
||||||
let ignore = config.out_dir.join(ignore);
|
let ignore = out_dir.join(ignore);
|
||||||
if ignore.is_file() {
|
if ignore.is_file() {
|
||||||
std::fs::remove_file(ignore)?;
|
std::fs::remove_file(ignore)?;
|
||||||
}
|
}
|
||||||
@@ -369,13 +369,13 @@ pub fn build_desktop(
|
|||||||
file_name
|
file_name
|
||||||
};
|
};
|
||||||
|
|
||||||
if !config.out_dir.is_dir() {
|
if !config.out_dir().is_dir() {
|
||||||
create_dir_all(&config.out_dir)?;
|
create_dir_all(config.out_dir())?;
|
||||||
}
|
}
|
||||||
copy(res_path, config.out_dir.join(target_file))?;
|
copy(res_path, config.out_dir().join(target_file))?;
|
||||||
|
|
||||||
// this code will copy all public file to the output dir
|
// this code will copy all public file to the output dir
|
||||||
if config.asset_dir.is_dir() {
|
if config.asset_dir().is_dir() {
|
||||||
let copy_options = fs_extra::dir::CopyOptions {
|
let copy_options = fs_extra::dir::CopyOptions {
|
||||||
overwrite: true,
|
overwrite: true,
|
||||||
skip_exist: false,
|
skip_exist: false,
|
||||||
@@ -385,20 +385,20 @@ pub fn build_desktop(
|
|||||||
depth: 0,
|
depth: 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
for entry in std::fs::read_dir(&config.asset_dir)? {
|
for entry in std::fs::read_dir(config.asset_dir())? {
|
||||||
let path = entry?.path();
|
let path = entry?.path();
|
||||||
if path.is_file() {
|
if path.is_file() {
|
||||||
std::fs::copy(&path, &config.out_dir.join(path.file_name().unwrap()))?;
|
std::fs::copy(&path, &config.out_dir().join(path.file_name().unwrap()))?;
|
||||||
} else {
|
} else {
|
||||||
match fs_extra::dir::copy(&path, &config.out_dir, ©_options) {
|
match fs_extra::dir::copy(&path, &config.out_dir(), ©_options) {
|
||||||
Ok(_) => {}
|
Ok(_) => {}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
log::warn!("Error copying dir: {}", e);
|
log::warn!("Error copying dir: {}", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for ignore in &ignore_files {
|
for ignore in &ignore_files {
|
||||||
let ignore = ignore.strip_prefix(&config.asset_dir).unwrap();
|
let ignore = ignore.strip_prefix(&config.asset_dir()).unwrap();
|
||||||
let ignore = config.out_dir.join(ignore);
|
let ignore = config.out_dir().join(ignore);
|
||||||
if ignore.is_file() {
|
if ignore.is_file() {
|
||||||
std::fs::remove_file(ignore)?;
|
std::fs::remove_file(ignore)?;
|
||||||
}
|
}
|
||||||
@@ -443,7 +443,7 @@ fn prettier_build(cmd: subprocess::Exec) -> anyhow::Result<Vec<Diagnostic>> {
|
|||||||
.unwrap()
|
.unwrap()
|
||||||
.tick_chars("/|\\- "),
|
.tick_chars("/|\\- "),
|
||||||
);
|
);
|
||||||
pb.set_message("💼 Waiting to start build the project...");
|
pb.set_message("💼 Waiting to start building the project...");
|
||||||
|
|
||||||
let stdout = cmd.detached().stream_stdout()?;
|
let stdout = cmd.detached().stream_stdout()?;
|
||||||
let reader = std::io::BufReader::new(stdout);
|
let reader = std::io::BufReader::new(stdout);
|
||||||
@@ -635,7 +635,7 @@ fn build_assets(config: &CrateConfig) -> Result<Vec<PathBuf>> {
|
|||||||
|
|
||||||
if file == "*" {
|
if file == "*" {
|
||||||
// if the sass open auto, we need auto-check the assets dir.
|
// if the sass open auto, we need auto-check the assets dir.
|
||||||
let asset_dir = config.asset_dir.clone();
|
let asset_dir = config.asset_dir().clone();
|
||||||
if asset_dir.is_dir() {
|
if asset_dir.is_dir() {
|
||||||
for entry in walkdir::WalkDir::new(&asset_dir)
|
for entry in walkdir::WalkDir::new(&asset_dir)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
@@ -655,7 +655,7 @@ fn build_assets(config: &CrateConfig) -> Result<Vec<PathBuf>> {
|
|||||||
temp.file_stem().unwrap().to_str().unwrap()
|
temp.file_stem().unwrap().to_str().unwrap()
|
||||||
);
|
);
|
||||||
let target_path = config
|
let target_path = config
|
||||||
.out_dir
|
.out_dir()
|
||||||
.join(
|
.join(
|
||||||
temp.strip_prefix(&asset_dir)
|
temp.strip_prefix(&asset_dir)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
@@ -685,11 +685,11 @@ fn build_assets(config: &CrateConfig) -> Result<Vec<PathBuf>> {
|
|||||||
} else {
|
} else {
|
||||||
file
|
file
|
||||||
};
|
};
|
||||||
let path = config.asset_dir.join(relative_path);
|
let path = config.asset_dir().join(relative_path);
|
||||||
let out_file =
|
let out_file =
|
||||||
format!("{}.css", path.file_stem().unwrap().to_str().unwrap());
|
format!("{}.css", path.file_stem().unwrap().to_str().unwrap());
|
||||||
let target_path = config
|
let target_path = config
|
||||||
.out_dir
|
.out_dir()
|
||||||
.join(PathBuf::from(relative_path).parent().unwrap())
|
.join(PathBuf::from(relative_path).parent().unwrap())
|
||||||
.join(out_file);
|
.join(out_file);
|
||||||
if path.is_file() {
|
if path.is_file() {
|
||||||
@@ -719,11 +719,11 @@ fn build_assets(config: &CrateConfig) -> Result<Vec<PathBuf>> {
|
|||||||
} else {
|
} else {
|
||||||
path
|
path
|
||||||
};
|
};
|
||||||
let path = config.asset_dir.join(relative_path);
|
let path = config.asset_dir().join(relative_path);
|
||||||
let out_file =
|
let out_file =
|
||||||
format!("{}.css", path.file_stem().unwrap().to_str().unwrap());
|
format!("{}.css", path.file_stem().unwrap().to_str().unwrap());
|
||||||
let target_path = config
|
let target_path = config
|
||||||
.out_dir
|
.out_dir()
|
||||||
.join(PathBuf::from(relative_path).parent().unwrap())
|
.join(PathBuf::from(relative_path).parent().unwrap())
|
||||||
.join(out_file);
|
.join(out_file);
|
||||||
if path.is_file() {
|
if path.is_file() {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
use dioxus_autofmt::{IndentOptions, IndentType};
|
use dioxus_autofmt::{IndentOptions, IndentType};
|
||||||
use futures::{stream::FuturesUnordered, StreamExt};
|
use futures_util::{stream::FuturesUnordered, StreamExt};
|
||||||
use std::{fs, path::Path, process::exit};
|
use std::{fs, path::Path, process::exit};
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ impl Bundle {
|
|||||||
build_desktop(&crate_config, false, false)?;
|
build_desktop(&crate_config, false, false)?;
|
||||||
|
|
||||||
// copy the binary to the out dir
|
// copy the binary to the out dir
|
||||||
let package = crate_config.manifest.package.unwrap();
|
let package = crate_config.manifest.package.as_ref().unwrap();
|
||||||
|
|
||||||
let mut name: PathBuf = match &crate_config.executable {
|
let mut name: PathBuf = match &crate_config.executable {
|
||||||
ExecutableType::Binary(name)
|
ExecutableType::Binary(name)
|
||||||
@@ -149,7 +149,7 @@ impl Bundle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let mut settings = SettingsBuilder::new()
|
let mut settings = SettingsBuilder::new()
|
||||||
.project_out_directory(crate_config.out_dir)
|
.project_out_directory(crate_config.out_dir())
|
||||||
.package_settings(PackageSettings {
|
.package_settings(PackageSettings {
|
||||||
product_name: crate_config.dioxus_config.application.name.clone(),
|
product_name: crate_config.dioxus_config.application.name.clone(),
|
||||||
version: package.version().to_string(),
|
version: package.version().to_string(),
|
||||||
|
|||||||
@@ -78,6 +78,7 @@ impl From<ConfigOptsServe> for ConfigOptsBuild {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Default, Deserialize, Parser)]
|
#[derive(Clone, Debug, Default, Deserialize, Parser)]
|
||||||
|
#[command(group = clap::ArgGroup::new("release-incompatible").multiple(true).conflicts_with("release"))]
|
||||||
pub struct ConfigOptsServe {
|
pub struct ConfigOptsServe {
|
||||||
/// Port of dev server
|
/// Port of dev server
|
||||||
#[clap(long)]
|
#[clap(long)]
|
||||||
@@ -116,8 +117,9 @@ pub struct ConfigOptsServe {
|
|||||||
#[clap(long, value_enum)]
|
#[clap(long, value_enum)]
|
||||||
pub platform: Option<Platform>,
|
pub platform: Option<Platform>,
|
||||||
|
|
||||||
/// Build with hot reloading rsx [default: false]
|
/// Build with hot reloading rsx. Will not work with release builds. [default: false]
|
||||||
#[clap(long)]
|
#[clap(long)]
|
||||||
|
#[clap(group = "release-incompatible")]
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub hot_reload: bool,
|
pub hot_reload: bool,
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
use futures::{stream::FuturesUnordered, StreamExt};
|
use futures_util::{stream::FuturesUnordered, StreamExt};
|
||||||
use std::{path::Path, process::exit};
|
use std::{path::Path, process::exit};
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|||||||
+26
-24
@@ -1,7 +1,7 @@
|
|||||||
use dioxus_cli_config::DioxusConfig;
|
use dioxus_cli_config::DioxusConfig;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use anyhow::anyhow;
|
use anyhow::Context;
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use dioxus_cli::*;
|
use dioxus_cli::*;
|
||||||
|
|
||||||
@@ -19,24 +19,26 @@ fn get_bin(bin: Option<String>) -> Result<PathBuf> {
|
|||||||
.workspace_packages()
|
.workspace_packages()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.find(|p| p.name == bin)
|
.find(|p| p.name == bin)
|
||||||
.ok_or(format!("no such package: {}", bin))
|
.ok_or(Error::CargoError(format!("no such package: {}", bin)))?
|
||||||
.map_err(Error::CargoError)?
|
|
||||||
} else {
|
} else {
|
||||||
metadata
|
metadata
|
||||||
.root_package()
|
.root_package()
|
||||||
.ok_or("no root package?".into())
|
.ok_or(Error::CargoError("no root package?".to_string()))?
|
||||||
.map_err(Error::CargoError)?
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let crate_dir = package
|
let crate_dir = package
|
||||||
.manifest_path
|
.manifest_path
|
||||||
.parent()
|
.parent()
|
||||||
.ok_or("couldn't take parent dir".into())
|
.ok_or(Error::CargoError("couldn't take parent dir".to_string()))?;
|
||||||
.map_err(Error::CargoError)?;
|
|
||||||
|
|
||||||
Ok(crate_dir.into())
|
Ok(crate_dir.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Simplifies error messages that use the same pattern.
|
||||||
|
fn error_wrapper(message: &str) -> String {
|
||||||
|
format!("🚫 {message}:")
|
||||||
|
}
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() -> anyhow::Result<()> {
|
async fn main() -> anyhow::Result<()> {
|
||||||
let args = Cli::parse();
|
let args = Cli::parse();
|
||||||
@@ -46,35 +48,35 @@ async fn main() -> anyhow::Result<()> {
|
|||||||
match args.action {
|
match args.action {
|
||||||
Translate(opts) => opts
|
Translate(opts) => opts
|
||||||
.translate()
|
.translate()
|
||||||
.map_err(|e| anyhow!("🚫 Translation of HTML into RSX failed: {}", e)),
|
.context(error_wrapper("Translation of HTML into RSX failed")),
|
||||||
|
|
||||||
Create(opts) => opts
|
Create(opts) => opts
|
||||||
.create()
|
.create()
|
||||||
.map_err(|e| anyhow!("🚫 Creating new project failed: {}", e)),
|
.context(error_wrapper("Creating new project failed")),
|
||||||
|
|
||||||
Init(opts) => opts
|
Init(opts) => opts
|
||||||
.init()
|
.init()
|
||||||
.map_err(|e| anyhow!("🚫 Initialising a new project failed: {}", e)),
|
.context(error_wrapper("Initialising a new project failed")),
|
||||||
|
|
||||||
Config(opts) => opts
|
Config(opts) => opts
|
||||||
.config()
|
.config()
|
||||||
.map_err(|e| anyhow!("🚫 Configuring new project failed: {}", e)),
|
.context(error_wrapper("Configuring new project failed")),
|
||||||
|
|
||||||
#[cfg(feature = "plugin")]
|
#[cfg(feature = "plugin")]
|
||||||
Plugin(opts) => opts
|
Plugin(opts) => opts
|
||||||
.plugin()
|
.plugin()
|
||||||
.await
|
.await
|
||||||
.map_err(|e| anyhow!("🚫 Error with plugin: {}", e)),
|
.context(error_wrapper("Error with plugin")),
|
||||||
|
|
||||||
Autoformat(opts) => opts
|
Autoformat(opts) => opts
|
||||||
.autoformat()
|
.autoformat()
|
||||||
.await
|
.await
|
||||||
.map_err(|e| anyhow!("🚫 Error autoformatting RSX: {}", e)),
|
.context(error_wrapper("Error autoformatting RSX")),
|
||||||
|
|
||||||
Check(opts) => opts
|
Check(opts) => opts
|
||||||
.check()
|
.check()
|
||||||
.await
|
.await
|
||||||
.map_err(|e| anyhow!("🚫 Error checking RSX: {}", e)),
|
.context(error_wrapper("Error checking RSX")),
|
||||||
|
|
||||||
Version(opt) => {
|
Version(opt) => {
|
||||||
let version = opt.version();
|
let version = opt.version();
|
||||||
@@ -85,33 +87,33 @@ async fn main() -> anyhow::Result<()> {
|
|||||||
action => {
|
action => {
|
||||||
let bin = get_bin(args.bin)?;
|
let bin = get_bin(args.bin)?;
|
||||||
let _dioxus_config = DioxusConfig::load(Some(bin.clone()))
|
let _dioxus_config = DioxusConfig::load(Some(bin.clone()))
|
||||||
.map_err(|e| anyhow!("Failed to load Dioxus config because: {e}"))?
|
.context("Failed to load Dioxus config because")?
|
||||||
.unwrap_or_else(|| {
|
.unwrap_or_else(|| {
|
||||||
log::info!("You appear to be creating a Dioxus project from scratch; we will use the default config");
|
log::info!("You appear to be creating a Dioxus project from scratch; we will use the default config");
|
||||||
DioxusConfig::default()
|
DioxusConfig::default()
|
||||||
});
|
});
|
||||||
|
|
||||||
#[cfg(feature = "plugin")]
|
#[cfg(feature = "plugin")]
|
||||||
PluginManager::init(_dioxus_config.plugin)
|
PluginManager::init(_dioxus_config.plugin)
|
||||||
.map_err(|e| anyhow!("🚫 Plugin system initialization failed: {e}"))?;
|
.context(error_wrapper("Plugin system initialization failed"))?;
|
||||||
|
|
||||||
match action {
|
match action {
|
||||||
Build(opts) => opts
|
Build(opts) => opts
|
||||||
.build(Some(bin.clone()), None)
|
.build(Some(bin.clone()), None)
|
||||||
.map_err(|e| anyhow!("🚫 Building project failed: {}", e)),
|
.context(error_wrapper("Building project failed")),
|
||||||
|
|
||||||
Clean(opts) => opts
|
Clean(opts) => opts
|
||||||
.clean(Some(bin.clone()))
|
.clean(Some(bin.clone()))
|
||||||
.map_err(|e| anyhow!("🚫 Cleaning project failed: {}", e)),
|
.context(error_wrapper("Cleaning project failed")),
|
||||||
|
|
||||||
Serve(opts) => opts
|
Serve(opts) => opts
|
||||||
.serve(Some(bin.clone()))
|
.serve(Some(bin.clone()))
|
||||||
.await
|
.await
|
||||||
.map_err(|e| anyhow!("🚫 Serving project failed: {}", e)),
|
.context(error_wrapper("Serving project failed")),
|
||||||
|
|
||||||
Bundle(opts) => opts
|
Bundle(opts) => opts
|
||||||
.bundle(Some(bin.clone()))
|
.bundle(Some(bin.clone()))
|
||||||
.map_err(|e| anyhow!("🚫 Bundling project failed: {}", e)),
|
.context(error_wrapper("Bundling project failed")),
|
||||||
|
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -181,8 +181,8 @@ impl PluginManager {
|
|||||||
let args = lua.create_table()?;
|
let args = lua.create_table()?;
|
||||||
args.set("name", crate_config.dioxus_config.application.name.clone())?;
|
args.set("name", crate_config.dioxus_config.application.name.clone())?;
|
||||||
args.set("platform", platform)?;
|
args.set("platform", platform)?;
|
||||||
args.set("out_dir", crate_config.out_dir.to_str().unwrap())?;
|
args.set("out_dir", crate_config.out_dir().to_str().unwrap())?;
|
||||||
args.set("asset_dir", crate_config.asset_dir.to_str().unwrap())?;
|
args.set("asset_dir", crate_config.asset_dir().to_str().unwrap())?;
|
||||||
|
|
||||||
for i in 1..(manager.len()? as i32 + 1) {
|
for i in 1..(manager.len()? as i32 + 1) {
|
||||||
let info = manager.get::<i32, PluginInfo>(i)?;
|
let info = manager.get::<i32, PluginInfo>(i)?;
|
||||||
@@ -205,8 +205,8 @@ impl PluginManager {
|
|||||||
let args = lua.create_table()?;
|
let args = lua.create_table()?;
|
||||||
args.set("name", crate_config.dioxus_config.application.name.clone())?;
|
args.set("name", crate_config.dioxus_config.application.name.clone())?;
|
||||||
args.set("platform", platform)?;
|
args.set("platform", platform)?;
|
||||||
args.set("out_dir", crate_config.out_dir.to_str().unwrap())?;
|
args.set("out_dir", crate_config.out_dir().to_str().unwrap())?;
|
||||||
args.set("asset_dir", crate_config.asset_dir.to_str().unwrap())?;
|
args.set("asset_dir", crate_config.asset_dir().to_str().unwrap())?;
|
||||||
|
|
||||||
for i in 1..(manager.len()? as i32 + 1) {
|
for i in 1..(manager.len()? as i32 + 1) {
|
||||||
let info = manager.get::<i32, PluginInfo>(i)?;
|
let info = manager.get::<i32, PluginInfo>(i)?;
|
||||||
|
|||||||
@@ -221,7 +221,7 @@ fn start_desktop(config: &CrateConfig, skip_assets: bool) -> Result<(RAIIChild,
|
|||||||
ExecutableType::Binary(name)
|
ExecutableType::Binary(name)
|
||||||
| ExecutableType::Lib(name)
|
| ExecutableType::Lib(name)
|
||||||
| ExecutableType::Example(name) => {
|
| ExecutableType::Example(name) => {
|
||||||
let mut file = config.out_dir.join(name);
|
let mut file = config.out_dir().join(name);
|
||||||
if cfg!(windows) {
|
if cfg!(windows) {
|
||||||
file.set_extension("exe");
|
file.set_extension("exe");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,93 +31,103 @@ async fn setup_file_watcher<F: Fn() -> Result<BuildResult> + Send + 'static>(
|
|||||||
let mut watcher = notify::recommended_watcher(move |info: notify::Result<notify::Event>| {
|
let mut watcher = notify::recommended_watcher(move |info: notify::Result<notify::Event>| {
|
||||||
let config = watcher_config.clone();
|
let config = watcher_config.clone();
|
||||||
if let Ok(e) = info {
|
if let Ok(e) = info {
|
||||||
if chrono::Local::now().timestamp() > last_update_time {
|
match e.kind {
|
||||||
let mut needs_full_rebuild;
|
notify::EventKind::Create(_)
|
||||||
if let Some(hot_reload) = &hot_reload {
|
| notify::EventKind::Remove(_)
|
||||||
// find changes to the rsx in the file
|
| notify::EventKind::Modify(_) => {
|
||||||
let mut rsx_file_map = hot_reload.file_map.lock().unwrap();
|
if chrono::Local::now().timestamp() > last_update_time {
|
||||||
let mut messages: Vec<Template> = Vec::new();
|
let mut needs_full_rebuild;
|
||||||
|
if let Some(hot_reload) = &hot_reload {
|
||||||
|
// find changes to the rsx in the file
|
||||||
|
let mut rsx_file_map = hot_reload.file_map.lock().unwrap();
|
||||||
|
let mut messages: Vec<Template> = Vec::new();
|
||||||
|
|
||||||
// In hot reload mode, we only need to rebuild if non-rsx code is changed
|
// In hot reload mode, we only need to rebuild if non-rsx code is changed
|
||||||
needs_full_rebuild = false;
|
needs_full_rebuild = false;
|
||||||
|
|
||||||
for path in &e.paths {
|
for path in &e.paths {
|
||||||
// if this is not a rust file, rebuild the whole project
|
// if this is not a rust file, rebuild the whole project
|
||||||
if path.extension().and_then(|p| p.to_str()) != Some("rs") {
|
if path.extension().and_then(|p| p.to_str()) != Some("rs") {
|
||||||
|
needs_full_rebuild = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Workaround for notify and vscode-like editor:
|
||||||
|
// when edit & save a file in vscode, there will be two notifications,
|
||||||
|
// the first one is a file with empty content.
|
||||||
|
// filter the empty file notification to avoid false rebuild during hot-reload
|
||||||
|
if let Ok(metadata) = fs::metadata(path) {
|
||||||
|
if metadata.len() == 0 {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
match rsx_file_map.update_rsx(path, &config.crate_dir) {
|
||||||
|
Ok(UpdateResult::UpdatedRsx(msgs)) => {
|
||||||
|
messages.extend(msgs);
|
||||||
|
needs_full_rebuild = false;
|
||||||
|
}
|
||||||
|
Ok(UpdateResult::NeedsRebuild) => {
|
||||||
|
needs_full_rebuild = true;
|
||||||
|
}
|
||||||
|
Err(err) => {
|
||||||
|
log::error!("{}", err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if needs_full_rebuild {
|
||||||
|
// Reset the file map to the new state of the project
|
||||||
|
let FileMapBuildResult {
|
||||||
|
map: new_file_map,
|
||||||
|
errors,
|
||||||
|
} = FileMap::<HtmlCtx>::create(config.crate_dir.clone()).unwrap();
|
||||||
|
|
||||||
|
for err in errors {
|
||||||
|
log::error!("{}", err);
|
||||||
|
}
|
||||||
|
|
||||||
|
*rsx_file_map = new_file_map;
|
||||||
|
} else {
|
||||||
|
for msg in messages {
|
||||||
|
let _ = hot_reload.messages.send(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
needs_full_rebuild = true;
|
needs_full_rebuild = true;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Workaround for notify and vscode-like editor:
|
if needs_full_rebuild {
|
||||||
// when edit & save a file in vscode, there will be two notifications,
|
match build_with() {
|
||||||
// the first one is a file with empty content.
|
Ok(res) => {
|
||||||
// filter the empty file notification to avoid false rebuild during hot-reload
|
last_update_time = chrono::Local::now().timestamp();
|
||||||
if let Ok(metadata) = fs::metadata(path) {
|
|
||||||
if metadata.len() == 0 {
|
#[allow(clippy::redundant_clone)]
|
||||||
continue;
|
print_console_info(
|
||||||
|
&config,
|
||||||
|
PrettierOptions {
|
||||||
|
changed: e.paths.clone(),
|
||||||
|
warnings: res.warnings,
|
||||||
|
elapsed_time: res.elapsed_time,
|
||||||
|
},
|
||||||
|
web_info.clone(),
|
||||||
|
);
|
||||||
|
|
||||||
|
#[cfg(feature = "plugin")]
|
||||||
|
let _ = PluginManager::on_serve_rebuild(
|
||||||
|
chrono::Local::now().timestamp(),
|
||||||
|
e.paths,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
last_update_time = chrono::Local::now().timestamp();
|
||||||
|
log::error!("{:?}", e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
match rsx_file_map.update_rsx(path, &config.crate_dir) {
|
|
||||||
Ok(UpdateResult::UpdatedRsx(msgs)) => {
|
|
||||||
messages.extend(msgs);
|
|
||||||
needs_full_rebuild = false;
|
|
||||||
}
|
|
||||||
Ok(UpdateResult::NeedsRebuild) => {
|
|
||||||
needs_full_rebuild = true;
|
|
||||||
}
|
|
||||||
Err(err) => {
|
|
||||||
log::error!("{}", err);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if needs_full_rebuild {
|
|
||||||
// Reset the file map to the new state of the project
|
|
||||||
let FileMapBuildResult {
|
|
||||||
map: new_file_map,
|
|
||||||
errors,
|
|
||||||
} = FileMap::<HtmlCtx>::create(config.crate_dir.clone()).unwrap();
|
|
||||||
|
|
||||||
for err in errors {
|
|
||||||
log::error!("{}", err);
|
|
||||||
}
|
|
||||||
|
|
||||||
*rsx_file_map = new_file_map;
|
|
||||||
} else {
|
|
||||||
for msg in messages {
|
|
||||||
let _ = hot_reload.messages.send(msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
needs_full_rebuild = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if needs_full_rebuild {
|
|
||||||
match build_with() {
|
|
||||||
Ok(res) => {
|
|
||||||
last_update_time = chrono::Local::now().timestamp();
|
|
||||||
|
|
||||||
#[allow(clippy::redundant_clone)]
|
|
||||||
print_console_info(
|
|
||||||
&config,
|
|
||||||
PrettierOptions {
|
|
||||||
changed: e.paths.clone(),
|
|
||||||
warnings: res.warnings,
|
|
||||||
elapsed_time: res.elapsed_time,
|
|
||||||
},
|
|
||||||
web_info.clone(),
|
|
||||||
);
|
|
||||||
|
|
||||||
#[cfg(feature = "plugin")]
|
|
||||||
let _ = crate::plugin::PluginManager::on_serve_rebuild(
|
|
||||||
chrono::Local::now().timestamp(),
|
|
||||||
e.paths,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
Err(e) => log::error!("{}", e),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -290,7 +290,7 @@ async fn setup_router(
|
|||||||
std::fs::read_to_string(
|
std::fs::read_to_string(
|
||||||
file_service_config
|
file_service_config
|
||||||
.crate_dir
|
.crate_dir
|
||||||
.join(file_service_config.out_dir)
|
.join(file_service_config.out_dir())
|
||||||
.join("index.html"),
|
.join("index.html"),
|
||||||
)
|
)
|
||||||
.ok()
|
.ok()
|
||||||
@@ -315,7 +315,7 @@ async fn setup_router(
|
|||||||
Ok(response)
|
Ok(response)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.service(ServeDir::new(config.crate_dir.join(&config.out_dir)));
|
.service(ServeDir::new(config.crate_dir.join(config.out_dir())));
|
||||||
|
|
||||||
// Setup websocket
|
// Setup websocket
|
||||||
let mut router = Router::new().route("/_dioxus/ws", get(ws_handler));
|
let mut router = Router::new().route("/_dioxus/ws", get(ws_handler));
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ use std::{
|
|||||||
|
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
use flate2::read::GzDecoder;
|
use flate2::read::GzDecoder;
|
||||||
use futures::StreamExt;
|
use futures_util::StreamExt;
|
||||||
use tar::Archive;
|
use tar::Archive;
|
||||||
use tokio::io::AsyncWriteExt;
|
use tokio::io::AsyncWriteExt;
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
use dioxus::dioxus_core::Mutation::*;
|
use dioxus::dioxus_core::Mutation::*;
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
use dioxus_core::{ElementId, NoOpMutations};
|
use dioxus_core::{AttributeValue, ElementId, NoOpMutations};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn text_diff() {
|
fn text_diff() {
|
||||||
@@ -82,3 +82,122 @@ fn element_swap() {
|
|||||||
]
|
]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn attribute_diff() {
|
||||||
|
fn app(cx: Scope) -> Element {
|
||||||
|
let gen = cx.generation();
|
||||||
|
|
||||||
|
// attributes have to be sorted by name
|
||||||
|
let attrs = match gen % 5 {
|
||||||
|
0 => cx.bump().alloc([Attribute::new(
|
||||||
|
"a",
|
||||||
|
AttributeValue::Text("hello"),
|
||||||
|
None,
|
||||||
|
false,
|
||||||
|
)]) as &[Attribute],
|
||||||
|
1 => cx.bump().alloc([
|
||||||
|
Attribute::new("a", AttributeValue::Text("hello"), None, false),
|
||||||
|
Attribute::new("b", AttributeValue::Text("hello"), None, false),
|
||||||
|
Attribute::new("c", AttributeValue::Text("hello"), None, false),
|
||||||
|
]) as &[Attribute],
|
||||||
|
2 => cx.bump().alloc([
|
||||||
|
Attribute::new("c", AttributeValue::Text("hello"), None, false),
|
||||||
|
Attribute::new("d", AttributeValue::Text("hello"), None, false),
|
||||||
|
Attribute::new("e", AttributeValue::Text("hello"), None, false),
|
||||||
|
]) as &[Attribute],
|
||||||
|
3 => cx.bump().alloc([Attribute::new(
|
||||||
|
"d",
|
||||||
|
AttributeValue::Text("world"),
|
||||||
|
None,
|
||||||
|
false,
|
||||||
|
)]) as &[Attribute],
|
||||||
|
_ => unreachable!(),
|
||||||
|
};
|
||||||
|
|
||||||
|
cx.render(rsx!(
|
||||||
|
div {
|
||||||
|
..*attrs,
|
||||||
|
"hello"
|
||||||
|
}
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut vdom = VirtualDom::new(app);
|
||||||
|
_ = vdom.rebuild();
|
||||||
|
|
||||||
|
vdom.mark_dirty(ScopeId::ROOT);
|
||||||
|
assert_eq!(
|
||||||
|
vdom.render_immediate().santize().edits,
|
||||||
|
[
|
||||||
|
SetAttribute {
|
||||||
|
name: "b",
|
||||||
|
value: (&AttributeValue::Text("hello",)).into(),
|
||||||
|
id: ElementId(1,),
|
||||||
|
ns: None,
|
||||||
|
},
|
||||||
|
SetAttribute {
|
||||||
|
name: "c",
|
||||||
|
value: (&AttributeValue::Text("hello",)).into(),
|
||||||
|
id: ElementId(1,),
|
||||||
|
ns: None,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
vdom.mark_dirty(ScopeId::ROOT);
|
||||||
|
assert_eq!(
|
||||||
|
vdom.render_immediate().santize().edits,
|
||||||
|
[
|
||||||
|
SetAttribute {
|
||||||
|
name: "a",
|
||||||
|
value: (&AttributeValue::None).into(),
|
||||||
|
id: ElementId(1,),
|
||||||
|
ns: None,
|
||||||
|
},
|
||||||
|
SetAttribute {
|
||||||
|
name: "b",
|
||||||
|
value: (&AttributeValue::None).into(),
|
||||||
|
id: ElementId(1,),
|
||||||
|
ns: None,
|
||||||
|
},
|
||||||
|
SetAttribute {
|
||||||
|
name: "d",
|
||||||
|
value: (&AttributeValue::Text("hello",)).into(),
|
||||||
|
id: ElementId(1,),
|
||||||
|
ns: None,
|
||||||
|
},
|
||||||
|
SetAttribute {
|
||||||
|
name: "e",
|
||||||
|
value: (&AttributeValue::Text("hello",)).into(),
|
||||||
|
id: ElementId(1,),
|
||||||
|
ns: None,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
vdom.mark_dirty(ScopeId::ROOT);
|
||||||
|
assert_eq!(
|
||||||
|
vdom.render_immediate().santize().edits,
|
||||||
|
[
|
||||||
|
SetAttribute {
|
||||||
|
name: "c",
|
||||||
|
value: (&AttributeValue::None).into(),
|
||||||
|
id: ElementId(1,),
|
||||||
|
ns: None,
|
||||||
|
},
|
||||||
|
SetAttribute {
|
||||||
|
name: "d",
|
||||||
|
value: (&AttributeValue::Text("world",)).into(),
|
||||||
|
id: ElementId(1,),
|
||||||
|
ns: None,
|
||||||
|
},
|
||||||
|
SetAttribute {
|
||||||
|
name: "e",
|
||||||
|
value: (&AttributeValue::None).into(),
|
||||||
|
id: ElementId(1,),
|
||||||
|
ns: None,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -147,7 +147,7 @@ fn app() -> Element {
|
|||||||
ctrlKey: false,
|
ctrlKey: false,
|
||||||
metaKey: false,
|
metaKey: false,
|
||||||
shiftKey: false,
|
shiftKey: false,
|
||||||
isComposing: false,
|
isComposing: true,
|
||||||
which: 65,
|
which: 65,
|
||||||
bubbles: true,
|
bubbles: true,
|
||||||
})"#,
|
})"#,
|
||||||
@@ -343,7 +343,8 @@ fn app() -> Element {
|
|||||||
assert_eq!(event.data.code().to_string(), "KeyA");
|
assert_eq!(event.data.code().to_string(), "KeyA");
|
||||||
assert_eq!(event.data.location(), Location::Standard);
|
assert_eq!(event.data.location(), Location::Standard);
|
||||||
assert!(event.data.is_auto_repeating());
|
assert!(event.data.is_auto_repeating());
|
||||||
received_events.with_mut(|x| *x + 1);
|
assert!(event.data.is_composing());
|
||||||
|
received_events.with_mut(|x| *x + 1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
input {
|
input {
|
||||||
@@ -355,7 +356,8 @@ fn app() -> Element {
|
|||||||
assert_eq!(event.data.code().to_string(), "KeyA");
|
assert_eq!(event.data.code().to_string(), "KeyA");
|
||||||
assert_eq!(event.data.location(), Location::Standard);
|
assert_eq!(event.data.location(), Location::Standard);
|
||||||
assert!(!event.data.is_auto_repeating());
|
assert!(!event.data.is_auto_repeating());
|
||||||
received_events.with_mut(|x| *x + 1);
|
assert!(!event.data.is_composing());
|
||||||
|
received_events.with_mut(|x| *x + 1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
input {
|
input {
|
||||||
@@ -367,7 +369,8 @@ fn app() -> Element {
|
|||||||
assert_eq!(event.data.code().to_string(), "KeyA");
|
assert_eq!(event.data.code().to_string(), "KeyA");
|
||||||
assert_eq!(event.data.location(), Location::Standard);
|
assert_eq!(event.data.location(), Location::Standard);
|
||||||
assert!(!event.data.is_auto_repeating());
|
assert!(!event.data.is_auto_repeating());
|
||||||
received_events.with_mut(|x| *x + 1);
|
assert!(!event.data.is_composing());
|
||||||
|
received_events.with_mut(|x| *x + 1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
input {
|
input {
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ mod impl_ {
|
|||||||
])
|
])
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let edit_menu = Submenu::new("Window", true);
|
let edit_menu = Submenu::new("Edit", true);
|
||||||
edit_menu
|
edit_menu
|
||||||
.append_items(&[
|
.append_items(&[
|
||||||
&PredefinedMenuItem::undo(None),
|
&PredefinedMenuItem::undo(None),
|
||||||
|
|||||||
@@ -91,7 +91,28 @@ impl WebviewInstance {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut webview = WebViewBuilder::new(&window)
|
#[cfg(any(
|
||||||
|
target_os = "windows",
|
||||||
|
target_os = "macos",
|
||||||
|
target_os = "ios",
|
||||||
|
target_os = "android"
|
||||||
|
))]
|
||||||
|
let mut webview = WebViewBuilder::new(&window);
|
||||||
|
|
||||||
|
#[cfg(not(any(
|
||||||
|
target_os = "windows",
|
||||||
|
target_os = "macos",
|
||||||
|
target_os = "ios",
|
||||||
|
target_os = "android"
|
||||||
|
)))]
|
||||||
|
let mut webview = {
|
||||||
|
use tao::platform::unix::WindowExtUnix;
|
||||||
|
use wry::WebViewBuilderExtUnix;
|
||||||
|
let vbox = window.default_vbox().unwrap();
|
||||||
|
WebViewBuilder::new_gtk(vbox)
|
||||||
|
};
|
||||||
|
|
||||||
|
webview = webview
|
||||||
.with_transparent(cfg.window.window.transparent)
|
.with_transparent(cfg.window.window.transparent)
|
||||||
.with_url("dioxus://index.html/")
|
.with_url("dioxus://index.html/")
|
||||||
.unwrap()
|
.unwrap()
|
||||||
|
|||||||
@@ -1744,4 +1744,199 @@ builder_constructors! {
|
|||||||
r#use ["use", "http://www.w3.org/2000/svg"] {
|
r#use ["use", "http://www.w3.org/2000/svg"] {
|
||||||
href: String DEFAULT,
|
href: String DEFAULT,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// MathML elements
|
||||||
|
|
||||||
|
/// Build a
|
||||||
|
/// [`<annotation>`](https://w3c.github.io/mathml-core/#dfn-annotation)
|
||||||
|
/// element.
|
||||||
|
annotation "http://www.w3.org/1998/Math/MathML" {
|
||||||
|
encoding: String DEFAULT,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Build a
|
||||||
|
/// [`<annotation-xml>`](https://w3c.github.io/mathml-core/#dfn-annotation-xml)
|
||||||
|
/// element.
|
||||||
|
annotationXml ["annotation-xml", "http://www.w3.org/1998/Math/MathML"] {
|
||||||
|
encoding: String DEFAULT,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Build a
|
||||||
|
/// [`<merror>`](https://developer.mozilla.org/en-US/docs/Web/MathML/Element/merror)
|
||||||
|
/// element.
|
||||||
|
merror "http://www.w3.org/1998/Math/MathML" {};
|
||||||
|
|
||||||
|
/// Build a
|
||||||
|
/// [`<math>`](https://developer.mozilla.org/en-US/docs/Web/MathML/Element/math)
|
||||||
|
/// element.
|
||||||
|
math "http://www.w3.org/1998/Math/MathML" {
|
||||||
|
display: String DEFAULT,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Build a
|
||||||
|
/// [`<mfrac>`](https://developer.mozilla.org/en-US/docs/Web/MathML/Element/mfrac)
|
||||||
|
/// element.
|
||||||
|
mfrac "http://www.w3.org/1998/Math/MathML" {
|
||||||
|
linethickness: usize DEFAULT,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Build a
|
||||||
|
/// [`<mi>`](https://developer.mozilla.org/en-US/docs/Web/MathML/Element/mi)
|
||||||
|
/// element.
|
||||||
|
mi "http://www.w3.org/1998/Math/MathML" {
|
||||||
|
mathvariant: String DEFAULT,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Build a
|
||||||
|
/// [`<mmultiscripts>`](https://developer.mozilla.org/en-US/docs/Web/MathML/Element/mmultiscripts)
|
||||||
|
/// element.
|
||||||
|
mmultiscripts "http://www.w3.org/1998/math/mathml" {};
|
||||||
|
|
||||||
|
/// Build a
|
||||||
|
/// [`<mn>`](https://developer.mozilla.org/en-US/docs/Web/MathML/Element/mn)
|
||||||
|
/// element.
|
||||||
|
mn "http://www.w3.org/1998/Math/MathML" {};
|
||||||
|
|
||||||
|
/// Build a
|
||||||
|
/// [`<mo>`](https://developer.mozilla.org/en-US/docs/Web/MathML/Element/mo)
|
||||||
|
/// element.
|
||||||
|
mo "http://www.w3.org/1998/Math/MathML" {
|
||||||
|
fence: Bool DEFAULT,
|
||||||
|
largeop: Bool DEFAULT,
|
||||||
|
lspace: usize DEFAULT,
|
||||||
|
maxsize: usize DEFAULT,
|
||||||
|
minsize: usize DEFAULT,
|
||||||
|
movablelimits: Bool DEFAULT,
|
||||||
|
rspace: usize DEFAULT,
|
||||||
|
separator: Bool DEFAULT,
|
||||||
|
stretchy: Bool DEFAULT,
|
||||||
|
symmetric: Bool DEFAULT,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Build a
|
||||||
|
/// [`<mover>`](https://developer.mozilla.org/en-US/docs/Web/MathML/Element/mover)
|
||||||
|
/// element.
|
||||||
|
mover "http://www.w3.org/1998/Math/MathML" {
|
||||||
|
accent: Bool DEFAULT,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Build a
|
||||||
|
/// [`<mpadded>`](https://developer.mozilla.org/en-US/docs/Web/MathML/Element/mpadded)
|
||||||
|
/// element.
|
||||||
|
mpadded "http://www.w3.org/1998/Math/MathML" {
|
||||||
|
depth: usize DEFAULT,
|
||||||
|
height: usize DEFAULT,
|
||||||
|
lspace: usize DEFAULT,
|
||||||
|
voffset: usize DEFAULT,
|
||||||
|
width: usize DEFAULT,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Build a
|
||||||
|
/// [`<mphantom>`](https://developer.mozilla.org/en-US/docs/Web/MathML/Element/mphantom)
|
||||||
|
/// element.
|
||||||
|
mphantom "http://www.w3.org/1998/Math/MathML" {};
|
||||||
|
|
||||||
|
/// Build a
|
||||||
|
/// [`<mprescripts>`](https://developer.mozilla.org/en-US/docs/Web/MathML/Element/mprescripts)
|
||||||
|
/// element.
|
||||||
|
mprescripts "http://www.w3.org/1998/Math/MathML" {};
|
||||||
|
|
||||||
|
/// Build a
|
||||||
|
/// [`<mroot>`](https://developer.mozilla.org/en-US/docs/Web/MathML/Element/mroot)
|
||||||
|
/// element.
|
||||||
|
mroot "http://www.w3.org/1998/Math/MathML" {};
|
||||||
|
|
||||||
|
/// Build a
|
||||||
|
/// [`<mrow>`](https://developer.mozilla.org/en-US/docs/Web/MathML/Element/mrow)
|
||||||
|
/// element.
|
||||||
|
mrow "http://www.w3.org/1998/Math/MathML" {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Build a
|
||||||
|
/// [`<ms>`](https://developer.mozilla.org/en-US/docs/Web/MathML/Element/ms)
|
||||||
|
/// element.
|
||||||
|
ms "http://www.w3.org/1998/Math/MathML" {
|
||||||
|
lquote: String DEFAULT,
|
||||||
|
rquote: String DEFAULT,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Build a
|
||||||
|
/// [`<mspace>`](https://developer.mozilla.org/en-US/docs/Web/MathML/Element/mspace)
|
||||||
|
/// element.
|
||||||
|
mspace "http://www.w3.org/1998/Math/MathML" {
|
||||||
|
depth: usize DEFAULT,
|
||||||
|
height: usize DEFAULT,
|
||||||
|
width: usize DEFAULT,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Build a
|
||||||
|
/// [`<msqrt>`](https://developer.mozilla.org/en-US/docs/Web/MathML/Element/msqrt)
|
||||||
|
/// element.
|
||||||
|
msqrt "http://www.w3.org/1998/Math/MathML" {};
|
||||||
|
|
||||||
|
/// Build a
|
||||||
|
/// [`<mstyle>`](https://developer.mozilla.org/en-US/docs/Web/MathML/Element/mstyle)
|
||||||
|
/// element.
|
||||||
|
mstyle "http://www.w3.org/1998/Math/MathML" {};
|
||||||
|
|
||||||
|
/// Build a
|
||||||
|
/// [`<msub>`](https://developer.mozilla.org/en-US/docs/Web/MathML/Element/msub)
|
||||||
|
/// element.
|
||||||
|
msub "http://www.w3.org/1998/Math/MathML" {};
|
||||||
|
|
||||||
|
/// Build a
|
||||||
|
/// [`<msubsup>`](https://developer.mozilla.org/en-US/docs/Web/MathML/Element/msubsup)
|
||||||
|
/// element.
|
||||||
|
msubsup "http://www.w3.org/1998/Math/MathML" {};
|
||||||
|
|
||||||
|
/// Build a
|
||||||
|
/// [`<msup>`](https://developer.mozilla.org/en-US/docs/Web/MathML/Element/msup)
|
||||||
|
/// element.
|
||||||
|
msup "http://www.w3.org/1998/Math/MathML" {};
|
||||||
|
|
||||||
|
/// Build a
|
||||||
|
/// [`<mtable>`](https://developer.mozilla.org/en-US/docs/Web/MathML/Element/mtable)
|
||||||
|
/// element.
|
||||||
|
mtable "http://www.w3.org/1998/Math/MathML" {};
|
||||||
|
|
||||||
|
/// Build a
|
||||||
|
/// [`<mtd>`](https://developer.mozilla.org/en-US/docs/Web/MathML/Element/mtd)
|
||||||
|
/// element.
|
||||||
|
mtd "http://www.w3.org/1998/Math/MathML" {
|
||||||
|
columnspan: usize DEFAULT,
|
||||||
|
rowspan: usize DEFAULT,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Build a
|
||||||
|
/// [`<mtext>`](https://developer.mozilla.org/en-US/docs/Web/MathML/Element/mtext)
|
||||||
|
/// element.
|
||||||
|
mtext "http://www.w3.org/1998/Math/MathML" {};
|
||||||
|
|
||||||
|
/// Build a
|
||||||
|
/// [`<mtr>`](https://developer.mozilla.org/en-US/docs/Web/MathML/Element/mtr)
|
||||||
|
/// element.
|
||||||
|
mtr "http://www.w3.org/1998/Math/MathML" {};
|
||||||
|
|
||||||
|
/// Build a
|
||||||
|
/// [`<munder>`](https://developer.mozilla.org/en-US/docs/Web/MathML/Element/munder)
|
||||||
|
/// element.
|
||||||
|
munder "http://www.w3.org/1998/Math/MathML" {
|
||||||
|
accentunder: Bool DEFAULT,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Build a
|
||||||
|
/// [`<munderover>`](https://developer.mozilla.org/en-US/docs/Web/MathML/Element/munderover)
|
||||||
|
/// element.
|
||||||
|
munderover "http://www.w3.org/1998/Math/MathML" {
|
||||||
|
accent: Bool DEFAULT,
|
||||||
|
accentunder: Bool DEFAULT,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Build a
|
||||||
|
/// [`<semantics>`](https://developer.mozilla.org/en-US/docs/Web/MathML/Element/semantics)
|
||||||
|
/// element.
|
||||||
|
semantics "http://www.w3.org/1998/Math/MathML" {
|
||||||
|
encoding: String DEFAULT,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
@@ -33,6 +33,7 @@ impl std::fmt::Debug for KeyboardData {
|
|||||||
.field("modifiers", &self.modifiers())
|
.field("modifiers", &self.modifiers())
|
||||||
.field("location", &self.location())
|
.field("location", &self.location())
|
||||||
.field("is_auto_repeating", &self.is_auto_repeating())
|
.field("is_auto_repeating", &self.is_auto_repeating())
|
||||||
|
.field("is_composing", &self.is_composing())
|
||||||
.finish()
|
.finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -44,6 +45,7 @@ impl PartialEq for KeyboardData {
|
|||||||
&& self.modifiers() == other.modifiers()
|
&& self.modifiers() == other.modifiers()
|
||||||
&& self.location() == other.location()
|
&& self.location() == other.location()
|
||||||
&& self.is_auto_repeating() == other.is_auto_repeating()
|
&& self.is_auto_repeating() == other.is_auto_repeating()
|
||||||
|
&& self.is_composing() == other.is_composing()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -75,6 +77,11 @@ impl KeyboardData {
|
|||||||
self.inner.is_auto_repeating()
|
self.inner.is_auto_repeating()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Indicates whether the key is fired within a composition session.
|
||||||
|
pub fn is_composing(&self) -> bool {
|
||||||
|
self.inner.is_composing()
|
||||||
|
}
|
||||||
|
|
||||||
/// Downcast this KeyboardData to a concrete type.
|
/// Downcast this KeyboardData to a concrete type.
|
||||||
pub fn downcast<T: 'static>(&self) -> Option<&T> {
|
pub fn downcast<T: 'static>(&self) -> Option<&T> {
|
||||||
self.inner.as_any().downcast_ref::<T>()
|
self.inner.as_any().downcast_ref::<T>()
|
||||||
@@ -92,6 +99,7 @@ impl ModifiersInteraction for KeyboardData {
|
|||||||
#[derive(serde::Serialize, serde::Deserialize, Debug, PartialEq, Clone)]
|
#[derive(serde::Serialize, serde::Deserialize, Debug, PartialEq, Clone)]
|
||||||
pub struct SerializedKeyboardData {
|
pub struct SerializedKeyboardData {
|
||||||
char_code: u32,
|
char_code: u32,
|
||||||
|
is_composing: bool,
|
||||||
key: String,
|
key: String,
|
||||||
key_code: KeyCode,
|
key_code: KeyCode,
|
||||||
#[serde(deserialize_with = "resilient_deserialize_code")]
|
#[serde(deserialize_with = "resilient_deserialize_code")]
|
||||||
@@ -114,9 +122,11 @@ impl SerializedKeyboardData {
|
|||||||
location: Location,
|
location: Location,
|
||||||
is_auto_repeating: bool,
|
is_auto_repeating: bool,
|
||||||
modifiers: Modifiers,
|
modifiers: Modifiers,
|
||||||
|
is_composing: bool,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
char_code: key.legacy_charcode(),
|
char_code: key.legacy_charcode(),
|
||||||
|
is_composing,
|
||||||
key: key.to_string(),
|
key: key.to_string(),
|
||||||
key_code: KeyCode::from_raw_code(
|
key_code: KeyCode::from_raw_code(
|
||||||
std::convert::TryInto::try_into(key.legacy_keycode())
|
std::convert::TryInto::try_into(key.legacy_keycode())
|
||||||
@@ -144,6 +154,7 @@ impl From<&KeyboardData> for SerializedKeyboardData {
|
|||||||
data.location(),
|
data.location(),
|
||||||
data.is_auto_repeating(),
|
data.is_auto_repeating(),
|
||||||
data.modifiers(),
|
data.modifiers(),
|
||||||
|
data.is_composing(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -166,6 +177,10 @@ impl HasKeyboardData for SerializedKeyboardData {
|
|||||||
self.repeat
|
self.repeat
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn is_composing(&self) -> bool {
|
||||||
|
self.is_composing
|
||||||
|
}
|
||||||
|
|
||||||
fn as_any(&self) -> &dyn std::any::Any {
|
fn as_any(&self) -> &dyn std::any::Any {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
@@ -236,6 +251,9 @@ pub trait HasKeyboardData: ModifiersInteraction + std::any::Any {
|
|||||||
/// `true` iff the key is being held down such that it is automatically repeating.
|
/// `true` iff the key is being held down such that it is automatically repeating.
|
||||||
fn is_auto_repeating(&self) -> bool;
|
fn is_auto_repeating(&self) -> bool;
|
||||||
|
|
||||||
|
/// Indicates whether the key is fired within a composition session.
|
||||||
|
fn is_composing(&self) -> bool;
|
||||||
|
|
||||||
/// return self as Any
|
/// return self as Any
|
||||||
fn as_any(&self) -> &dyn std::any::Any;
|
fn as_any(&self) -> &dyn std::any::Any;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -78,6 +78,10 @@ impl HasKeyboardData for KeyboardEvent {
|
|||||||
self.repeat()
|
self.repeat()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn is_composing(&self) -> bool {
|
||||||
|
self.is_composing()
|
||||||
|
}
|
||||||
|
|
||||||
fn as_any(&self) -> &dyn std::any::Any {
|
fn as_any(&self) -> &dyn std::any::Any {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -351,6 +351,7 @@ async function serialize_event(event) {
|
|||||||
case "keyup": {
|
case "keyup": {
|
||||||
let {
|
let {
|
||||||
charCode,
|
charCode,
|
||||||
|
isComposing,
|
||||||
key,
|
key,
|
||||||
altKey,
|
altKey,
|
||||||
ctrlKey,
|
ctrlKey,
|
||||||
@@ -364,6 +365,7 @@ async function serialize_event(event) {
|
|||||||
} = event;
|
} = event;
|
||||||
return {
|
return {
|
||||||
char_code: charCode,
|
char_code: charCode,
|
||||||
|
is_composing: isComposing,
|
||||||
key: key,
|
key: key,
|
||||||
alt_key: altKey,
|
alt_key: altKey,
|
||||||
ctrl_key: ctrlKey,
|
ctrl_key: ctrlKey,
|
||||||
|
|||||||
@@ -179,6 +179,7 @@ impl InnerInputState {
|
|||||||
k.location(),
|
k.location(),
|
||||||
is_repeating,
|
is_repeating,
|
||||||
k.modifiers(),
|
k.modifiers(),
|
||||||
|
k.is_composing(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -779,6 +780,7 @@ fn translate_key_event(event: crossterm::event::KeyEvent) -> Option<EventData> {
|
|||||||
Location::Standard,
|
Location::Standard,
|
||||||
false,
|
false,
|
||||||
modifiers,
|
modifiers,
|
||||||
|
false,
|
||||||
)))
|
)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -84,7 +84,7 @@ mod segment;
|
|||||||
///
|
///
|
||||||
/// # `#[route("path", component)]`
|
/// # `#[route("path", component)]`
|
||||||
///
|
///
|
||||||
/// The `#[route]` attribute is used to define a route. It takes up to 3 parameters:
|
/// The `#[route]` attribute is used to define a route. It takes up to 2 parameters:
|
||||||
/// - `path`: The path to the enum variant (relative to the parent nest)
|
/// - `path`: The path to the enum variant (relative to the parent nest)
|
||||||
/// - (optional) `component`: The component to render when the route is matched. If not specified, the name of the variant is used
|
/// - (optional) `component`: The component to render when the route is matched. If not specified, the name of the variant is used
|
||||||
///
|
///
|
||||||
@@ -162,7 +162,7 @@ mod segment;
|
|||||||
///
|
///
|
||||||
/// # `#[layout(component)]`
|
/// # `#[layout(component)]`
|
||||||
///
|
///
|
||||||
/// The `#[layout]` attribute is used to define a layout. It takes 2 parameters:
|
/// The `#[layout]` attribute is used to define a layout. It takes 1 parameters:
|
||||||
/// - `component`: The component to render when the route is matched. If not specified, the name of the variant is used
|
/// - `component`: The component to render when the route is matched. If not specified, the name of the variant is used
|
||||||
///
|
///
|
||||||
/// The layout component allows you to wrap all children of the layout in a component. The child routes are rendered in the Outlet of the layout component. The layout component must take all dynamic parameters of the nests it is nested in.
|
/// The layout component allows you to wrap all children of the layout in a component. The child routes are rendered in the Outlet of the layout component. The layout component must take all dynamic parameters of the nests it is nested in.
|
||||||
|
|||||||
+20
-3
@@ -9,7 +9,8 @@
|
|||||||
/// ```
|
/// ```
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
pub(crate) hydrate: bool,
|
pub(crate) hydrate: bool,
|
||||||
pub(crate) rootname: String,
|
pub(crate) root: ConfigRoot,
|
||||||
|
pub(crate) cached_strings: Vec<String>,
|
||||||
pub(crate) default_panic_hook: bool,
|
pub(crate) default_panic_hook: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -17,7 +18,8 @@ impl Default for Config {
|
|||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
hydrate: false,
|
hydrate: false,
|
||||||
rootname: "main".to_string(),
|
root: ConfigRoot::RootName("main".to_string()),
|
||||||
|
cached_strings: Vec::new(),
|
||||||
default_panic_hook: true,
|
default_panic_hook: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -46,8 +48,18 @@ impl Config {
|
|||||||
/// Set the name of the element that Dioxus will use as the root.
|
/// Set the name of the element that Dioxus will use as the root.
|
||||||
///
|
///
|
||||||
/// This is akin to calling React.render() on the element with the specified name.
|
/// This is akin to calling React.render() on the element with the specified name.
|
||||||
|
/// Note that this only works on the current document, i.e. `window.document`.
|
||||||
|
/// To use a different document (popup, iframe, ...) use [Self::rootelement] instead.
|
||||||
pub fn rootname(mut self, name: impl Into<String>) -> Self {
|
pub fn rootname(mut self, name: impl Into<String>) -> Self {
|
||||||
self.rootname = name.into();
|
self.root = ConfigRoot::RootName(name.into());
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set the element that Dioxus will use as root.
|
||||||
|
///
|
||||||
|
/// This is akin to calling React.render() on the given element.
|
||||||
|
pub fn rootelement(mut self, elem: web_sys::Element) -> Self {
|
||||||
|
self.root = ConfigRoot::RootElement(elem);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -59,3 +71,8 @@ impl Config {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) enum ConfigRoot {
|
||||||
|
RootName(String),
|
||||||
|
RootElement(web_sys::Element),
|
||||||
|
}
|
||||||
+26
-14
@@ -36,24 +36,36 @@ pub struct UiEvent {
|
|||||||
pub data: PlatformEventData,
|
pub data: PlatformEventData,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//fn get_document(elem: &web_sys::Element) ->
|
||||||
|
|
||||||
impl WebsysDom {
|
impl WebsysDom {
|
||||||
pub fn new(cfg: Config, event_channel: mpsc::UnboundedSender<UiEvent>) -> Self {
|
pub fn new(cfg: Config, event_channel: mpsc::UnboundedSender<UiEvent>) -> Self {
|
||||||
// eventually, we just want to let the interpreter do all the work of decoding events into our event type
|
let (document, root) = match cfg.root {
|
||||||
// a match here in order to avoid some error during runtime browser test
|
crate::cfg::ConfigRoot::RootName(rootname) => {
|
||||||
let document = load_document();
|
// eventually, we just want to let the interpreter do all the work of decoding events into our event type
|
||||||
let root = match document.get_element_by_id(&cfg.rootname) {
|
// a match here in order to avoid some error during runtime browser test
|
||||||
Some(root) => root,
|
let document = load_document();
|
||||||
None => {
|
let root = match document.get_element_by_id(&rootname) {
|
||||||
web_sys::console::error_1(
|
Some(root) => root,
|
||||||
&format!(
|
None => {
|
||||||
"element '#{}' not found. mounting to the body.",
|
web_sys::console::error_1(
|
||||||
cfg.rootname
|
&format!("element '#{}' not found. mounting to the body.", rootname)
|
||||||
)
|
.into(),
|
||||||
.into(),
|
);
|
||||||
);
|
document.create_element("body").ok().unwrap()
|
||||||
document.create_element("body").ok().unwrap()
|
}
|
||||||
|
};
|
||||||
|
(document, root)
|
||||||
|
}
|
||||||
|
crate::cfg::ConfigRoot::RootElement(root) => {
|
||||||
|
let document = match root.owner_document() {
|
||||||
|
Some(document) => document,
|
||||||
|
None => load_document(),
|
||||||
|
};
|
||||||
|
(document, root)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let interpreter = Channel::default();
|
let interpreter = Channel::default();
|
||||||
|
|
||||||
let handler: Closure<dyn FnMut(&Event)> = Closure::wrap(Box::new({
|
let handler: Closure<dyn FnMut(&Event)> = Closure::wrap(Box::new({
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<p align="center">
|
<p align="center">
|
||||||
<img src="../header.svg">
|
<img src="../../notes/header.svg">
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div align="center">
|
<div align="center">
|
||||||
@@ -66,17 +66,17 @@ fn app() -> Element {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Dioxus 可用于生成 网页前端、桌面应用、静态网站、移动端应用、TUI程序、等多类平台应用。
|
Dioxus 可用于生成 网页前端、桌面应用、静态网站、移动端应用、TUI程序、 liveview程序等多类平台应用,Dioxus完全与渲染器无关,可以作用于任何渲染平台。
|
||||||
|
|
||||||
如果你能够熟悉使用 React 框架,那 Dioxus 对你来说将非常简单。
|
如果你能够熟悉使用 React 框架,那 Dioxus 对你来说将非常简单。
|
||||||
|
|
||||||
## 独特的特性:
|
## 独特的特性:
|
||||||
- 桌面程序完全基于本地环境运行(并非 Electron 的封装)
|
- 只需不到10行代码就能原生运行桌面程序(并非 Electron 的封装)
|
||||||
- 符合人体工程学的设计以及拥有强大的状态管理
|
- 符合人体工程学的设计以及拥有强大的状态管理
|
||||||
- 全面的内联文档 - 包含所有 HTML 元素、监听器 和 事件 指南。
|
- 全面的内联文档 - 包含所有 HTML 元素、监听器 和 事件 指南。
|
||||||
- 极快的运行效率和极高的内存效率
|
- 极快的运行效率🔥🔥和极高的内存效率
|
||||||
- 智能项目热更新和高效的项目迭代
|
- 智能项目热重载以便快速迭代
|
||||||
- 一流的异步支持🔥
|
- 使用协程和Suspense来进行一流的异步支持
|
||||||
- 更多内容请查看 [版本发布信息](https://dioxuslabs.com/blog/introducing-dioxus/).
|
- 更多内容请查看 [版本发布信息](https://dioxuslabs.com/blog/introducing-dioxus/).
|
||||||
|
|
||||||
## 已支持的平台
|
## 已支持的平台
|
||||||
@@ -89,7 +89,7 @@ Dioxus 可用于生成 网页前端、桌面应用、静态网站、移动端应
|
|||||||
<li>使用 WebAssembly 直接对 DOM 进行渲染</li>
|
<li>使用 WebAssembly 直接对 DOM 进行渲染</li>
|
||||||
<li>为 SSR 提供预渲染或作为客户端使用</li>
|
<li>为 SSR 提供预渲染或作为客户端使用</li>
|
||||||
<li>简单的 "Hello World" 仅仅 65kb, 媲美 React 框架</li>
|
<li>简单的 "Hello World" 仅仅 65kb, 媲美 React 框架</li>
|
||||||
<li>CLI 提供热更新支持,方便项目快速迭代</li>
|
<li>内置开发服务和热重载支持,方便项目快速迭代</li>
|
||||||
</ul>
|
</ul>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@@ -98,7 +98,7 @@ Dioxus 可用于生成 网页前端、桌面应用、静态网站、移动端应
|
|||||||
<td>
|
<td>
|
||||||
<ul>
|
<ul>
|
||||||
<li>使用 Webview 进行渲染 或 使用 WGPU 和 Skia(试验性的)</li>
|
<li>使用 Webview 进行渲染 或 使用 WGPU 和 Skia(试验性的)</li>
|
||||||
<li>无多余配置,使用 `cargo build` 即可快速构建</li>
|
<li>无多余配置,简单的使用 `cargo build` 即可快速构建</li>
|
||||||
<li>对原生系统的全面支持</li>
|
<li>对原生系统的全面支持</li>
|
||||||
<li>支持 Macos、Linux、Windows 等系统,极小的二进制文件</li>
|
<li>支持 Macos、Linux、Windows 等系统,极小的二进制文件</li>
|
||||||
</ul>
|
</ul>
|
||||||
@@ -118,9 +118,9 @@ Dioxus 可用于生成 网页前端、桌面应用、静态网站、移动端应
|
|||||||
<td><em>Liveview</em></td>
|
<td><em>Liveview</em></td>
|
||||||
<td>
|
<td>
|
||||||
<ul>
|
<ul>
|
||||||
<li>使用服务器渲染组件与应用程序</li>
|
<li>完全使用服务器渲染应用程序或单个组件</li>
|
||||||
<li>与受欢迎的后端框架进行融合(Axum、Wrap)</li>
|
<li>与受欢迎的后端框架进行融合(Axum、Wrap)</li>
|
||||||
<li>及低的延迟</li>
|
<li>及低的延迟,可以同时支持10000个以上的终端程序</li>
|
||||||
</ul>
|
</ul>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@@ -130,22 +130,22 @@ Dioxus 可用于生成 网页前端、桌面应用、静态网站、移动端应
|
|||||||
<ul>
|
<ul>
|
||||||
<li>在终端程序中渲染,类似于: <a href="https://github.com/vadimdemedes/ink"> ink.js</a></li>
|
<li>在终端程序中渲染,类似于: <a href="https://github.com/vadimdemedes/ink"> ink.js</a></li>
|
||||||
<li>支持 CSS 相关模型(类似于浏览器内的)</li>
|
<li>支持 CSS 相关模型(类似于浏览器内的)</li>
|
||||||
<li>Built-in widgets like text input, buttons, and focus system</li>
|
<li>内置类似文字输入,按钮和焦点系统的小组件</li>
|
||||||
</ul>
|
</ul>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
## Why Dioxus?
|
## 为什么选择Dioxus?
|
||||||
|
|
||||||
目前有非常多的应用开发选择,为什么偏偏要选择 Dioxus 呢?
|
目前有非常多的应用开发选择,为什么偏偏要选择 Dioxus 呢?
|
||||||
|
|
||||||
首先,Dioxus将开发者的经验放在首位。这反映在 Dioxus 特有的各种功能上。
|
首先,Dioxus将开发者的体验放在首位。这体现在 Dioxus 特有的各种功能上。
|
||||||
|
|
||||||
- 自动格式化 RSX 格式代码,并拥有 VSCode 插件作为支持。
|
- 自动格式化 RSX 格式代码,并拥有 VSCode 插件作为支持。
|
||||||
- 热加载基于 RSX 代码解析器,同时支持桌面程序和网页程序。
|
- 热加载基于 RSX 代码解析器,同时支持桌面程序和网页程序。
|
||||||
- 强调文档的重要性,我们对所有 HTML 元素都提供文档支持。
|
- 强调文档的重要性--我们的指南是完整的,并且我们对所有 HTML 元素都提供文档支持。
|
||||||
|
|
||||||
Dioxus 也是一个可扩展化的平台。
|
Dioxus 也是一个可扩展化的平台。
|
||||||
|
|
||||||
@@ -160,7 +160,7 @@ Dioxus 那么优秀,但什么时候它不适合我呢?
|
|||||||
|
|
||||||
## 贡献代码
|
## 贡献代码
|
||||||
- 在我们的 [问题追踪](https://github.com/dioxuslabs/dioxus/issues) 中汇报你遇到的问题。
|
- 在我们的 [问题追踪](https://github.com/dioxuslabs/dioxus/issues) 中汇报你遇到的问题。
|
||||||
- 加入我们的 Discord 与我们交流。
|
- [加入](https://discord.gg/XgGxMSkvUM)我们的 Discord 与我们交流。
|
||||||
|
|
||||||
|
|
||||||
<a href="https://github.com/dioxuslabs/dioxus/graphs/contributors">
|
<a href="https://github.com/dioxuslabs/dioxus/graphs/contributors">
|
||||||
Reference in new issue
Block a user