Upgrade to Blitz 0.1.0-alpha.2 (#4227)
* Update to use latest Blitz net traits * Pass url to flush_style_attribute * Add system-fonts feature to dioxus-native * Native: cleanup log output * Make dioxus-native work with Blitz simplified Document and Renderer traits * Native: upgrade to event refactor * Upgrade to blitz 0.1.0-alpha.2 * Add typo exception Signed-off-by: Nico Burns <nico@nicoburns.com> * Ensure root_id is set to <main> element --------- Signed-off-by: Nico Burns <nico@nicoburns.com>
This commit is contained in:
1 parent
e1bd06bda5
commit
51d7affc54
10 files changed
+654
-1222
No files matched your search
Generated
+182
-173
@@ -379,6 +379,47 @@ version = "0.13.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d301b3b94cb4b2f23d7917810addbbaff90738e0ca2be692bd027e70d7e0330c"
|
checksum = "d301b3b94cb4b2f23d7917810addbbaff90738e0ca2be692bd027e70d7e0330c"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anyrender"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fff8da5f4a3e508ed376118a7e04ed992df07630fb47d7b3dce8d1f92427975d"
|
||||||
|
dependencies = [
|
||||||
|
"kurbo",
|
||||||
|
"peniko",
|
||||||
|
"raw-window-handle 0.6.2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anyrender_svg"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4197139c97b2d204e44fd79c58e16f1c6023d18fe3db1e3eebfa335f78e39072"
|
||||||
|
dependencies = [
|
||||||
|
"anyrender",
|
||||||
|
"image",
|
||||||
|
"kurbo",
|
||||||
|
"peniko",
|
||||||
|
"thiserror 2.0.12",
|
||||||
|
"usvg",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anyrender_vello"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "83e99c7f0936960037aa11d64bf7c9c5cf2f624dd9faf8c57a6581b056e08852"
|
||||||
|
dependencies = [
|
||||||
|
"anyrender",
|
||||||
|
"futures-intrusive",
|
||||||
|
"kurbo",
|
||||||
|
"peniko",
|
||||||
|
"pollster",
|
||||||
|
"raw-window-handle 0.6.2",
|
||||||
|
"vello",
|
||||||
|
"wgpu 24.0.5",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "app_units"
|
name = "app_units"
|
||||||
version = "0.7.8"
|
version = "0.7.8"
|
||||||
@@ -1563,24 +1604,26 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "blitz-dom"
|
name = "blitz-dom"
|
||||||
version = "0.1.0-alpha.1"
|
version = "0.1.0-alpha.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "eae8889dde80e2aaceec27455c63446ca841cb7217a4f5489691295da922792b"
|
checksum = "7dc174ecca5c3e94b162335be4c9e17b35a0b421898ea559cb7f5926ff0fe5c6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"accesskit",
|
"accesskit",
|
||||||
"app_units",
|
"app_units",
|
||||||
"atomic_refcell",
|
"atomic_refcell",
|
||||||
"blitz-traits",
|
"blitz-traits",
|
||||||
"color 0.2.4",
|
"color",
|
||||||
"cursor-icon",
|
"cursor-icon",
|
||||||
"euclid",
|
"euclid",
|
||||||
"html-escape",
|
"html-escape",
|
||||||
"image",
|
"image",
|
||||||
"keyboard-types",
|
"keyboard-types",
|
||||||
"markup5ever 0.15.0",
|
"markup5ever 0.16.1",
|
||||||
|
"objc2 0.6.1",
|
||||||
"parley",
|
"parley",
|
||||||
"peniko 0.3.2",
|
"peniko",
|
||||||
"selectors 0.27.0",
|
"percent-encoding",
|
||||||
|
"selectors 0.28.0",
|
||||||
"slab",
|
"slab",
|
||||||
"smallvec",
|
"smallvec",
|
||||||
"string_cache",
|
"string_cache",
|
||||||
@@ -1597,49 +1640,49 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "blitz-net"
|
name = "blitz-net"
|
||||||
version = "0.1.0-alpha.1"
|
version = "0.1.0-alpha.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "efc80023b8f6758d7f61bda68440917b72cbe2fe6187cbe1b7837e73b2522dfe"
|
checksum = "96b2788c54be9856d8a13a8bfcf0f184573d7169fdb6bf3f867cef87eca48874"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"blitz-traits",
|
"blitz-traits",
|
||||||
"data-url 0.3.1",
|
"data-url 0.3.1",
|
||||||
"reqwest 0.12.15",
|
"reqwest 0.12.15",
|
||||||
"thiserror 1.0.69",
|
|
||||||
"tokio",
|
"tokio",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "blitz-renderer-vello"
|
name = "blitz-paint"
|
||||||
version = "0.1.0-alpha.1"
|
version = "0.1.0-alpha.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "44fdafaf87eb502da99667fad2ae9757d01c8bd83772f6b7b6a78c48c3ab6ff5"
|
checksum = "3dd45f19bf9db46e67282bd24e764904c9624458fc4f71ec6566cc916e43ef36"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"anyrender",
|
||||||
|
"anyrender_svg",
|
||||||
"blitz-dom",
|
"blitz-dom",
|
||||||
"blitz-traits",
|
"blitz-traits",
|
||||||
"color 0.2.4",
|
"color",
|
||||||
"euclid",
|
"euclid",
|
||||||
"futures-intrusive",
|
"kurbo",
|
||||||
"image",
|
|
||||||
"parley",
|
"parley",
|
||||||
"pollster",
|
"peniko",
|
||||||
"raw-window-handle 0.6.2",
|
|
||||||
"stylo",
|
"stylo",
|
||||||
"taffy",
|
"taffy",
|
||||||
"vello",
|
"tracing",
|
||||||
"vello_svg",
|
"usvg",
|
||||||
"wgpu 23.0.1",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "blitz-shell"
|
name = "blitz-shell"
|
||||||
version = "0.1.0-alpha.1"
|
version = "0.1.0-alpha.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ef0a6122f3619a746dddd21883edaae5f791d6e9f401dbdf7f7756caa4f69453"
|
checksum = "ac5e9acd11cd37fee6819686eb4893ae175e2c2563865fb823a9811418a90541"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"accesskit",
|
"accesskit",
|
||||||
"accesskit_winit",
|
"accesskit_winit",
|
||||||
"android-activity",
|
"android-activity",
|
||||||
|
"anyrender",
|
||||||
"blitz-dom",
|
"blitz-dom",
|
||||||
|
"blitz-paint",
|
||||||
"blitz-traits",
|
"blitz-traits",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"keyboard-types",
|
"keyboard-types",
|
||||||
@@ -1650,15 +1693,15 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "blitz-traits"
|
name = "blitz-traits"
|
||||||
version = "0.1.0-alpha.1"
|
version = "0.1.0-alpha.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9972442314e8bf9dd65af7aee0634a2d575972587d404520c7c6986abbd523d3"
|
checksum = "1d0ce7b7e5e2f49321dc4cec28ea7e83b7af0a287eb705674e36a9ac8f9691b9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.9.1",
|
"bitflags 2.9.1",
|
||||||
"bytes",
|
"bytes",
|
||||||
|
"cursor-icon",
|
||||||
"http 1.3.1",
|
"http 1.3.1",
|
||||||
"keyboard-types",
|
"keyboard-types",
|
||||||
"raw-window-handle 0.6.2",
|
|
||||||
"smol_str",
|
"smol_str",
|
||||||
"url",
|
"url",
|
||||||
]
|
]
|
||||||
@@ -2457,12 +2500,6 @@ dependencies = [
|
|||||||
"unicode-width 0.2.0",
|
"unicode-width 0.2.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "color"
|
|
||||||
version = "0.2.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "fa7f99105610438d4b3ee7ae8e453c2990e325c806a14d71e8ea937d584c5289"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "color"
|
name = "color"
|
||||||
version = "0.3.1"
|
version = "0.3.1"
|
||||||
@@ -4300,9 +4337,11 @@ dependencies = [
|
|||||||
name = "dioxus-native"
|
name = "dioxus-native"
|
||||||
version = "0.7.0-alpha.0"
|
version = "0.7.0-alpha.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"anyrender",
|
||||||
|
"anyrender_vello",
|
||||||
"blitz-dom",
|
"blitz-dom",
|
||||||
"blitz-net",
|
"blitz-net",
|
||||||
"blitz-renderer-vello",
|
"blitz-paint",
|
||||||
"blitz-shell",
|
"blitz-shell",
|
||||||
"blitz-traits",
|
"blitz-traits",
|
||||||
"dioxus-asset-resolver",
|
"dioxus-asset-resolver",
|
||||||
@@ -5343,15 +5382,6 @@ version = "0.1.5"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
|
checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "font-types"
|
|
||||||
version = "0.8.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "1fa6a5e5a77b5f3f7f9e32879f484aa5b3632ddfbe568a16266c904a6f32cdaf"
|
|
||||||
dependencies = [
|
|
||||||
"bytemuck",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "font-types"
|
name = "font-types"
|
||||||
version = "0.9.0"
|
version = "0.9.0"
|
||||||
@@ -5396,20 +5426,21 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fontique"
|
name = "fontique"
|
||||||
version = "0.3.0"
|
version = "0.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6b5fcb214137f01bc842c4fd633236255c51f8a24c6d3923eb8361c6d0940737"
|
checksum = "64763d1f274c8383333851435b6cdf071c31cfcdb39fd5860d20943205a007a7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytemuck",
|
"bytemuck",
|
||||||
"fontconfig-cache-parser",
|
"fontconfig-cache-parser",
|
||||||
"hashbrown 0.15.3",
|
"hashbrown 0.15.3",
|
||||||
"icu_locid",
|
"icu_locid",
|
||||||
"memmap2",
|
"memmap2",
|
||||||
|
"objc2 0.6.1",
|
||||||
"objc2-core-foundation",
|
"objc2-core-foundation",
|
||||||
"objc2-core-text",
|
"objc2-core-text",
|
||||||
"objc2-foundation 0.3.1",
|
"objc2-foundation 0.3.1",
|
||||||
"peniko 0.3.2",
|
"peniko",
|
||||||
"read-fonts 0.25.3",
|
"read-fonts",
|
||||||
"roxmltree",
|
"roxmltree",
|
||||||
"smallvec",
|
"smallvec",
|
||||||
"windows 0.58.0",
|
"windows 0.58.0",
|
||||||
@@ -6469,9 +6500,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "glow"
|
name = "glow"
|
||||||
version = "0.14.2"
|
version = "0.16.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d51fa363f025f5c111e03f13eda21162faeacb6911fe8caa0c0349f9cf0c4483"
|
checksum = "c5e5ea60d70410161c8bf5da3fdfeaa1c72ed2c15f8bbb9d19fe3a4fad085f08"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"js-sys",
|
"js-sys",
|
||||||
"slotmap",
|
"slotmap",
|
||||||
@@ -8676,16 +8707,13 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "markup5ever"
|
name = "markup5ever"
|
||||||
version = "0.15.0"
|
version = "0.16.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "03a7b81dfb91586d0677086d40a6d755070e0799b71bb897485bac408dfd5c69"
|
checksum = "d0a8096766c229e8c88a3900c9b44b7e06aa7f7343cc229158c3e58ef8f9973a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"log",
|
"log",
|
||||||
"phf 0.11.3",
|
|
||||||
"phf_codegen 0.11.3",
|
|
||||||
"string_cache",
|
|
||||||
"string_cache_codegen",
|
|
||||||
"tendril",
|
"tendril",
|
||||||
|
"web_atoms",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -8824,9 +8852,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "metal"
|
name = "metal"
|
||||||
version = "0.29.0"
|
version = "0.31.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7ecfd3296f8c56b7c1f6fbac3c71cefa9d78ce009850c45000015f206dc7fa21"
|
checksum = "f569fb946490b5743ad69813cb19629130ce9374034abe31614a36402d18f99e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.9.1",
|
"bitflags 2.9.1",
|
||||||
"block",
|
"block",
|
||||||
@@ -9014,22 +9042,23 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "naga"
|
name = "naga"
|
||||||
version = "23.1.0"
|
version = "24.0.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "364f94bc34f61332abebe8cad6f6cd82a5b65cff22c828d05d0968911462ca4f"
|
checksum = "e380993072e52eef724eddfcde0ed013b0c023c3f0417336ed041aa9f076994e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"arrayvec",
|
"arrayvec",
|
||||||
"bit-set 0.8.0",
|
"bit-set 0.8.0",
|
||||||
"bitflags 2.9.1",
|
"bitflags 2.9.1",
|
||||||
"cfg_aliases 0.1.1",
|
"cfg_aliases 0.2.1",
|
||||||
"codespan-reporting 0.11.1",
|
"codespan-reporting 0.11.1",
|
||||||
"hexf-parse",
|
"hexf-parse",
|
||||||
"indexmap 2.9.0",
|
"indexmap 2.9.0",
|
||||||
"log",
|
"log",
|
||||||
"rustc-hash 1.1.0",
|
"rustc-hash 1.1.0",
|
||||||
"spirv",
|
"spirv",
|
||||||
|
"strum 0.26.3",
|
||||||
"termcolor",
|
"termcolor",
|
||||||
"thiserror 1.0.69",
|
"thiserror 2.0.12",
|
||||||
"unicode-xid",
|
"unicode-xid",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -9900,6 +9929,15 @@ dependencies = [
|
|||||||
"num-traits",
|
"num-traits",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ordered-float"
|
||||||
|
version = "4.6.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7bb71e1b3fa6ca1c61f383464aaf2bb0e2f8e772a1f01d486832464de363b951"
|
||||||
|
dependencies = [
|
||||||
|
"num-traits",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ordered-stream"
|
name = "ordered-stream"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
@@ -10123,14 +10161,14 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "parley"
|
name = "parley"
|
||||||
version = "0.3.0"
|
version = "0.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0d1c2b33b240c246f06cfceac48dc6c96040cb177d2aa5348899982b298b5577"
|
checksum = "e28dadbe655332fd7d996794ec8d0c376695f6ca47bc75aa01e0967c7f28e42a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"fontique",
|
"fontique",
|
||||||
"hashbrown 0.15.3",
|
"hashbrown 0.15.3",
|
||||||
"peniko 0.3.2",
|
"peniko",
|
||||||
"skrifa 0.26.6",
|
"skrifa",
|
||||||
"swash",
|
"swash",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -10234,25 +10272,13 @@ dependencies = [
|
|||||||
"base64ct",
|
"base64ct",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "peniko"
|
|
||||||
version = "0.3.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "5c1f594c54ccdc9bd177a726885f066bf28d20e17169e31a8a1456217b1316b4"
|
|
||||||
dependencies = [
|
|
||||||
"color 0.2.4",
|
|
||||||
"kurbo",
|
|
||||||
"peniko 0.4.0",
|
|
||||||
"smallvec",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "peniko"
|
name = "peniko"
|
||||||
version = "0.4.0"
|
version = "0.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1f9529efd019889b2a205193c14ffb6e2839b54ed9d2720674f10f4b04d87ac9"
|
checksum = "1f9529efd019889b2a205193c14ffb6e2839b54ed9d2720674f10f4b04d87ac9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"color 0.3.1",
|
"color",
|
||||||
"kurbo",
|
"kurbo",
|
||||||
"smallvec",
|
"smallvec",
|
||||||
]
|
]
|
||||||
@@ -11379,16 +11405,6 @@ dependencies = [
|
|||||||
"cipher",
|
"cipher",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "read-fonts"
|
|
||||||
version = "0.25.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "f6f9e8a4f503e5c8750e4cd3b32a4e090035c46374b305a15c70bad833dca05f"
|
|
||||||
dependencies = [
|
|
||||||
"bytemuck",
|
|
||||||
"font-types 0.8.4",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "read-fonts"
|
name = "read-fonts"
|
||||||
version = "0.29.1"
|
version = "0.29.1"
|
||||||
@@ -11396,7 +11412,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "4e85935612710191461ec9df47b4b5880dd6359d4fad3b2f2ed696215f6f3146"
|
checksum = "4e85935612710191461ec9df47b4b5880dd6359d4fad3b2f2ed696215f6f3146"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytemuck",
|
"bytemuck",
|
||||||
"font-types 0.9.0",
|
"font-types",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -12238,9 +12254,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "selectors"
|
name = "selectors"
|
||||||
version = "0.27.0"
|
version = "0.28.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5b75e048a93e14929e68e37b82e207db957cbb368375a80ed3ca28ac75080856"
|
checksum = "db3079aef7a4383aff1e60eca2818995d3de8168e85ae4b6ea8fb2804b182c54"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.9.1",
|
"bitflags 2.9.1",
|
||||||
"cssparser 0.35.0",
|
"cssparser 0.35.0",
|
||||||
@@ -12342,7 +12358,7 @@ version = "0.7.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f3a1a3341211875ef120e117ea7fd5228530ae7e7036a779fdc9117be6b3282c"
|
checksum = "f3a1a3341211875ef120e117ea7fd5228530ae7e7036a779fdc9117be6b3282c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ordered-float",
|
"ordered-float 2.10.1",
|
||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -12743,16 +12759,6 @@ version = "1.0.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d"
|
checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "skrifa"
|
|
||||||
version = "0.26.6"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "8cc1aa86c26dbb1b63875a7180aa0819709b33348eb5b1491e4321fae388179d"
|
|
||||||
dependencies = [
|
|
||||||
"bytemuck",
|
|
||||||
"read-fonts 0.25.3",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "skrifa"
|
name = "skrifa"
|
||||||
version = "0.31.1"
|
version = "0.31.1"
|
||||||
@@ -12760,7 +12766,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "b9c3bb8cab5196b98d70c866ce1ea81ab516104d5b396f84ae80f8766b5d5b4e"
|
checksum = "b9c3bb8cab5196b98d70c866ce1ea81ab516104d5b396f84ae80f8766b5d5b4e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytemuck",
|
"bytemuck",
|
||||||
"read-fonts 0.29.1",
|
"read-fonts",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -13393,9 +13399,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "stylo"
|
name = "stylo"
|
||||||
version = "0.2.1"
|
version = "0.3.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "bfacf8821bb157fbd6cebaa682f22bcebddc38e4165cdedba0061dae24b241c2"
|
checksum = "d6034deda3e062865c4011d70a97ba8691bb00777f14c4575bee41451e46594d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"app_units",
|
"app_units",
|
||||||
"arrayvec",
|
"arrayvec",
|
||||||
@@ -13409,12 +13415,11 @@ dependencies = [
|
|||||||
"fxhash",
|
"fxhash",
|
||||||
"icu_segmenter",
|
"icu_segmenter",
|
||||||
"indexmap 2.9.0",
|
"indexmap 2.9.0",
|
||||||
"itertools 0.10.5",
|
"itertools 0.14.0",
|
||||||
"itoa 1.0.15",
|
"itoa 1.0.15",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"log",
|
"log",
|
||||||
"malloc_size_of_derive",
|
"malloc_size_of_derive",
|
||||||
"markup5ever 0.15.0",
|
|
||||||
"matches",
|
"matches",
|
||||||
"mime",
|
"mime",
|
||||||
"new_debug_unreachable",
|
"new_debug_unreachable",
|
||||||
@@ -13426,7 +13431,7 @@ dependencies = [
|
|||||||
"precomputed-hash",
|
"precomputed-hash",
|
||||||
"rayon",
|
"rayon",
|
||||||
"rayon-core",
|
"rayon-core",
|
||||||
"selectors 0.27.0",
|
"selectors 0.28.0",
|
||||||
"serde",
|
"serde",
|
||||||
"servo_arc 0.4.0",
|
"servo_arc 0.4.0",
|
||||||
"smallbitvec",
|
"smallbitvec",
|
||||||
@@ -13448,13 +13453,14 @@ dependencies = [
|
|||||||
"url",
|
"url",
|
||||||
"void",
|
"void",
|
||||||
"walkdir",
|
"walkdir",
|
||||||
|
"web_atoms",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "stylo_atoms"
|
name = "stylo_atoms"
|
||||||
version = "0.2.0"
|
version = "0.3.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b943c983729930ee70141ab6515604bb33ff5de8d7626024072c38a27c8023bb"
|
checksum = "4b7dacdd62700078300263cece93a9c41823305d461ee5b3b65a51d6cdce3d38"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"string_cache",
|
"string_cache",
|
||||||
"string_cache_codegen",
|
"string_cache_codegen",
|
||||||
@@ -13462,15 +13468,15 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "stylo_config"
|
name = "stylo_config"
|
||||||
version = "0.2.0"
|
version = "0.3.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b2e53afe5289d75063564e60aa59c591a2c496d3425f2bb2a3002251785e2058"
|
checksum = "3fe07c673f8989e237e544c17723a8831d37d80b1a55437ac67bec8fe877e3cb"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "stylo_derive"
|
name = "stylo_derive"
|
||||||
version = "0.2.0"
|
version = "0.3.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e745b58d581ba8eb932825e684634eae9be848fd49c086b3f17ccb7d6c417594"
|
checksum = "9a2c2bf677324ef587e97b8f5fc055f97a50bd26493411100e1442824ab289b8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"darling",
|
"darling",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
@@ -13481,9 +13487,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "stylo_dom"
|
name = "stylo_dom"
|
||||||
version = "0.2.0"
|
version = "0.3.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "06606e83c4feb986ea601a2c7d625aa5c303ecfc9526494480f6e599b8d6956e"
|
checksum = "183a89dc60a136308a1c83056660692bb598b3a99db2ac79b1b53f935cf3c87d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.9.1",
|
"bitflags 2.9.1",
|
||||||
"stylo_malloc_size_of",
|
"stylo_malloc_size_of",
|
||||||
@@ -13491,14 +13497,14 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "stylo_malloc_size_of"
|
name = "stylo_malloc_size_of"
|
||||||
version = "0.2.0"
|
version = "0.3.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "93db6fdbcde7f037f7810873374d85a2b3d37686b046577943818167a6e52d3f"
|
checksum = "150243bffdabaeafc7370354f6102559fec103b63d84875383fb657dd9c8549c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"app_units",
|
"app_units",
|
||||||
"cssparser 0.35.0",
|
"cssparser 0.35.0",
|
||||||
"euclid",
|
"euclid",
|
||||||
"selectors 0.27.0",
|
"selectors 0.28.0",
|
||||||
"servo_arc 0.4.0",
|
"servo_arc 0.4.0",
|
||||||
"smallbitvec",
|
"smallbitvec",
|
||||||
"smallvec",
|
"smallvec",
|
||||||
@@ -13509,15 +13515,15 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "stylo_static_prefs"
|
name = "stylo_static_prefs"
|
||||||
version = "0.2.0"
|
version = "0.3.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "decb57071c4b4d5690a9719fb04a07cf2fab0fa3df99a830ef735192a1a98e5d"
|
checksum = "9600d11cdad6c275426272f35fbe085c4362be1d67bb9775f378fd2be7942d3a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "stylo_taffy"
|
name = "stylo_taffy"
|
||||||
version = "0.1.0-alpha.1"
|
version = "0.1.0-alpha.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a6da84b2bae9d25a2156b7cf89acab90683ac4d25dcb3fe1817dc9e77a20ce2f"
|
checksum = "1c0f66aad13b557aafcf971220a04150228604da2b377f0b2aa6a03113adfac7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"stylo",
|
"stylo",
|
||||||
"taffy",
|
"taffy",
|
||||||
@@ -13525,16 +13531,16 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "stylo_traits"
|
name = "stylo_traits"
|
||||||
version = "0.2.0"
|
version = "0.3.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5f611ebeee90c0d255bf4d4fadc05f964ef019f8aaed307108fa859c826f2753"
|
checksum = "2a24b6eb257a1e68e184e113a3a426dd9e38e4a0017b805fcf43a44c939e5642"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"app_units",
|
"app_units",
|
||||||
"bitflags 2.9.1",
|
"bitflags 2.9.1",
|
||||||
"cssparser 0.35.0",
|
"cssparser 0.35.0",
|
||||||
"euclid",
|
"euclid",
|
||||||
"malloc_size_of_derive",
|
"malloc_size_of_derive",
|
||||||
"selectors 0.27.0",
|
"selectors 0.28.0",
|
||||||
"serde",
|
"serde",
|
||||||
"servo_arc 0.4.0",
|
"servo_arc 0.4.0",
|
||||||
"stylo_atoms",
|
"stylo_atoms",
|
||||||
@@ -13634,7 +13640,7 @@ version = "0.2.5"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f745de914febc7c9ab4388dfaf94bbc87e69f57bb41133a9b0c84d4be49856f3"
|
checksum = "f745de914febc7c9ab4388dfaf94bbc87e69f57bb41133a9b0c84d4be49856f3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"skrifa 0.31.1",
|
"skrifa",
|
||||||
"yazi",
|
"yazi",
|
||||||
"zeno",
|
"zeno",
|
||||||
]
|
]
|
||||||
@@ -15635,60 +15641,48 @@ checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "vello"
|
name = "vello"
|
||||||
version = "0.4.1"
|
version = "0.5.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3d5b0bafa35e0c2e4132104576d6bcec4bf7cd0044f1760e92ecae0d4d9bc0e7"
|
checksum = "df026e62e8b0d12d55ff5e91ae9114a20f82d9b856bedfdbf3abd5d1472dceed"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytemuck",
|
"bytemuck",
|
||||||
"futures-intrusive",
|
"futures-intrusive",
|
||||||
"log",
|
"log",
|
||||||
"peniko 0.3.2",
|
"peniko",
|
||||||
"png",
|
"png",
|
||||||
"skrifa 0.26.6",
|
"skrifa",
|
||||||
"static_assertions",
|
"static_assertions",
|
||||||
"thiserror 2.0.12",
|
"thiserror 2.0.12",
|
||||||
"vello_encoding",
|
"vello_encoding",
|
||||||
"vello_shaders",
|
"vello_shaders",
|
||||||
"wgpu 23.0.1",
|
"wgpu 24.0.5",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "vello_encoding"
|
name = "vello_encoding"
|
||||||
version = "0.4.1"
|
version = "0.5.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "cbbdec68dea2b39ece9f82ab15ec4cf2c4f8600ce6926df0638290702d95b3f7"
|
checksum = "3c5702642f6ea77eedc12d119e1eebead0dba3cf91fe5c5d1f3efc12bf0cfaf1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytemuck",
|
"bytemuck",
|
||||||
"guillotiere",
|
"guillotiere",
|
||||||
"peniko 0.3.2",
|
"peniko",
|
||||||
"skrifa 0.26.6",
|
"skrifa",
|
||||||
"smallvec",
|
"smallvec",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "vello_shaders"
|
name = "vello_shaders"
|
||||||
version = "0.4.1"
|
version = "0.5.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6e0179d74cf9131dfd7882323751d2544f3aefdfda9d16c39bbe2729799410d2"
|
checksum = "381790a3779021edd9f88267c1b13b49546cb0fb164f329ee2f2587869ddf459"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytemuck",
|
"bytemuck",
|
||||||
"naga 23.1.0",
|
"naga 24.0.0",
|
||||||
"thiserror 2.0.12",
|
"thiserror 2.0.12",
|
||||||
"vello_encoding",
|
"vello_encoding",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "vello_svg"
|
|
||||||
version = "0.6.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "3a0fd265f55b496a8048a43c769bf15487f2be9f6642086b3468c64677cc8c87"
|
|
||||||
dependencies = [
|
|
||||||
"image",
|
|
||||||
"thiserror 2.0.12",
|
|
||||||
"usvg",
|
|
||||||
"vello",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "version-compare"
|
name = "version-compare"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
@@ -16245,6 +16239,18 @@ dependencies = [
|
|||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "web_atoms"
|
||||||
|
version = "0.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0b9c5f0bc545ea3b20b423e33b9b457764de0b3730cd957f6c6aa6c301785f6e"
|
||||||
|
dependencies = [
|
||||||
|
"phf 0.11.3",
|
||||||
|
"phf_codegen 0.11.3",
|
||||||
|
"string_cache",
|
||||||
|
"string_cache_codegen",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "webbrowser"
|
name = "webbrowser"
|
||||||
version = "1.0.4"
|
version = "1.0.4"
|
||||||
@@ -16399,16 +16405,17 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wgpu"
|
name = "wgpu"
|
||||||
version = "23.0.1"
|
version = "24.0.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "80f70000db37c469ea9d67defdc13024ddf9a5f1b89cb2941b812ad7cde1735a"
|
checksum = "6b0b3436f0729f6cdf2e6e9201f3d39dc95813fad61d826c1ed07918b4539353"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"arrayvec",
|
"arrayvec",
|
||||||
"cfg_aliases 0.1.1",
|
"bitflags 2.9.1",
|
||||||
|
"cfg_aliases 0.2.1",
|
||||||
"document-features",
|
"document-features",
|
||||||
"js-sys",
|
"js-sys",
|
||||||
"log",
|
"log",
|
||||||
"naga 23.1.0",
|
"naga 24.0.0",
|
||||||
"parking_lot",
|
"parking_lot",
|
||||||
"profiling",
|
"profiling",
|
||||||
"raw-window-handle 0.6.2",
|
"raw-window-handle 0.6.2",
|
||||||
@@ -16417,9 +16424,9 @@ dependencies = [
|
|||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
"wasm-bindgen-futures",
|
"wasm-bindgen-futures",
|
||||||
"web-sys",
|
"web-sys",
|
||||||
"wgpu-core 23.0.1",
|
"wgpu-core 24.0.5",
|
||||||
"wgpu-hal 23.0.1",
|
"wgpu-hal 24.0.4",
|
||||||
"wgpu-types 23.0.0",
|
"wgpu-types 24.0.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -16450,27 +16457,27 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wgpu-core"
|
name = "wgpu-core"
|
||||||
version = "23.0.1"
|
version = "24.0.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d63c3c478de8e7e01786479919c8769f62a22eec16788d8c2ac77ce2c132778a"
|
checksum = "7f0aa306497a238d169b9dc70659105b4a096859a34894544ca81719242e1499"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"arrayvec",
|
"arrayvec",
|
||||||
"bit-vec 0.8.0",
|
"bit-vec 0.8.0",
|
||||||
"bitflags 2.9.1",
|
"bitflags 2.9.1",
|
||||||
"cfg_aliases 0.1.1",
|
"cfg_aliases 0.2.1",
|
||||||
"document-features",
|
"document-features",
|
||||||
"indexmap 2.9.0",
|
"indexmap 2.9.0",
|
||||||
"log",
|
"log",
|
||||||
"naga 23.1.0",
|
"naga 24.0.0",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"parking_lot",
|
"parking_lot",
|
||||||
"profiling",
|
"profiling",
|
||||||
"raw-window-handle 0.6.2",
|
"raw-window-handle 0.6.2",
|
||||||
"rustc-hash 1.1.0",
|
"rustc-hash 1.1.0",
|
||||||
"smallvec",
|
"smallvec",
|
||||||
"thiserror 1.0.69",
|
"thiserror 2.0.12",
|
||||||
"wgpu-hal 23.0.1",
|
"wgpu-hal 24.0.4",
|
||||||
"wgpu-types 23.0.0",
|
"wgpu-types 24.0.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -16520,9 +16527,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wgpu-hal"
|
name = "wgpu-hal"
|
||||||
version = "23.0.1"
|
version = "24.0.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "89364b8a0b211adc7b16aeaf1bd5ad4a919c1154b44c9ce27838213ba05fd821"
|
checksum = "f112f464674ca69f3533248508ee30cb84c67cf06c25ff6800685f5e0294e259"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"android_system_properties",
|
"android_system_properties",
|
||||||
"arrayvec",
|
"arrayvec",
|
||||||
@@ -16531,9 +16538,9 @@ dependencies = [
|
|||||||
"bitflags 2.9.1",
|
"bitflags 2.9.1",
|
||||||
"block",
|
"block",
|
||||||
"bytemuck",
|
"bytemuck",
|
||||||
"cfg_aliases 0.1.1",
|
"cfg_aliases 0.2.1",
|
||||||
"core-graphics-types 0.1.3",
|
"core-graphics-types 0.1.3",
|
||||||
"glow 0.14.2",
|
"glow 0.16.0",
|
||||||
"glutin_wgl_sys 0.6.1",
|
"glutin_wgl_sys 0.6.1",
|
||||||
"gpu-alloc",
|
"gpu-alloc",
|
||||||
"gpu-allocator 0.27.0",
|
"gpu-allocator 0.27.0",
|
||||||
@@ -16543,11 +16550,12 @@ dependencies = [
|
|||||||
"libc",
|
"libc",
|
||||||
"libloading 0.8.7",
|
"libloading 0.8.7",
|
||||||
"log",
|
"log",
|
||||||
"metal 0.29.0",
|
"metal 0.31.0",
|
||||||
"naga 23.1.0",
|
"naga 24.0.0",
|
||||||
"ndk-sys 0.5.0+25.2.9519653",
|
"ndk-sys 0.5.0+25.2.9519653",
|
||||||
"objc",
|
"objc",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
|
"ordered-float 4.6.0",
|
||||||
"parking_lot",
|
"parking_lot",
|
||||||
"profiling",
|
"profiling",
|
||||||
"range-alloc",
|
"range-alloc",
|
||||||
@@ -16555,10 +16563,10 @@ dependencies = [
|
|||||||
"renderdoc-sys",
|
"renderdoc-sys",
|
||||||
"rustc-hash 1.1.0",
|
"rustc-hash 1.1.0",
|
||||||
"smallvec",
|
"smallvec",
|
||||||
"thiserror 1.0.69",
|
"thiserror 2.0.12",
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
"web-sys",
|
"web-sys",
|
||||||
"wgpu-types 23.0.0",
|
"wgpu-types 24.0.0",
|
||||||
"windows 0.58.0",
|
"windows 0.58.0",
|
||||||
"windows-core 0.58.0",
|
"windows-core 0.58.0",
|
||||||
]
|
]
|
||||||
@@ -16576,12 +16584,13 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wgpu-types"
|
name = "wgpu-types"
|
||||||
version = "23.0.0"
|
version = "24.0.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "610f6ff27778148c31093f3b03abc4840f9636d58d597ca2f5977433acfe0068"
|
checksum = "50ac044c0e76c03a0378e7786ac505d010a873665e2d51383dcff8dd227dc69c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.9.1",
|
"bitflags 2.9.1",
|
||||||
"js-sys",
|
"js-sys",
|
||||||
|
"log",
|
||||||
"web-sys",
|
"web-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ seeked = "seeked"
|
|||||||
# https://developer.apple.com/forums/thread/108953
|
# https://developer.apple.com/forums/thread/108953
|
||||||
# udid = unique device identifier
|
# udid = unique device identifier
|
||||||
udid = "udid"
|
udid = "udid"
|
||||||
|
# Part of Blitz's API
|
||||||
|
unparented = "unparented"
|
||||||
|
|
||||||
[files]
|
[files]
|
||||||
extend-exclude = ["translations/*", "CHANGELOG.md", "*.js"]
|
extend-exclude = ["translations/*", "CHANGELOG.md", "*.js"]
|
||||||
+10
-12
@@ -11,27 +11,25 @@ keywords = ["dom", "ui", "gui", "react"]
|
|||||||
|
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["accessibility", "hot-reload", "menu", "tracing", "net", "svg"]
|
default = ["accessibility", "hot-reload", "menu", "tracing", "net", "svg", "system-fonts"]
|
||||||
svg = ["blitz-dom/svg", "blitz-renderer-vello/svg"]
|
svg = ["blitz-dom/svg", "blitz-paint/svg"]
|
||||||
net = ["dep:tokio", "dep:blitz-net"]
|
net = ["dep:tokio", "dep:blitz-net"]
|
||||||
accessibility = ["blitz-shell/accessibility", "blitz-dom/accessibility"]
|
accessibility = ["blitz-shell/accessibility", "blitz-dom/accessibility"]
|
||||||
menu = ["blitz-shell/menu"]
|
menu = ["blitz-shell/menu"]
|
||||||
tracing = ["dep:tracing", "blitz-shell/tracing", "blitz-dom/tracing"]
|
tracing = ["dep:tracing", "blitz-shell/tracing", "blitz-dom/tracing"]
|
||||||
hot-reload = ["dep:dioxus-cli-config", "dep:dioxus-devtools"]
|
hot-reload = ["dep:dioxus-cli-config", "dep:dioxus-devtools"]
|
||||||
|
system-fonts = ["blitz-dom/system_fonts"]
|
||||||
autofocus = []
|
autofocus = []
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
# Blitz dependencies
|
# Blitz dependencies
|
||||||
blitz-renderer-vello = { version = "0.1.0-alpha.1", default-features = false }
|
anyrender = { version = "0.1", default-features = false }
|
||||||
blitz-dom = { version = "0.1.0-alpha.1", default-features = false }
|
anyrender_vello = { version = "0.1", default-features = false }
|
||||||
blitz-net = { version = "0.1.0-alpha.1", optional = true }
|
blitz-dom = { version = "0.1.0-alpha.2", default-features = false }
|
||||||
blitz-traits = { version = "0.1.0-alpha.1" }
|
blitz-net = { version = "0.1.0-alpha.2", optional = true }
|
||||||
blitz-shell = { version = "0.1.0-alpha.1", default-features = false }
|
blitz-paint = { version = "0.1.0-alpha.2", optional = true }
|
||||||
# blitz-renderer-vello = { git = "https://github.com/dioxuslabs/blitz", rev="c1a7ecf06d1760a268e0046dc0e43f6c796ddc3c", default-features = false }
|
blitz-traits = { version = "0.1.0-alpha.2" }
|
||||||
# blitz-dom = { git = "https://github.com/dioxuslabs/blitz", rev="c1a7ecf06d1760a268e0046dc0e43f6c796ddc3c", default-features = false }
|
blitz-shell = { version = "0.1.0-alpha.2", default-features = false }
|
||||||
# blitz-net = { git = "https://github.com/dioxuslabs/blitz", rev="c1a7ecf06d1760a268e0046dc0e43f6c796ddc3c", optional = true }
|
|
||||||
# blitz-traits = { git = "https://github.com/dioxuslabs/blitz", rev="c1a7ecf06d1760a268e0046dc0e43f6c796ddc3c" }
|
|
||||||
# blitz-shell = { git = "https://github.com/dioxuslabs/blitz", rev="c1a7ecf06d1760a268e0046dc0e43f6c796ddc3c", default-features = false }
|
|
||||||
|
|
||||||
# DioxusLabs dependencies
|
# DioxusLabs dependencies
|
||||||
dioxus-core = { workspace = true }
|
dioxus-core = { workspace = true }
|
||||||
|
|||||||
@@ -1,24 +1,18 @@
|
|||||||
use blitz_shell::BlitzShellNetCallback;
|
use blitz_shell::BlitzShellNetCallback;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use blitz_dom::{
|
use blitz_dom::net::Resource;
|
||||||
net::{CssHandler, ImageHandler, Resource},
|
|
||||||
util::ImageType,
|
|
||||||
BaseDocument,
|
|
||||||
};
|
|
||||||
use blitz_shell::BlitzShellEvent;
|
use blitz_shell::BlitzShellEvent;
|
||||||
use blitz_traits::net::{NetCallback, NetProvider};
|
use blitz_traits::net::{NetCallback, NetProvider};
|
||||||
use winit::event_loop::EventLoopProxy;
|
use winit::event_loop::EventLoopProxy;
|
||||||
|
|
||||||
use crate::NodeId;
|
|
||||||
|
|
||||||
pub struct DioxusNativeNetProvider {
|
pub struct DioxusNativeNetProvider {
|
||||||
callback: Arc<dyn NetCallback<Data = Resource> + 'static>,
|
callback: Arc<dyn NetCallback<Resource> + 'static>,
|
||||||
inner_net_provider: Arc<dyn NetProvider<Data = Resource> + 'static>,
|
inner_net_provider: Arc<dyn NetProvider<Resource> + 'static>,
|
||||||
}
|
}
|
||||||
impl DioxusNativeNetProvider {
|
impl DioxusNativeNetProvider {
|
||||||
pub fn shared(proxy: EventLoopProxy<BlitzShellEvent>) -> Arc<dyn NetProvider<Data = Resource>> {
|
pub fn shared(proxy: EventLoopProxy<BlitzShellEvent>) -> Arc<dyn NetProvider<Resource>> {
|
||||||
Arc::new(Self::new(proxy)) as Arc<dyn NetProvider<Data = Resource>>
|
Arc::new(Self::new(proxy)) as Arc<dyn NetProvider<Resource>>
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new(proxy: EventLoopProxy<BlitzShellEvent>) -> Self {
|
pub fn new(proxy: EventLoopProxy<BlitzShellEvent>) -> Self {
|
||||||
@@ -31,14 +25,12 @@ impl DioxusNativeNetProvider {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl NetProvider for DioxusNativeNetProvider {
|
impl NetProvider<Resource> for DioxusNativeNetProvider {
|
||||||
type Data = Resource;
|
|
||||||
|
|
||||||
fn fetch(
|
fn fetch(
|
||||||
&self,
|
&self,
|
||||||
doc_id: usize,
|
doc_id: usize,
|
||||||
request: blitz_traits::net::Request,
|
request: blitz_traits::net::Request,
|
||||||
handler: blitz_traits::net::BoxedHandler<Self::Data>,
|
handler: blitz_traits::net::BoxedHandler<Resource>,
|
||||||
) {
|
) {
|
||||||
if request.url.scheme() == "dioxus" {
|
if request.url.scheme() == "dioxus" {
|
||||||
match dioxus_asset_resolver::serve_asset_from_raw_path(request.url.path()) {
|
match dioxus_asset_resolver::serve_asset_from_raw_path(request.url.path()) {
|
||||||
@@ -55,26 +47,3 @@ impl NetProvider for DioxusNativeNetProvider {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fetch_linked_stylesheet(doc: &BaseDocument, node_id: NodeId, queued_url: String) {
|
|
||||||
let url = doc.resolve_url(&queued_url);
|
|
||||||
doc.net_provider.fetch(
|
|
||||||
doc.id(),
|
|
||||||
blitz_traits::net::Request::get(url.clone()),
|
|
||||||
Box::new(CssHandler {
|
|
||||||
node: node_id,
|
|
||||||
source_url: url,
|
|
||||||
guard: doc.guard.clone(),
|
|
||||||
provider: doc.net_provider.clone(),
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn fetch_image(doc: &BaseDocument, node_id: usize, queued_image: String) {
|
|
||||||
let src = doc.resolve_url(&queued_image);
|
|
||||||
doc.net_provider.fetch(
|
|
||||||
doc.id(),
|
|
||||||
blitz_traits::net::Request::get(src),
|
|
||||||
Box::new(ImageHandler::new(node_id, ImageType::Image)),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
use blitz_renderer_vello::BlitzVelloRenderer;
|
use anyrender_vello::VelloWindowRenderer;
|
||||||
use blitz_shell::BlitzApplication;
|
use blitz_shell::BlitzApplication;
|
||||||
use dioxus_core::{ScopeId, VirtualDom};
|
use dioxus_core::{ScopeId, VirtualDom};
|
||||||
use dioxus_history::{History, MemoryHistory};
|
use dioxus_history::{History, MemoryHistory};
|
||||||
@@ -10,13 +10,34 @@ use winit::window::WindowId;
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
assets::DioxusNativeNetProvider, contexts::DioxusNativeDocument,
|
assets::DioxusNativeNetProvider, contexts::DioxusNativeDocument,
|
||||||
mutation_writer::MutationWriter, BlitzShellEvent, DioxusDocument, DioxusNativeEvent,
|
mutation_writer::MutationWriter, BlitzShellEvent, DioxusDocument, WindowConfig,
|
||||||
WindowConfig,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// Dioxus-native specific event type
|
||||||
|
pub enum DioxusNativeEvent {
|
||||||
|
/// A hotreload event, basically telling us to update our templates.
|
||||||
|
#[cfg(all(
|
||||||
|
feature = "hot-reload",
|
||||||
|
debug_assertions,
|
||||||
|
not(target_os = "android"),
|
||||||
|
not(target_os = "ios")
|
||||||
|
))]
|
||||||
|
DevserverEvent(dioxus_devtools::DevserverMsg),
|
||||||
|
|
||||||
|
/// Create a new head element from the Link and Title elements
|
||||||
|
///
|
||||||
|
/// todo(jon): these should probabkly be synchronous somehow
|
||||||
|
CreateHeadElement {
|
||||||
|
window: WindowId,
|
||||||
|
name: String,
|
||||||
|
attributes: Vec<(String, String)>,
|
||||||
|
contents: Option<String>,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
pub struct DioxusNativeApplication {
|
pub struct DioxusNativeApplication {
|
||||||
pending_vdom: Option<VirtualDom>,
|
pending_vdom: Option<VirtualDom>,
|
||||||
inner: BlitzApplication<DioxusDocument, BlitzVelloRenderer>,
|
inner: BlitzApplication<VelloWindowRenderer>,
|
||||||
proxy: EventLoopProxy<BlitzShellEvent>,
|
proxy: EventLoopProxy<BlitzShellEvent>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -29,7 +50,7 @@ impl DioxusNativeApplication {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_window(&mut self, window_config: WindowConfig<DioxusDocument, BlitzVelloRenderer>) {
|
pub fn add_window(&mut self, window_config: WindowConfig<VelloWindowRenderer>) {
|
||||||
self.inner.add_window(window_config);
|
self.inner.add_window(window_config);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -48,7 +69,8 @@ impl DioxusNativeApplication {
|
|||||||
DioxusNativeEvent::DevserverEvent(event) => match event {
|
DioxusNativeEvent::DevserverEvent(event) => match event {
|
||||||
dioxus_devtools::DevserverMsg::HotReload(hotreload_message) => {
|
dioxus_devtools::DevserverMsg::HotReload(hotreload_message) => {
|
||||||
for window in self.inner.windows.values_mut() {
|
for window in self.inner.windows.values_mut() {
|
||||||
dioxus_devtools::apply_changes(&window.doc.vdom, hotreload_message);
|
let doc = window.downcast_doc_mut::<DioxusDocument>();
|
||||||
|
dioxus_devtools::apply_changes(&doc.vdom, hotreload_message);
|
||||||
window.poll();
|
window.poll();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -66,7 +88,8 @@ impl DioxusNativeApplication {
|
|||||||
window,
|
window,
|
||||||
} => {
|
} => {
|
||||||
if let Some(window) = self.inner.windows.get_mut(window) {
|
if let Some(window) = self.inner.windows.get_mut(window) {
|
||||||
window.doc.create_head_element(name, attributes, contents);
|
let doc = window.downcast_doc_mut::<DioxusDocument>();
|
||||||
|
doc.create_head_element(name, attributes, contents);
|
||||||
window.poll();
|
window.poll();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -103,7 +126,7 @@ impl ApplicationHandler<BlitzShellEvent> for DioxusNativeApplication {
|
|||||||
|
|
||||||
// Create document + window from the baked virtualdom
|
// Create document + window from the baked virtualdom
|
||||||
let doc = DioxusDocument::new(vdom, net_provider);
|
let doc = DioxusDocument::new(vdom, net_provider);
|
||||||
let window = WindowConfig::new(doc);
|
let window = WindowConfig::new(Box::new(doc) as _);
|
||||||
|
|
||||||
// little hack since View::init is not public - fix this once alpha-2 is out
|
// little hack since View::init is not public - fix this once alpha-2 is out
|
||||||
let old_windows = self.inner.windows.keys().copied().collect::<HashSet<_>>();
|
let old_windows = self.inner.windows.keys().copied().collect::<HashSet<_>>();
|
||||||
@@ -114,7 +137,8 @@ impl ApplicationHandler<BlitzShellEvent> for DioxusNativeApplication {
|
|||||||
// todo(jon): we should actually mess with the pending windows instead of passing along the contexts
|
// todo(jon): we should actually mess with the pending windows instead of passing along the contexts
|
||||||
for window_id in new_windows.difference(&old_windows) {
|
for window_id in new_windows.difference(&old_windows) {
|
||||||
let window = self.inner.windows.get_mut(window_id).unwrap();
|
let window = self.inner.windows.get_mut(window_id).unwrap();
|
||||||
window.doc.vdom.in_runtime(|| {
|
let doc = window.downcast_doc_mut::<DioxusDocument>();
|
||||||
|
doc.vdom.in_runtime(|| {
|
||||||
let shared: Rc<dyn dioxus_document::Document> =
|
let shared: Rc<dyn dioxus_document::Document> =
|
||||||
Rc::new(DioxusNativeDocument::new(self.proxy.clone(), *window_id));
|
Rc::new(DioxusNativeDocument::new(self.proxy.clone(), *window_id));
|
||||||
ScopeId::ROOT.provide_context(shared);
|
ScopeId::ROOT.provide_context(shared);
|
||||||
@@ -122,14 +146,12 @@ impl ApplicationHandler<BlitzShellEvent> for DioxusNativeApplication {
|
|||||||
|
|
||||||
// Add history
|
// Add history
|
||||||
let history_provider: Rc<dyn History> = Rc::new(MemoryHistory::default());
|
let history_provider: Rc<dyn History> = Rc::new(MemoryHistory::default());
|
||||||
window
|
doc.vdom
|
||||||
.doc
|
|
||||||
.vdom
|
|
||||||
.in_runtime(|| ScopeId::ROOT.provide_context(history_provider));
|
.in_runtime(|| ScopeId::ROOT.provide_context(history_provider));
|
||||||
|
|
||||||
// Queue rebuild
|
// Queue rebuild
|
||||||
let mut writer = MutationWriter::new(&mut window.doc.inner, &mut window.doc.vdom_state);
|
let mut writer = MutationWriter::new(&mut doc.inner, &mut doc.vdom_state);
|
||||||
window.doc.vdom.rebuild(&mut writer);
|
doc.vdom.rebuild(&mut writer);
|
||||||
drop(writer);
|
drop(writer);
|
||||||
|
|
||||||
// And then request redraw
|
// And then request redraw
|
||||||
|
|||||||
@@ -1,29 +1,36 @@
|
|||||||
//! Integration between Dioxus and Blitz
|
//! Integration between Dioxus and Blitz
|
||||||
|
use blitz_dom::Attribute;
|
||||||
|
use futures_util::{pin_mut, FutureExt};
|
||||||
|
use std::ops::{Deref, DerefMut};
|
||||||
use std::{any::Any, collections::HashMap, rc::Rc, sync::Arc};
|
use std::{any::Any, collections::HashMap, rc::Rc, sync::Arc};
|
||||||
|
|
||||||
use blitz_dom::{
|
use blitz_dom::{
|
||||||
local_name, namespace_url,
|
net::Resource, BaseDocument, Document, EventDriver, EventHandler, Node, DEFAULT_CSS,
|
||||||
net::Resource,
|
};
|
||||||
node::{Attribute, NodeSpecificData},
|
use blitz_traits::{
|
||||||
ns, Atom, BaseDocument, ElementNodeData, Node, NodeData, QualName, DEFAULT_CSS,
|
events::UiEvent, net::NetProvider, ColorScheme, DomEvent, DomEventData, EventState, Viewport,
|
||||||
};
|
};
|
||||||
|
|
||||||
use blitz_traits::{net::NetProvider, ColorScheme, Document, DomEvent, DomEventData, Viewport};
|
|
||||||
use dioxus_core::{ElementId, Event, VirtualDom};
|
use dioxus_core::{ElementId, Event, VirtualDom};
|
||||||
use dioxus_html::{set_event_converter, FormValue, PlatformEventData};
|
use dioxus_html::{set_event_converter, PlatformEventData};
|
||||||
use futures_util::{pin_mut, FutureExt};
|
|
||||||
|
|
||||||
use super::event_handler::{BlitzKeyboardData, NativeClickData, NativeConverter, NativeFormData};
|
use crate::events::{BlitzKeyboardData, NativeClickData, NativeConverter, NativeFormData};
|
||||||
use crate::mutation_writer::{DioxusState, MutationWriter};
|
use crate::mutation_writer::{DioxusState, MutationWriter};
|
||||||
|
use crate::qual_name;
|
||||||
use crate::NodeId;
|
use crate::NodeId;
|
||||||
|
|
||||||
pub(crate) fn qual_name(local_name: &str, namespace: Option<&str>) -> QualName {
|
fn wrap_event_data<T: Any>(value: T) -> Rc<dyn Any> {
|
||||||
QualName {
|
Rc::new(PlatformEventData::new(Box::new(value)))
|
||||||
prefix: None,
|
}
|
||||||
ns: namespace.map(Atom::from).unwrap_or(ns!(html)),
|
|
||||||
local: Atom::from(local_name),
|
/// Get the value of the "dioxus-data-id" attribute parsed aa usize
|
||||||
}
|
fn get_dioxus_id(node: &Node) -> Option<ElementId> {
|
||||||
|
node.element_data()?
|
||||||
|
.attrs
|
||||||
|
.iter()
|
||||||
|
.find(|attr| *attr.name.local == *"data-dioxus-id")
|
||||||
|
.and_then(|attr| attr.value.parse::<usize>().ok())
|
||||||
|
.map(ElementId)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct DioxusDocument {
|
pub struct DioxusDocument {
|
||||||
@@ -41,25 +48,106 @@ pub struct DioxusDocument {
|
|||||||
pub(crate) main_element_id: NodeId,
|
pub(crate) main_element_id: NodeId,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Implement DocumentLike and required traits for DioxusDocument
|
impl DioxusDocument {
|
||||||
|
pub fn new(vdom: VirtualDom, net_provider: Option<Arc<dyn NetProvider<Resource>>>) -> Self {
|
||||||
|
let viewport = Viewport::new(0, 0, 1.0, ColorScheme::Light);
|
||||||
|
let mut doc = BaseDocument::new(viewport);
|
||||||
|
|
||||||
impl AsRef<BaseDocument> for DioxusDocument {
|
// Set net provider
|
||||||
fn as_ref(&self) -> &BaseDocument {
|
if let Some(net_provider) = net_provider {
|
||||||
&self.inner
|
doc.set_net_provider(net_provider);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create some minimal HTML to render the app into.
|
||||||
|
|
||||||
|
// Create the html element
|
||||||
|
let mut mutr = doc.mutate();
|
||||||
|
let html_element_id = mutr.create_element(qual_name("html", None), vec![]);
|
||||||
|
mutr.append_children(mutr.doc.root_node().id, &[html_element_id]);
|
||||||
|
|
||||||
|
// Create the body element
|
||||||
|
let head_element_id = mutr.create_element(qual_name("head", None), vec![]);
|
||||||
|
mutr.append_children(html_element_id, &[head_element_id]);
|
||||||
|
|
||||||
|
// Create the body element
|
||||||
|
let body_element_id = mutr.create_element(qual_name("body", None), vec![]);
|
||||||
|
mutr.append_children(html_element_id, &[body_element_id]);
|
||||||
|
|
||||||
|
// Create another virtual element to hold the root <div id="main"></div> under the html element
|
||||||
|
let main_attr = blitz_dom::Attribute {
|
||||||
|
name: qual_name("id", None),
|
||||||
|
value: "main".to_string(),
|
||||||
|
};
|
||||||
|
let main_element_id = mutr.create_element(qual_name("main", None), vec![main_attr]);
|
||||||
|
mutr.append_children(body_element_id, &[main_element_id]);
|
||||||
|
|
||||||
|
drop(mutr);
|
||||||
|
|
||||||
|
// Include default and user-specified stylesheets
|
||||||
|
doc.add_user_agent_stylesheet(DEFAULT_CSS);
|
||||||
|
|
||||||
|
let vdom_state = DioxusState::create(main_element_id);
|
||||||
|
let mut doc = Self {
|
||||||
|
vdom,
|
||||||
|
vdom_state,
|
||||||
|
inner: doc,
|
||||||
|
html_element_id,
|
||||||
|
head_element_id,
|
||||||
|
body_element_id,
|
||||||
|
main_element_id,
|
||||||
|
};
|
||||||
|
|
||||||
|
doc.inner.set_base_url("dioxus://index.html");
|
||||||
|
//doc.initial_build();
|
||||||
|
doc.inner.print_tree();
|
||||||
|
|
||||||
|
doc
|
||||||
}
|
}
|
||||||
}
|
|
||||||
impl AsMut<BaseDocument> for DioxusDocument {
|
pub fn initial_build(&mut self) {
|
||||||
fn as_mut(&mut self) -> &mut BaseDocument {
|
let mut writer = MutationWriter::new(&mut self.inner, &mut self.vdom_state);
|
||||||
&mut self.inner
|
self.vdom.rebuild(&mut writer);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
impl From<DioxusDocument> for BaseDocument {
|
pub fn create_head_element(
|
||||||
fn from(doc: DioxusDocument) -> BaseDocument {
|
&mut self,
|
||||||
doc.inner
|
name: &str,
|
||||||
|
attributes: &[(String, String)],
|
||||||
|
contents: &Option<String>,
|
||||||
|
) {
|
||||||
|
let mut mutr = self.inner.mutate();
|
||||||
|
|
||||||
|
let attributes = attributes
|
||||||
|
.iter()
|
||||||
|
.map(|(name, value)| Attribute {
|
||||||
|
name: qual_name(name, None),
|
||||||
|
value: value.clone(),
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
let new_elem_id = mutr.create_element(qual_name(name, None), attributes);
|
||||||
|
mutr.append_children(self.head_element_id, &[new_elem_id]);
|
||||||
|
if let Some(contents) = contents {
|
||||||
|
mutr.append_text_to_node(new_elem_id, contents).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: set title (we may also wish to have this built-in to the document?)
|
||||||
|
// if name == "title" {
|
||||||
|
// let title = mutr.doc.nodes[new_elem_id].text_content();
|
||||||
|
//
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Implement DocumentLike and required traits for DioxusDocument
|
||||||
impl Document for DioxusDocument {
|
impl Document for DioxusDocument {
|
||||||
type Doc = BaseDocument;
|
fn id(&self) -> usize {
|
||||||
|
self.inner.id()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn as_any_mut(&mut self) -> &mut dyn Any {
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
fn poll(&mut self, mut cx: std::task::Context) -> bool {
|
fn poll(&mut self, mut cx: std::task::Context) -> bool {
|
||||||
{
|
{
|
||||||
@@ -78,487 +166,94 @@ impl Document for DioxusDocument {
|
|||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
fn id(&self) -> usize {
|
fn handle_event(&mut self, event: UiEvent) {
|
||||||
self.inner.id()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn handle_event(&mut self, event: &mut DomEvent) {
|
|
||||||
let chain = self.inner.node_chain(event.target);
|
|
||||||
|
|
||||||
set_event_converter(Box::new(NativeConverter {}));
|
set_event_converter(Box::new(NativeConverter {}));
|
||||||
|
let handler = DioxusEventHandler {
|
||||||
let renderer_event = event.clone();
|
vdom: &mut self.vdom,
|
||||||
|
vdom_state: &mut self.vdom_state,
|
||||||
let mut prevent_default = false;
|
};
|
||||||
let mut stop_propagation = false;
|
let mut driver = EventDriver::new(self.inner.mutate(), handler);
|
||||||
|
driver.handle_ui_event(event);
|
||||||
match &event.data {
|
|
||||||
DomEventData::MouseMove(data)
|
|
||||||
| DomEventData::MouseDown(data)
|
|
||||||
| DomEventData::MouseUp(data) => {
|
|
||||||
let click_event_data = wrap_event_data(NativeClickData(data.clone()));
|
|
||||||
|
|
||||||
for node_id in chain.clone().into_iter() {
|
|
||||||
let node = &self.inner.tree()[node_id];
|
|
||||||
let dioxus_id = node.element_data().and_then(DioxusDocument::dioxus_id);
|
|
||||||
|
|
||||||
if let Some(id) = dioxus_id {
|
|
||||||
let click_event = Event::new(click_event_data.clone(), true);
|
|
||||||
self.vdom
|
|
||||||
.runtime()
|
|
||||||
.handle_event(event.name(), click_event.clone(), id);
|
|
||||||
prevent_default |= !click_event.default_action_enabled();
|
|
||||||
stop_propagation |= !click_event.propagates();
|
|
||||||
}
|
|
||||||
|
|
||||||
if !event.bubbles || stop_propagation {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DomEventData::Click(data) => {
|
|
||||||
let click_event_data = wrap_event_data(NativeClickData(data.clone()));
|
|
||||||
|
|
||||||
for node_id in chain.clone().into_iter() {
|
|
||||||
let node = &self.inner.tree()[node_id];
|
|
||||||
let dioxus_id = node.element_data().and_then(DioxusDocument::dioxus_id);
|
|
||||||
let mut trigger_label = false;
|
|
||||||
|
|
||||||
if let Some(id) = dioxus_id {
|
|
||||||
// Trigger click event
|
|
||||||
let click_event = Event::new(click_event_data.clone(), true);
|
|
||||||
self.vdom
|
|
||||||
.runtime()
|
|
||||||
.handle_event("click", click_event.clone(), id);
|
|
||||||
prevent_default |= !click_event.default_action_enabled();
|
|
||||||
stop_propagation |= !click_event.propagates();
|
|
||||||
|
|
||||||
if !prevent_default {
|
|
||||||
let mut default_event =
|
|
||||||
DomEvent::new(node_id, renderer_event.data.clone());
|
|
||||||
self.inner.as_mut().handle_event(&mut default_event);
|
|
||||||
prevent_default = true;
|
|
||||||
|
|
||||||
let element = self.inner.tree()[node_id].element_data().unwrap();
|
|
||||||
trigger_label = element.name.local == *"label";
|
|
||||||
|
|
||||||
//TODO Check for other inputs which trigger input event on click here, eg radio
|
|
||||||
let triggers_input_event = element.name.local == local_name!("input")
|
|
||||||
&& element.attr(local_name!("type")) == Some("checkbox");
|
|
||||||
if triggers_input_event {
|
|
||||||
let form_data =
|
|
||||||
wrap_event_data(self.input_event_form_data(&chain, element));
|
|
||||||
let input_event = Event::new(form_data, true);
|
|
||||||
self.vdom.runtime().handle_event("input", input_event, id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Clicking labels triggers click, and possibly input event, of bound input
|
|
||||||
if trigger_label {
|
|
||||||
if let Some((dioxus_id, node_id)) = self.label_bound_input_element(node_id)
|
|
||||||
{
|
|
||||||
let click_event = Event::new(click_event_data.clone(), true);
|
|
||||||
self.vdom.runtime().handle_event(
|
|
||||||
"click",
|
|
||||||
click_event.clone(),
|
|
||||||
dioxus_id,
|
|
||||||
);
|
|
||||||
|
|
||||||
// Handle default DOM event
|
|
||||||
if click_event.default_action_enabled() {
|
|
||||||
let DomEventData::Click(event) = &renderer_event.data else {
|
|
||||||
unreachable!();
|
|
||||||
};
|
|
||||||
let input_click_data = self
|
|
||||||
.inner
|
|
||||||
.get_node(node_id)
|
|
||||||
.unwrap()
|
|
||||||
.synthetic_click_event(event.mods);
|
|
||||||
let mut default_event = DomEvent::new(node_id, input_click_data);
|
|
||||||
self.inner.as_mut().handle_event(&mut default_event);
|
|
||||||
prevent_default = true;
|
|
||||||
|
|
||||||
// TODO: Generated click events should bubble separately
|
|
||||||
// prevent_default |= !click_event.default_action_enabled();
|
|
||||||
|
|
||||||
//TODO Check for other inputs which trigger input event on click here, eg radio
|
|
||||||
let element_data = self
|
|
||||||
.inner
|
|
||||||
.get_node(node_id)
|
|
||||||
.unwrap()
|
|
||||||
.element_data()
|
|
||||||
.unwrap();
|
|
||||||
let triggers_input_event =
|
|
||||||
element_data.attr(local_name!("type")) == Some("checkbox");
|
|
||||||
let form_data = wrap_event_data(
|
|
||||||
self.input_event_form_data(&chain, element_data),
|
|
||||||
);
|
|
||||||
if triggers_input_event {
|
|
||||||
let input_event = Event::new(form_data, true);
|
|
||||||
self.vdom.runtime().handle_event(
|
|
||||||
"input",
|
|
||||||
input_event,
|
|
||||||
dioxus_id,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if !event.bubbles || stop_propagation {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DomEventData::KeyPress(kevent) => {
|
|
||||||
let key_event_data = wrap_event_data(BlitzKeyboardData(kevent.clone()));
|
|
||||||
|
|
||||||
for node_id in chain.clone().into_iter() {
|
|
||||||
let node = &self.inner.tree()[node_id];
|
|
||||||
let dioxus_id = node.element_data().and_then(DioxusDocument::dioxus_id);
|
|
||||||
println!("{} {:?}", node_id, dioxus_id);
|
|
||||||
|
|
||||||
if let Some(id) = dioxus_id {
|
|
||||||
if kevent.state.is_pressed() {
|
|
||||||
// Handle keydown event
|
|
||||||
let event = Event::new(key_event_data.clone(), true);
|
|
||||||
self.vdom
|
|
||||||
.runtime()
|
|
||||||
.handle_event("keydown", event.clone(), id);
|
|
||||||
prevent_default |= !event.default_action_enabled();
|
|
||||||
stop_propagation |= !event.propagates();
|
|
||||||
|
|
||||||
if !prevent_default && kevent.text.is_some() {
|
|
||||||
// Handle keypress event
|
|
||||||
let event = Event::new(key_event_data.clone(), true);
|
|
||||||
self.vdom
|
|
||||||
.runtime()
|
|
||||||
.handle_event("keypress", event.clone(), id);
|
|
||||||
prevent_default |= !event.default_action_enabled();
|
|
||||||
stop_propagation |= !event.propagates();
|
|
||||||
|
|
||||||
if !prevent_default {
|
|
||||||
// Handle default DOM event
|
|
||||||
let mut default_event =
|
|
||||||
DomEvent::new(node_id, renderer_event.data.clone());
|
|
||||||
self.inner.as_mut().handle_event(&mut default_event);
|
|
||||||
prevent_default = true;
|
|
||||||
|
|
||||||
// Handle input event
|
|
||||||
let element =
|
|
||||||
self.inner.tree()[node_id].element_data().unwrap();
|
|
||||||
let triggers_input_event = &element.name.local == "input"
|
|
||||||
&& matches!(
|
|
||||||
element.attr(local_name!("type")),
|
|
||||||
None | Some("text" | "password" | "email" | "search")
|
|
||||||
);
|
|
||||||
if triggers_input_event {
|
|
||||||
let form_data = wrap_event_data(dbg!(
|
|
||||||
self.input_event_form_data(&chain, element)
|
|
||||||
));
|
|
||||||
let input_event = Event::new(form_data, true);
|
|
||||||
self.vdom.runtime().handle_event("input", input_event, id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Handle keyup event
|
|
||||||
let event = Event::new(key_event_data.clone(), true);
|
|
||||||
self.vdom.runtime().handle_event("keyup", event.clone(), id);
|
|
||||||
prevent_default |= !event.default_action_enabled();
|
|
||||||
stop_propagation |= !event.propagates();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if !event.bubbles || stop_propagation {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DomEventData::Hover => {}
|
|
||||||
|
|
||||||
// TODO: Implement IME and Hover events handling
|
|
||||||
DomEventData::Ime(_) => {}
|
|
||||||
}
|
|
||||||
|
|
||||||
if !event.cancelable || !prevent_default {
|
|
||||||
self.inner.as_mut().handle_event(event);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn wrap_event_data<T: Any>(value: T) -> Rc<dyn Any> {
|
impl Deref for DioxusDocument {
|
||||||
Rc::new(PlatformEventData::new(Box::new(value)))
|
type Target = BaseDocument;
|
||||||
|
fn deref(&self) -> &BaseDocument {
|
||||||
|
&self.inner
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl DerefMut for DioxusDocument {
|
||||||
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||||
|
&mut self.inner
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl From<DioxusDocument> for BaseDocument {
|
||||||
|
fn from(doc: DioxusDocument) -> BaseDocument {
|
||||||
|
doc.inner
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DioxusDocument {
|
pub struct DioxusEventHandler<'v> {
|
||||||
/// Generate the FormData from an input event
|
vdom: &'v mut VirtualDom,
|
||||||
/// Currently only cares about input checkboxes
|
#[allow(dead_code, reason = "WIP")]
|
||||||
pub fn input_event_form_data(
|
vdom_state: &'v mut DioxusState,
|
||||||
&self,
|
}
|
||||||
parent_chain: &[usize],
|
|
||||||
element_node_data: &ElementNodeData,
|
|
||||||
) -> NativeFormData {
|
|
||||||
let parent_form = parent_chain.iter().find_map(|id| {
|
|
||||||
let node = self.inner.get_node(*id)?;
|
|
||||||
let element_data = node.element_data()?;
|
|
||||||
if element_data.name.local == local_name!("form") {
|
|
||||||
Some(node)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
});
|
|
||||||
let values = if let Some(parent_form) = parent_form {
|
|
||||||
let mut values = HashMap::<String, FormValue>::new();
|
|
||||||
for form_input in self.input_descendents(parent_form).into_iter() {
|
|
||||||
// Match html behaviour here. To be included in values:
|
|
||||||
// - input must have a name
|
|
||||||
// - if its an input, we only include it if checked
|
|
||||||
// - if value is not specified, it defaults to 'on'
|
|
||||||
if let Some(name) = form_input.attr(local_name!("name")) {
|
|
||||||
if form_input.attr(local_name!("type")) == Some("checkbox")
|
|
||||||
&& form_input
|
|
||||||
.element_data()
|
|
||||||
.and_then(|data| data.checkbox_input_checked())
|
|
||||||
.unwrap_or(false)
|
|
||||||
{
|
|
||||||
let value = form_input
|
|
||||||
.attr(local_name!("value"))
|
|
||||||
.unwrap_or("on")
|
|
||||||
.to_string();
|
|
||||||
values.insert(name.to_string(), FormValue(vec![value]));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
values
|
|
||||||
} else {
|
|
||||||
Default::default()
|
|
||||||
};
|
|
||||||
let value = match &element_node_data.node_specific_data {
|
|
||||||
NodeSpecificData::CheckboxInput(checked) => checked.to_string(),
|
|
||||||
NodeSpecificData::TextInput(input_data) => input_data.editor.text().to_string(),
|
|
||||||
_ => element_node_data
|
|
||||||
.attr(local_name!("value"))
|
|
||||||
.unwrap_or_default()
|
|
||||||
.to_string(),
|
|
||||||
};
|
|
||||||
|
|
||||||
NativeFormData { value, values }
|
impl EventHandler for DioxusEventHandler<'_> {
|
||||||
}
|
fn handle_event(
|
||||||
|
|
||||||
/// Collect all the inputs which are descendents of a given node
|
|
||||||
fn input_descendents(&self, node: &Node) -> Vec<&Node> {
|
|
||||||
node.children
|
|
||||||
.iter()
|
|
||||||
.flat_map(|id| {
|
|
||||||
let mut res = Vec::<&Node>::new();
|
|
||||||
let Some(n) = self.inner.get_node(*id) else {
|
|
||||||
return res;
|
|
||||||
};
|
|
||||||
let Some(element_data) = n.element_data() else {
|
|
||||||
return res;
|
|
||||||
};
|
|
||||||
if element_data.name.local == local_name!("input") {
|
|
||||||
res.push(n);
|
|
||||||
}
|
|
||||||
res.extend(self.input_descendents(n).iter());
|
|
||||||
res
|
|
||||||
})
|
|
||||||
.collect()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn new(
|
|
||||||
vdom: VirtualDom,
|
|
||||||
net_provider: Option<Arc<dyn NetProvider<Data = Resource>>>,
|
|
||||||
) -> Self {
|
|
||||||
let viewport = Viewport::new(0, 0, 1.0, ColorScheme::Light);
|
|
||||||
let mut doc = BaseDocument::new(viewport);
|
|
||||||
|
|
||||||
// Set net provider
|
|
||||||
if let Some(net_provider) = net_provider {
|
|
||||||
doc.set_net_provider(net_provider);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create a virtual "html" element to act as the root element, as we won't necessarily
|
|
||||||
// have a single root otherwise, while the rest of blitz requires that we do
|
|
||||||
let html_element_id = doc.create_node(NodeData::Element(ElementNodeData::new(
|
|
||||||
qual_name("html", None),
|
|
||||||
Vec::new(),
|
|
||||||
)));
|
|
||||||
let root_node_id = doc.root_node().id;
|
|
||||||
let html_element = doc.get_node_mut(html_element_id).unwrap();
|
|
||||||
html_element.parent = Some(root_node_id);
|
|
||||||
let root_node = doc.get_node_mut(root_node_id).unwrap();
|
|
||||||
root_node.children.push(html_element_id);
|
|
||||||
|
|
||||||
// Create the body element
|
|
||||||
let body_element_id = doc.create_node(NodeData::Element(ElementNodeData::new(
|
|
||||||
qual_name("body", None),
|
|
||||||
Vec::new(),
|
|
||||||
)));
|
|
||||||
let html_element = doc.get_node_mut(html_element_id).unwrap();
|
|
||||||
html_element.children.push(body_element_id);
|
|
||||||
let body_element = doc.get_node_mut(body_element_id).unwrap();
|
|
||||||
body_element.parent = Some(html_element_id);
|
|
||||||
|
|
||||||
// Create another virtual element to hold the root <div id="main"></div> under the html element
|
|
||||||
let main_element_id = doc.create_node(NodeData::Element(ElementNodeData::new(
|
|
||||||
qual_name("div", Some("id")),
|
|
||||||
vec![blitz_dom::node::Attribute {
|
|
||||||
name: qual_name("id", None),
|
|
||||||
value: "main".to_string(),
|
|
||||||
}],
|
|
||||||
)));
|
|
||||||
let body_element = doc.get_node_mut(body_element_id).unwrap();
|
|
||||||
body_element.children.push(main_element_id);
|
|
||||||
let main_element = doc.get_node_mut(main_element_id).unwrap();
|
|
||||||
main_element.parent = Some(body_element_id);
|
|
||||||
|
|
||||||
// Create the head element
|
|
||||||
let head_element_id = doc.create_node(NodeData::Element(ElementNodeData::new(
|
|
||||||
qual_name("head", None),
|
|
||||||
Vec::new(),
|
|
||||||
)));
|
|
||||||
let head_element = doc.get_node_mut(head_element_id).unwrap();
|
|
||||||
head_element.parent = Some(html_element_id);
|
|
||||||
let html_element = doc.get_node_mut(html_element_id).unwrap();
|
|
||||||
html_element.children.push(head_element_id);
|
|
||||||
|
|
||||||
// Include default and user-specified stylesheets
|
|
||||||
doc.add_user_agent_stylesheet(DEFAULT_CSS);
|
|
||||||
|
|
||||||
let state = DioxusState::create(&mut doc, main_element_id);
|
|
||||||
let mut doc = Self {
|
|
||||||
vdom,
|
|
||||||
vdom_state: state,
|
|
||||||
inner: doc,
|
|
||||||
html_element_id,
|
|
||||||
head_element_id,
|
|
||||||
body_element_id,
|
|
||||||
main_element_id,
|
|
||||||
};
|
|
||||||
|
|
||||||
doc.inner.set_base_url("dioxus://index.html");
|
|
||||||
|
|
||||||
// doc.initial_build();
|
|
||||||
|
|
||||||
// doc.inner.print_tree();
|
|
||||||
|
|
||||||
doc
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn initial_build(&mut self) {
|
|
||||||
// let mut writer = MutationWriter::new(&mut self.inner, &mut self.vdom_state);
|
|
||||||
|
|
||||||
// self.vdom.rebuild(&mut writer);
|
|
||||||
// dbg!(self.vdom.rebuild_to_vec());
|
|
||||||
// std::process::exit(0);
|
|
||||||
// dbg!(writer.state);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn label_bound_input_element(&self, label_node_id: NodeId) -> Option<(ElementId, NodeId)> {
|
|
||||||
let bound_input_elements = self.inner.label_bound_input_elements(label_node_id);
|
|
||||||
|
|
||||||
// Filter down bound elements to those which have dioxus id
|
|
||||||
bound_input_elements.into_iter().find_map(|n| {
|
|
||||||
let target_element_data = n.element_data()?;
|
|
||||||
let node_id = n.id;
|
|
||||||
let dioxus_id = DioxusDocument::dioxus_id(target_element_data)?;
|
|
||||||
Some((dioxus_id, node_id))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn dioxus_id(element_node_data: &ElementNodeData) -> Option<ElementId> {
|
|
||||||
Some(ElementId(
|
|
||||||
element_node_data
|
|
||||||
.attrs
|
|
||||||
.iter()
|
|
||||||
.find(|attr| *attr.name.local == *"data-dioxus-id")?
|
|
||||||
.value
|
|
||||||
.parse::<usize>()
|
|
||||||
.ok()?,
|
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn create_head_element(
|
|
||||||
&mut self,
|
&mut self,
|
||||||
name: &str,
|
chain: &[usize],
|
||||||
attributes: &[(String, String)],
|
event: &mut DomEvent,
|
||||||
contents: &Option<String>,
|
mutr: &mut blitz_dom::DocumentMutator<'_>,
|
||||||
|
event_state: &mut EventState,
|
||||||
) {
|
) {
|
||||||
let mut stylesheet = None;
|
let event_data = match &event.data {
|
||||||
let mut title = None;
|
DomEventData::MouseMove(mevent)
|
||||||
if name == "link" {
|
| DomEventData::MouseDown(mevent)
|
||||||
let is_stylesheet = attributes
|
| DomEventData::MouseUp(mevent)
|
||||||
.iter()
|
| DomEventData::Click(mevent) => Some(wrap_event_data(NativeClickData(mevent.clone()))),
|
||||||
.any(|(name, value)| name == "rel" && value == "stylesheet");
|
|
||||||
if is_stylesheet {
|
DomEventData::KeyDown(kevent)
|
||||||
stylesheet = attributes
|
| DomEventData::KeyUp(kevent)
|
||||||
.iter()
|
| DomEventData::KeyPress(kevent) => {
|
||||||
.find(|(name, _value)| name == "href")
|
Some(wrap_event_data(BlitzKeyboardData(kevent.clone())))
|
||||||
.map(|(_name, value)| value.clone());
|
}
|
||||||
|
|
||||||
|
DomEventData::Input(data) => Some(wrap_event_data(NativeFormData {
|
||||||
|
value: data.value.clone(),
|
||||||
|
values: HashMap::new(),
|
||||||
|
})),
|
||||||
|
|
||||||
|
// TODO: Implement IME handling
|
||||||
|
DomEventData::Ime(_) => None,
|
||||||
|
};
|
||||||
|
|
||||||
|
let Some(event_data) = event_data else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
for &node_id in chain {
|
||||||
|
// Get dioxus vdom id for node
|
||||||
|
let dioxus_id = mutr.doc.get_node(node_id).and_then(get_dioxus_id);
|
||||||
|
let Some(id) = dioxus_id else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Handle event in vdom
|
||||||
|
let dx_event = Event::new(event_data.clone(), event.bubbles);
|
||||||
|
self.vdom
|
||||||
|
.runtime()
|
||||||
|
.handle_event(event.name(), dx_event.clone(), id);
|
||||||
|
|
||||||
|
// Update event state
|
||||||
|
if !dx_event.default_action_enabled() {
|
||||||
|
event_state.prevent_default();
|
||||||
|
}
|
||||||
|
if !dx_event.propagates() {
|
||||||
|
event_state.stop_propagation();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if name == "title" {
|
|
||||||
title = attributes
|
|
||||||
.iter()
|
|
||||||
.find(|(name, _value)| name == "text")
|
|
||||||
.and_then(|(_name, _value)| contents.clone());
|
|
||||||
}
|
|
||||||
|
|
||||||
let attributes = attributes
|
|
||||||
.iter()
|
|
||||||
.map(|(name, value)| Attribute {
|
|
||||||
name: qual_name(name, None),
|
|
||||||
value: value.clone(),
|
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
let new_element = self
|
|
||||||
.inner
|
|
||||||
.create_node(NodeData::Element(ElementNodeData::new(
|
|
||||||
qual_name(name, None),
|
|
||||||
attributes,
|
|
||||||
)));
|
|
||||||
|
|
||||||
if let Some(contents) = contents {
|
|
||||||
let text_node = self.inner.create_text_node(contents);
|
|
||||||
self.inner
|
|
||||||
.get_node_mut(new_element)
|
|
||||||
.unwrap()
|
|
||||||
.children
|
|
||||||
.push(text_node);
|
|
||||||
}
|
|
||||||
|
|
||||||
self.inner
|
|
||||||
.get_node_mut(self.head_element_id)
|
|
||||||
.unwrap()
|
|
||||||
.children
|
|
||||||
.push(new_element);
|
|
||||||
|
|
||||||
if let Some(url) = stylesheet {
|
|
||||||
crate::assets::fetch_linked_stylesheet(&self.inner, new_element, url);
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(_title) = title {
|
|
||||||
println!("todo: set title");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// pub fn apply_mutations(&mut self) {
|
|
||||||
// // Apply the mutations to the actual dom
|
|
||||||
// let mut writer = MutationWriter {
|
|
||||||
// doc: &mut self.inner,
|
|
||||||
// state: &mut self.vdom_state,
|
|
||||||
// };
|
|
||||||
// self.vdom.render_immediate(&mut writer);
|
|
||||||
|
|
||||||
// println!("APPLY MUTATIONS");
|
|
||||||
// self.inner.print_tree();
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
use winit::window::WindowId;
|
|
||||||
|
|
||||||
/// Dioxus-native specific event type
|
|
||||||
pub enum DioxusNativeEvent {
|
|
||||||
/// A hotreload event, basically telling us to update our templates.
|
|
||||||
#[cfg(all(
|
|
||||||
feature = "hot-reload",
|
|
||||||
debug_assertions,
|
|
||||||
not(target_os = "android"),
|
|
||||||
not(target_os = "ios")
|
|
||||||
))]
|
|
||||||
DevserverEvent(dioxus_devtools::DevserverMsg),
|
|
||||||
|
|
||||||
/// Create a new head element from the Link and Title elements
|
|
||||||
///
|
|
||||||
/// todo(jon): these should probabkly be synchronous somehow
|
|
||||||
CreateHeadElement {
|
|
||||||
window: WindowId,
|
|
||||||
name: String,
|
|
||||||
attributes: Vec<(String, String)>,
|
|
||||||
contents: Option<String>,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
File renamed without changes.
@@ -13,13 +13,12 @@ mod assets;
|
|||||||
mod contexts;
|
mod contexts;
|
||||||
mod dioxus_application;
|
mod dioxus_application;
|
||||||
mod dioxus_document;
|
mod dioxus_document;
|
||||||
mod event;
|
mod events;
|
||||||
mod event_handler;
|
|
||||||
mod mutation_writer;
|
mod mutation_writer;
|
||||||
|
|
||||||
pub use dioxus_application::DioxusNativeApplication;
|
use blitz_dom::{ns, Atom, QualName};
|
||||||
|
pub use dioxus_application::{DioxusNativeApplication, DioxusNativeEvent};
|
||||||
pub use dioxus_document::DioxusDocument;
|
pub use dioxus_document::DioxusDocument;
|
||||||
pub use event::DioxusNativeEvent;
|
|
||||||
|
|
||||||
use blitz_shell::{create_default_event_loop, BlitzShellEvent, Config, WindowConfig};
|
use blitz_shell::{create_default_event_loop, BlitzShellEvent, Config, WindowConfig};
|
||||||
use dioxus_core::{ComponentFunction, Element, VirtualDom};
|
use dioxus_core::{ComponentFunction, Element, VirtualDom};
|
||||||
@@ -68,7 +67,6 @@ pub fn launch_cfg_with_props<P: Clone + 'static, M: 'static>(
|
|||||||
not(target_os = "ios")
|
not(target_os = "ios")
|
||||||
))]
|
))]
|
||||||
{
|
{
|
||||||
use crate::event::DioxusNativeEvent;
|
|
||||||
let proxy = event_loop.create_proxy();
|
let proxy = event_loop.create_proxy();
|
||||||
dioxus_devtools::connect(move |event| {
|
dioxus_devtools::connect(move |event| {
|
||||||
let dxn_event = DioxusNativeEvent::DevserverEvent(event);
|
let dxn_event = DioxusNativeEvent::DevserverEvent(event);
|
||||||
@@ -92,3 +90,36 @@ pub fn launch_cfg_with_props<P: Clone + 'static, M: 'static>(
|
|||||||
// Run event loop
|
// Run event loop
|
||||||
event_loop.run_app(&mut application).unwrap();
|
event_loop.run_app(&mut application).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn qual_name(local_name: &str, namespace: Option<&str>) -> QualName {
|
||||||
|
QualName {
|
||||||
|
prefix: None,
|
||||||
|
ns: namespace.map(Atom::from).unwrap_or(ns!(html)),
|
||||||
|
local: Atom::from(local_name),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Syntax sugar to make tracing calls less noisy in function below
|
||||||
|
macro_rules! trace {
|
||||||
|
($pattern:literal) => {{
|
||||||
|
#[cfg(feature = "tracing")]
|
||||||
|
tracing::info!($pattern);
|
||||||
|
}};
|
||||||
|
($pattern:literal, $item1:expr) => {{
|
||||||
|
#[cfg(feature = "tracing")]
|
||||||
|
tracing::info!($pattern, $item1);
|
||||||
|
}};
|
||||||
|
($pattern:literal, $item1:expr, $item2:expr) => {{
|
||||||
|
#[cfg(feature = "tracing")]
|
||||||
|
tracing::info!($pattern, $item1, $item2);
|
||||||
|
}};
|
||||||
|
($pattern:literal, $item1:expr, $item2:expr, $item3:expr) => {{
|
||||||
|
#[cfg(feature = "tracing")]
|
||||||
|
tracing::info!($pattern, $item1, $item2);
|
||||||
|
}};
|
||||||
|
($pattern:literal, $item1:expr, $item2:expr, $item3:expr, $item4:expr) => {{
|
||||||
|
#[cfg(feature = "tracing")]
|
||||||
|
tracing::info!($pattern, $item1, $item2, $item3, $item4);
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
pub(crate) use trace;
|
||||||
@@ -1,14 +1,10 @@
|
|||||||
use crate::{dioxus_document::qual_name, NodeId};
|
//! Integration between Dioxus and Blitz
|
||||||
use blitz_dom::{
|
use crate::{qual_name, trace, NodeId};
|
||||||
local_name, namespace_url,
|
use blitz_dom::{Attribute, BaseDocument, DocumentMutator};
|
||||||
node::{Attribute, NodeSpecificData},
|
|
||||||
ns, BaseDocument, ElementNodeData, NodeData, QualName, RestyleHint,
|
|
||||||
};
|
|
||||||
use dioxus_core::{
|
use dioxus_core::{
|
||||||
AttributeValue, ElementId, Template, TemplateAttribute, TemplateNode, WriteMutations,
|
AttributeValue, ElementId, Template, TemplateAttribute, TemplateNode, WriteMutations,
|
||||||
};
|
};
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
use std::collections::HashSet;
|
|
||||||
|
|
||||||
/// The state of the Dioxus integration with the RealDom
|
/// The state of the Dioxus integration with the RealDom
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@@ -21,79 +17,13 @@ pub struct DioxusState {
|
|||||||
node_id_mapping: Vec<Option<NodeId>>,
|
node_id_mapping: Vec<Option<NodeId>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A writer for mutations that can be used with the RealDom.
|
|
||||||
pub struct MutationWriter<'a> {
|
|
||||||
/// The realdom associated with this writer
|
|
||||||
pub doc: &'a mut BaseDocument,
|
|
||||||
|
|
||||||
/// The state associated with this writer
|
|
||||||
pub state: &'a mut DioxusState,
|
|
||||||
|
|
||||||
pub style_nodes: HashSet<usize>,
|
|
||||||
|
|
||||||
/// The (latest) node which has been mounted in and had autofocus=true, if any
|
|
||||||
#[cfg(feature = "autofocus")]
|
|
||||||
pub node_to_autofocus: Option<usize>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> MutationWriter<'a> {
|
|
||||||
pub fn new(doc: &'a mut BaseDocument, state: &'a mut DioxusState) -> Self {
|
|
||||||
MutationWriter {
|
|
||||||
doc,
|
|
||||||
state,
|
|
||||||
style_nodes: HashSet::new(),
|
|
||||||
|
|
||||||
#[cfg(feature = "autofocus")]
|
|
||||||
node_to_autofocus: None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn is_style_node(&self, node_id: NodeId) -> bool {
|
|
||||||
self.doc
|
|
||||||
.get_node(node_id)
|
|
||||||
.unwrap()
|
|
||||||
.data
|
|
||||||
.is_element_with_tag_name(&local_name!("style"))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn maybe_push_style_node(&mut self, node_id: impl Into<Option<NodeId>>) {
|
|
||||||
if let Some(node_id) = node_id.into() {
|
|
||||||
if self.is_style_node(node_id) {
|
|
||||||
self.style_nodes.insert(node_id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[track_caller]
|
|
||||||
fn maybe_push_parent_style_node(&mut self, node_id: NodeId) {
|
|
||||||
let parent_id = self.doc.get_node(node_id).unwrap().parent;
|
|
||||||
self.maybe_push_style_node(parent_id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Drop for MutationWriter<'_> {
|
|
||||||
fn drop(&mut self) {
|
|
||||||
// Add/Update inline stylesheets (<style> elements)
|
|
||||||
for &id in &self.style_nodes {
|
|
||||||
self.doc.upsert_stylesheet_for_node(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "autofocus")]
|
|
||||||
if let Some(node_id) = self.node_to_autofocus {
|
|
||||||
if self.doc.get_node(node_id).is_some() {
|
|
||||||
self.doc.set_focus_to(node_id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl DioxusState {
|
impl DioxusState {
|
||||||
/// Initialize the DioxusState in the RealDom
|
/// Initialize the DioxusState in the RealDom
|
||||||
pub fn create(_doc: &mut BaseDocument, mount_node: NodeId) -> Self {
|
pub fn create(root_id: usize) -> Self {
|
||||||
Self {
|
Self {
|
||||||
templates: FxHashMap::default(),
|
templates: FxHashMap::default(),
|
||||||
stack: vec![mount_node],
|
stack: vec![root_id],
|
||||||
node_id_mapping: vec![Some(mount_node)],
|
node_id_mapping: vec![Some(root_id)],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -106,6 +36,33 @@ impl DioxusState {
|
|||||||
pub fn try_element_to_node_id(&self, element_id: ElementId) -> Option<NodeId> {
|
pub fn try_element_to_node_id(&self, element_id: ElementId) -> Option<NodeId> {
|
||||||
self.node_id_mapping.get(element_id.0).copied().flatten()
|
self.node_id_mapping.get(element_id.0).copied().flatten()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn anchor_and_nodes(&mut self, id: ElementId, m: usize) -> (usize, Vec<usize>) {
|
||||||
|
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<usize> {
|
||||||
|
self.stack.split_off(self.stack.len() - m)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 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,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MutationWriter<'_> {
|
impl MutationWriter<'_> {
|
||||||
@@ -122,454 +79,226 @@ impl MutationWriter<'_> {
|
|||||||
self.state.node_id_mapping[element_id] = Some(node_id);
|
self.state.node_id_mapping[element_id] = Some(node_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Find a child in the document by child index path
|
/// Create a ElementId -> NodeId mapping and push the node to the stack
|
||||||
fn load_child(&self, path: &[u8]) -> NodeId {
|
fn map_new_node(&mut self, node_id: NodeId, element_id: ElementId) {
|
||||||
let mut current = self
|
self.set_id_mapping(node_id, element_id);
|
||||||
.doc
|
self.state.stack.push(node_id);
|
||||||
.get_node(*self.state.stack.last().unwrap())
|
|
||||||
.unwrap();
|
|
||||||
for i in path {
|
|
||||||
let new_id = current.children[*i as usize];
|
|
||||||
current = self.doc.get_node(new_id).unwrap();
|
|
||||||
}
|
|
||||||
current.id
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_template_node(&mut self, node: &TemplateNode) -> NodeId {
|
/// Find a child in the document by child index path
|
||||||
match node {
|
fn load_child(&self, path: &[u8]) -> NodeId {
|
||||||
TemplateNode::Element {
|
let top_of_stack_node_id = *self.state.stack.last().unwrap();
|
||||||
tag,
|
self.docm.node_at_path(top_of_stack_node_id, path)
|
||||||
namespace,
|
|
||||||
attrs,
|
|
||||||
children,
|
|
||||||
} => {
|
|
||||||
let name = qual_name(tag, *namespace);
|
|
||||||
let attrs = attrs
|
|
||||||
.iter()
|
|
||||||
.filter_map(|attr| match attr {
|
|
||||||
TemplateAttribute::Static {
|
|
||||||
name,
|
|
||||||
value,
|
|
||||||
namespace,
|
|
||||||
} => Some(Attribute {
|
|
||||||
name: qual_name(name, *namespace),
|
|
||||||
value: value.to_string(),
|
|
||||||
}),
|
|
||||||
TemplateAttribute::Dynamic { .. } => None,
|
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
let mut data = ElementNodeData::new(name, attrs);
|
|
||||||
data.flush_style_attribute(self.doc.guard());
|
|
||||||
|
|
||||||
let child_ids: Vec<NodeId> = children
|
|
||||||
.iter()
|
|
||||||
.map(|child| self.create_template_node(child))
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
let id = self.doc.create_node(NodeData::Element(data));
|
|
||||||
let node = self.doc.get_node(id).unwrap();
|
|
||||||
|
|
||||||
// Initialise style data
|
|
||||||
*node.stylo_element_data.borrow_mut() = Some(Default::default());
|
|
||||||
|
|
||||||
if let Some(src_attr) = node.attr(local_name!("src")) {
|
|
||||||
crate::assets::fetch_image(self.doc, id, src_attr.to_string());
|
|
||||||
}
|
|
||||||
|
|
||||||
let rel_attr = node.attr(local_name!("rel"));
|
|
||||||
let href_attr = node.attr(local_name!("href"));
|
|
||||||
if let (Some("stylesheet"), Some(href)) = (rel_attr, href_attr) {
|
|
||||||
crate::assets::fetch_linked_stylesheet(self.doc, id, href.to_string());
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the node has an "id" attribute, store it in the ID map.
|
|
||||||
if let Some(id_attr) = node.attr(local_name!("id")) {
|
|
||||||
self.doc.nodes_to_id.insert(id_attr.to_string(), id);
|
|
||||||
}
|
|
||||||
|
|
||||||
for &child_id in &child_ids {
|
|
||||||
self.doc.get_node_mut(child_id).unwrap().parent = Some(id);
|
|
||||||
}
|
|
||||||
self.doc.get_node_mut(id).unwrap().children = child_ids;
|
|
||||||
|
|
||||||
id
|
|
||||||
}
|
|
||||||
TemplateNode::Text { text } => self.doc.create_text_node(text),
|
|
||||||
TemplateNode::Dynamic { .. } => self.doc.create_node(NodeData::Comment),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WriteMutations for MutationWriter<'_> {
|
impl WriteMutations for MutationWriter<'_> {
|
||||||
fn append_children(&mut self, id: ElementId, m: usize) {
|
|
||||||
#[cfg(feature = "tracing")]
|
|
||||||
tracing::info!("append_children id:{} m:{}", id.0, m);
|
|
||||||
|
|
||||||
let children = self.state.stack.split_off(self.state.stack.len() - m);
|
|
||||||
let parent = self.state.element_to_node_id(id);
|
|
||||||
for child in children {
|
|
||||||
self.doc.get_node_mut(parent).unwrap().children.push(child);
|
|
||||||
self.doc.get_node_mut(child).unwrap().parent = Some(parent);
|
|
||||||
}
|
|
||||||
|
|
||||||
self.maybe_push_style_node(parent);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn assign_node_id(&mut self, path: &'static [u8], id: ElementId) {
|
fn assign_node_id(&mut self, path: &'static [u8], id: ElementId) {
|
||||||
#[cfg(feature = "tracing")]
|
trace!("assign_node_id path:{:?} id:{}", path, id.0);
|
||||||
tracing::info!("assign_node_id path:{:?} id:{}", path, id.0);
|
|
||||||
|
|
||||||
// If there is an existing node already mapped to that ID and
|
// If there is an existing node already mapped to that ID and it has no parent, then drop it
|
||||||
// it has no parent, then drop it
|
// TODO: more automated GC/ref-counted semantics for node lifetimes
|
||||||
if let Some(node_id) = self.state.try_element_to_node_id(id) {
|
if let Some(node_id) = self.state.try_element_to_node_id(id) {
|
||||||
if let Some(node) = self.doc.get_node(node_id) {
|
self.docm.remove_node_if_unparented(node_id);
|
||||||
if node.parent.is_none() {
|
|
||||||
self.doc.remove_and_drop_node(node_id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let node_id = self.load_child(path);
|
// Map the node at specified path
|
||||||
self.set_id_mapping(node_id, id);
|
self.set_id_mapping(self.load_child(path), id);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_placeholder(&mut self, id: ElementId) {
|
fn create_placeholder(&mut self, id: ElementId) {
|
||||||
#[cfg(feature = "tracing")]
|
trace!("create_placeholder id:{}", id.0);
|
||||||
tracing::info!("create_placeholder id:{}", id.0);
|
let node_id = self.docm.create_comment_node();
|
||||||
|
self.map_new_node(node_id, id);
|
||||||
let node_id = self.doc.create_node(NodeData::Comment);
|
|
||||||
self.set_id_mapping(node_id, id);
|
|
||||||
self.state.stack.push(node_id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_text_node(&mut self, value: &str, id: ElementId) {
|
fn create_text_node(&mut self, value: &str, id: ElementId) {
|
||||||
#[cfg(feature = "tracing")]
|
trace!("create_text_node id:{} text:{}", id.0, value);
|
||||||
tracing::info!("create_text_node id:{} text:{}", id.0, value);
|
let node_id = self.docm.create_text_node(value);
|
||||||
|
self.map_new_node(node_id, id);
|
||||||
let node_id = self.doc.create_text_node(value);
|
|
||||||
self.set_id_mapping(node_id, id);
|
|
||||||
self.state.stack.push(node_id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::map_entry)]
|
fn append_children(&mut self, id: ElementId, m: usize) {
|
||||||
fn load_template(&mut self, template: Template, index: usize, id: ElementId) {
|
trace!("append_children id:{} m:{}", id.0, m);
|
||||||
if !self.state.templates.contains_key(&template) {
|
let (parent_id, child_node_ids) = self.state.anchor_and_nodes(id, m);
|
||||||
let template_root_ids: Vec<NodeId> = template
|
self.docm.append_children(parent_id, &child_node_ids);
|
||||||
.roots
|
|
||||||
.iter()
|
|
||||||
.map(|root| self.create_template_node(root))
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
self.state.templates.insert(template, template_root_ids);
|
|
||||||
}
|
|
||||||
|
|
||||||
let template_entry = &self.state.templates[&template];
|
|
||||||
|
|
||||||
let template_node_id = template_entry[index];
|
|
||||||
let clone_id = self.doc.deep_clone_node(template_node_id);
|
|
||||||
|
|
||||||
#[cfg(feature = "autofocus")]
|
|
||||||
autofocus_node_recursive(self.doc, &mut self.node_to_autofocus, clone_id);
|
|
||||||
|
|
||||||
self.set_id_mapping(clone_id, id);
|
|
||||||
self.state.stack.push(clone_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn replace_node_with(&mut self, id: ElementId, m: usize) {
|
|
||||||
#[cfg(feature = "tracing")]
|
|
||||||
tracing::info!("replace_node_with id:{} m:{}", id.0, m);
|
|
||||||
|
|
||||||
let new_nodes = self.state.stack.split_off(self.state.stack.len() - m);
|
|
||||||
let anchor_node_id = self.state.element_to_node_id(id);
|
|
||||||
self.maybe_push_parent_style_node(anchor_node_id);
|
|
||||||
self.doc.insert_before(anchor_node_id, &new_nodes);
|
|
||||||
self.doc.remove_node(anchor_node_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn replace_placeholder_with_nodes(&mut self, path: &'static [u8], m: usize) {
|
|
||||||
#[cfg(feature = "tracing")]
|
|
||||||
tracing::info!("replace_placeholder_with_nodes path:{:?} m:{}", path, m);
|
|
||||||
|
|
||||||
let new_nodes = self.state.stack.split_off(self.state.stack.len() - m);
|
|
||||||
let anchor_node_id = self.load_child(path);
|
|
||||||
self.maybe_push_parent_style_node(anchor_node_id);
|
|
||||||
self.doc.insert_before(anchor_node_id, &new_nodes);
|
|
||||||
self.doc.remove_node(anchor_node_id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn insert_nodes_after(&mut self, id: ElementId, m: usize) {
|
fn insert_nodes_after(&mut self, id: ElementId, m: usize) {
|
||||||
#[cfg(feature = "tracing")]
|
trace!("insert_nodes_after id:{} m:{}", id.0, m);
|
||||||
tracing::info!("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);
|
||||||
let new_nodes = self.state.stack.split_off(self.state.stack.len() - m);
|
|
||||||
let anchor_node_id = self.state.element_to_node_id(id);
|
|
||||||
let next_sibling_id = self
|
|
||||||
.doc
|
|
||||||
.get_node(anchor_node_id)
|
|
||||||
.unwrap()
|
|
||||||
.forward(1)
|
|
||||||
.map(|node| node.id);
|
|
||||||
|
|
||||||
match next_sibling_id {
|
|
||||||
Some(anchor_node_id) => {
|
|
||||||
self.doc.insert_before(anchor_node_id, &new_nodes);
|
|
||||||
}
|
|
||||||
None => self.doc.append(anchor_node_id, &new_nodes),
|
|
||||||
}
|
|
||||||
|
|
||||||
self.maybe_push_parent_style_node(anchor_node_id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn insert_nodes_before(&mut self, id: ElementId, m: usize) {
|
fn insert_nodes_before(&mut self, id: ElementId, m: usize) {
|
||||||
#[cfg(feature = "tracing")]
|
trace!("insert_nodes_before id:{} m:{}", id.0, m);
|
||||||
tracing::info!("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);
|
||||||
|
}
|
||||||
|
|
||||||
let new_nodes = self.state.stack.split_off(self.state.stack.len() - m);
|
fn replace_node_with(&mut self, id: ElementId, m: usize) {
|
||||||
let anchor_node_id = self.state.element_to_node_id(id);
|
trace!("replace_node_with id:{} m:{}", id.0, m);
|
||||||
self.doc.insert_before(anchor_node_id, &new_nodes);
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
self.maybe_push_parent_style_node(anchor_node_id);
|
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_placeholder_with_nodes(anchor_node_id, &new_node_ids);
|
||||||
|
}
|
||||||
|
|
||||||
|
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 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
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 set_attribute(
|
fn set_attribute(
|
||||||
&mut self,
|
&mut self,
|
||||||
name: &'static str,
|
local_name: &'static str,
|
||||||
ns: Option<&'static str>,
|
ns: Option<&'static str>,
|
||||||
value: &AttributeValue,
|
value: &AttributeValue,
|
||||||
id: ElementId,
|
id: ElementId,
|
||||||
) {
|
) {
|
||||||
let node_id = self.state.element_to_node_id(id);
|
let node_id = self.state.element_to_node_id(id);
|
||||||
|
trace!("set_attribute node_id:{node_id} ns: {ns:?} name:{local_name}, value:{value:?}");
|
||||||
|
|
||||||
#[cfg(feature = "tracing")]
|
// Dioxus has overloaded the style namespace to accumulate style attributes without a `style` block
|
||||||
tracing::info!(
|
// TODO: accumulate style attributes into a single style element.
|
||||||
"set_attribute node_id:{} ns: {:?} name:{}, value:{:?}",
|
if ns == Some("style") {
|
||||||
node_id,
|
return;
|
||||||
ns,
|
}
|
||||||
name,
|
|
||||||
value
|
|
||||||
);
|
|
||||||
|
|
||||||
self.doc.snapshot_node(node_id);
|
fn is_falsy(val: &AttributeValue) -> bool {
|
||||||
|
match val {
|
||||||
let mut queued_image = None;
|
AttributeValue::None => true,
|
||||||
let mut queued_stylesheet = None;
|
AttributeValue::Text(val) => val == "false",
|
||||||
|
AttributeValue::Bool(val) => !val,
|
||||||
{
|
AttributeValue::Int(val) => *val == 0,
|
||||||
let node = &mut self.doc.nodes[node_id];
|
AttributeValue::Float(val) => *val == 0.0,
|
||||||
|
_ => false,
|
||||||
let stylo_element_data = &mut *node.stylo_element_data.borrow_mut();
|
|
||||||
if let Some(data) = stylo_element_data {
|
|
||||||
data.hint |= RestyleHint::restyle_subtree();
|
|
||||||
}
|
|
||||||
|
|
||||||
if let NodeData::Element(ref mut element) = node.data {
|
|
||||||
if element.name.local == local_name!("input") && name == "checked" {
|
|
||||||
set_input_checked_state(element, value);
|
|
||||||
}
|
|
||||||
// FIXME: support other non-text attributes
|
|
||||||
else if let AttributeValue::Text(val) = value {
|
|
||||||
if name == "value" {
|
|
||||||
// Update text input value
|
|
||||||
if let Some(input_data) = element.text_input_data_mut() {
|
|
||||||
input_data.set_text(
|
|
||||||
&mut self.doc.font_ctx,
|
|
||||||
&mut self.doc.layout_ctx,
|
|
||||||
val,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME check namespace
|
|
||||||
let existing_attr = element
|
|
||||||
.attrs
|
|
||||||
.iter_mut()
|
|
||||||
.find(|attr| attr.name.local == *name);
|
|
||||||
|
|
||||||
if let Some(existing_attr) = existing_attr {
|
|
||||||
existing_attr.value.clear();
|
|
||||||
existing_attr.value.push_str(val);
|
|
||||||
} else {
|
|
||||||
// we have overloaded the style namespace to accumulate style attributes without a `style` block
|
|
||||||
if ns == Some("style") {
|
|
||||||
// todo: need to accumulate style attributes into a single style
|
|
||||||
//
|
|
||||||
// element.
|
|
||||||
} else {
|
|
||||||
element.attrs.push(Attribute {
|
|
||||||
name: qual_name(name, ns),
|
|
||||||
value: val.to_string(),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if name == "style" {
|
|
||||||
element.flush_style_attribute(&self.doc.guard);
|
|
||||||
}
|
|
||||||
|
|
||||||
if name == "src" && !val.is_empty() {
|
|
||||||
element.node_specific_data = NodeSpecificData::None;
|
|
||||||
queued_image = Some(val.to_string());
|
|
||||||
}
|
|
||||||
|
|
||||||
if element.name.local == local_name!("link")
|
|
||||||
&& name == "href"
|
|
||||||
&& !val.is_empty()
|
|
||||||
{
|
|
||||||
queued_stylesheet = Some(val.to_string());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if let AttributeValue::None = value {
|
|
||||||
// Update text input value
|
|
||||||
if name == "value" {
|
|
||||||
if let Some(input_data) = element.text_input_data_mut() {
|
|
||||||
input_data.set_text(
|
|
||||||
&mut self.doc.font_ctx,
|
|
||||||
&mut self.doc.layout_ctx,
|
|
||||||
"",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME: check namespace
|
|
||||||
element.attrs.retain(|attr| attr.name.local != *name);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(queued_image) = queued_image {
|
let name = qual_name(local_name, ns);
|
||||||
crate::assets::fetch_image(self.doc, node_id, queued_image);
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(queued_stylesheet) = queued_stylesheet {
|
// FIXME: more principled handling of special case attributes
|
||||||
crate::assets::fetch_linked_stylesheet(self.doc, node_id, queued_stylesheet);
|
if value == &AttributeValue::None || (local_name == "checked" && is_falsy(value)) {
|
||||||
|
self.docm.clear_attribute(node_id, name);
|
||||||
|
} else {
|
||||||
|
match value {
|
||||||
|
AttributeValue::Text(value) => self.docm.set_attribute(node_id, name, value),
|
||||||
|
AttributeValue::Float(value) => {
|
||||||
|
let value = value.to_string();
|
||||||
|
self.docm.set_attribute(node_id, name, &value);
|
||||||
|
}
|
||||||
|
AttributeValue::Int(value) => {
|
||||||
|
let value = value.to_string();
|
||||||
|
self.docm.set_attribute(node_id, name, &value);
|
||||||
|
}
|
||||||
|
AttributeValue::Bool(value) => {
|
||||||
|
let value = value.to_string();
|
||||||
|
self.docm.set_attribute(node_id, name, &value);
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
// FIXME: support all attribute types
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_node_text(&mut self, value: &str, id: ElementId) {
|
fn load_template(&mut self, template: Template, index: usize, id: ElementId) {
|
||||||
#[cfg(feature = "tracing")]
|
// TODO: proper template node support
|
||||||
tracing::info!("set_node_text id:{} value:{}", id.0, value);
|
let template_entry = self.state.templates.entry(template).or_insert_with(|| {
|
||||||
|
let template_root_ids: Vec<NodeId> = template
|
||||||
|
.roots
|
||||||
|
.iter()
|
||||||
|
.map(|root| create_template_node(&mut self.docm, root))
|
||||||
|
.collect();
|
||||||
|
|
||||||
let node_id = self.state.element_to_node_id(id);
|
template_root_ids
|
||||||
let node = self.doc.get_node_mut(node_id).unwrap();
|
});
|
||||||
|
|
||||||
let text = match node.data {
|
let template_node_id = template_entry[index];
|
||||||
NodeData::Text(ref mut text) => text,
|
let clone_id = self.docm.deep_clone_node(template_node_id);
|
||||||
// todo: otherwise this is basically element.textContent which is a bit different - need to parse as html
|
|
||||||
_ => return,
|
|
||||||
};
|
|
||||||
|
|
||||||
let changed = text.content != value;
|
trace!("load_template template_node_id:{template_node_id} clone_id:{clone_id}");
|
||||||
if changed {
|
self.map_new_node(clone_id, id);
|
||||||
text.content.clear();
|
|
||||||
text.content.push_str(value);
|
|
||||||
let parent = node.parent;
|
|
||||||
self.maybe_push_style_node(parent);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_event_listener(&mut self, _name: &'static str, _id: ElementId) {
|
fn create_event_listener(&mut self, name: &'static str, id: ElementId) {
|
||||||
// we're going to actually set the listener here as a placeholder - in JS this would also be a placeholder
|
// 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)
|
// we might actually just want to attach the attribute to the root element (delegation)
|
||||||
self.set_attribute(
|
let value = AttributeValue::Text("<rust func>".into());
|
||||||
_name,
|
self.set_attribute(name, None, &value, id);
|
||||||
None,
|
|
||||||
&AttributeValue::Text("<rust func>".into()),
|
|
||||||
_id,
|
|
||||||
);
|
|
||||||
|
|
||||||
// also set the data-dioxus-id attribute so we can find the element later
|
// Also set the data-dioxus-id attribute so we can find the element later
|
||||||
self.set_attribute(
|
let value = AttributeValue::Text(id.0.to_string());
|
||||||
"data-dioxus-id",
|
self.set_attribute("data-dioxus-id", None, &value, id);
|
||||||
None,
|
|
||||||
&AttributeValue::Text(_id.0.to_string()),
|
|
||||||
_id,
|
|
||||||
);
|
|
||||||
|
|
||||||
// let node_id = self.state.element_to_node_id(id);
|
|
||||||
// let mut node = self.rdom.get_mut(node_id).unwrap();
|
|
||||||
// node.add_event_listener(name);
|
// node.add_event_listener(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn remove_event_listener(&mut self, _name: &'static str, _id: ElementId) {
|
fn remove_event_listener(&mut self, _name: &'static str, _id: ElementId) {
|
||||||
// let node_id = self.state.element_to_node_id(id);
|
|
||||||
// let mut node = self.rdom.get_mut(node_id).unwrap();
|
|
||||||
// node.remove_event_listener(name);
|
// node.remove_event_listener(name);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn remove_node(&mut self, id: ElementId) {
|
fn create_template_node(docm: &mut DocumentMutator<'_>, node: &TemplateNode) -> NodeId {
|
||||||
#[cfg(feature = "tracing")]
|
match node {
|
||||||
tracing::info!("remove_node id:{}", id.0);
|
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, attrs);
|
||||||
|
|
||||||
let node_id = self.state.element_to_node_id(id);
|
let child_ids: Vec<NodeId> = children
|
||||||
self.doc.remove_node(node_id);
|
.iter()
|
||||||
}
|
.map(|child| create_template_node(docm, child))
|
||||||
|
.collect();
|
||||||
|
|
||||||
fn push_root(&mut self, id: ElementId) {
|
docm.append_children(node_id, &child_ids);
|
||||||
#[cfg(feature = "tracing")]
|
|
||||||
tracing::info!("push_root id:{}", id.0,);
|
|
||||||
|
|
||||||
let node_id = self.state.element_to_node_id(id);
|
node_id
|
||||||
self.state.stack.push(node_id);
|
}
|
||||||
|
TemplateNode::Text { text } => docm.create_text_node(text),
|
||||||
|
TemplateNode::Dynamic { .. } => docm.create_comment_node(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set 'checked' state on an input based on given attributevalue
|
fn map_template_attr(attr: &TemplateAttribute) -> Option<Attribute> {
|
||||||
fn set_input_checked_state(element: &mut ElementNodeData, value: &AttributeValue) {
|
let TemplateAttribute::Static {
|
||||||
let checked: bool;
|
name,
|
||||||
match value {
|
value,
|
||||||
AttributeValue::Bool(checked_bool) => {
|
namespace,
|
||||||
checked = *checked_bool;
|
} = attr
|
||||||
}
|
else {
|
||||||
AttributeValue::Text(val) => {
|
return None;
|
||||||
if let Ok(checked_bool) = val.parse() {
|
|
||||||
checked = checked_bool;
|
|
||||||
} else {
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
match element.node_specific_data {
|
|
||||||
NodeSpecificData::CheckboxInput(ref mut checked_mut) => *checked_mut = checked,
|
|
||||||
// If we have just constructed the element, set the node attribute,
|
|
||||||
// and NodeSpecificData will be created from that later
|
|
||||||
// this simulates the checked attribute being set in html,
|
|
||||||
// and the element's checked property being set from that
|
|
||||||
NodeSpecificData::None => element.attrs.push(Attribute {
|
|
||||||
name: QualName {
|
|
||||||
prefix: None,
|
|
||||||
ns: ns!(html),
|
|
||||||
local: local_name!("checked"),
|
|
||||||
},
|
|
||||||
value: checked.to_string(),
|
|
||||||
}),
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "autofocus")]
|
let name = qual_name(name, *namespace);
|
||||||
fn autofocus_node_recursive(
|
let value = value.to_string();
|
||||||
doc: &BaseDocument,
|
Some(Attribute { name, value })
|
||||||
node_to_autofocus: &mut Option<usize>,
|
|
||||||
node_id: usize,
|
|
||||||
) {
|
|
||||||
if let Some(node) = doc.get_node(node_id) {
|
|
||||||
if node.is_focussable() {
|
|
||||||
if let NodeData::Element(ref element) = node.data {
|
|
||||||
if let Some(value) = element.attr(local_name!("autofocus")) {
|
|
||||||
if value == "true" {
|
|
||||||
*node_to_autofocus = Some(node_id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for child_node_id in &node.children {
|
|
||||||
autofocus_node_recursive(doc, node_to_autofocus, *child_node_id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user