diff --git a/Cargo.lock b/Cargo.lock index 4ec71bc5c..4dbc1ff42 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2790,9 +2790,9 @@ dependencies = [ [[package]] name = "blitz-dom" -version = "0.1.0-rc.2" +version = "0.1.0-rc.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "145a503f45b2284a75ca1e715dbbef4d1ccf1eeace85330e29a2ae12a01d1263" +checksum = "214e9e87e3eccaea98ae35eb6a9e0451048ef1b6175c99500b23a331c1a941b8" dependencies = [ "accesskit 0.17.1", "app_units", @@ -2800,7 +2800,9 @@ dependencies = [ "bitflags 2.9.1", "blitz-traits", "color", + "cssparser 0.35.0", "cursor-icon", + "debug_timer", "euclid", "fastrand", "html-escape", @@ -2811,7 +2813,7 @@ dependencies = [ "parley", "peniko", "percent-encoding", - "selectors 0.29.0", + "selectors 0.31.0", "slab", "smallvec", "stylo", @@ -2819,7 +2821,7 @@ dependencies = [ "stylo_dom", "stylo_taffy", "stylo_traits", - "taffy 0.8.3", + "taffy 0.9.0", "tracing", "url", "usvg", @@ -2827,10 +2829,22 @@ dependencies = [ ] [[package]] -name = "blitz-net" -version = "0.1.0-rc.2" +name = "blitz-html" +version = "0.1.0-rc.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2a5ebc8993e3985097716262d4d496c18d3324727109e3c865071776dfe38b1" +checksum = "28a627d02a71432bffcf4cdc6100f138e9b8dc7d62f132a27ef9678f3c80223d" +dependencies = [ + "blitz-dom", + "blitz-traits", + "html5ever 0.35.0", + "xml5ever", +] + +[[package]] +name = "blitz-net" +version = "0.1.0-rc.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24ed18ece8779731ec9a1e453194ac133885c48b2bcfb1d70e4054b27a4574f8" dependencies = [ "blitz-traits", "data-url 0.3.1", @@ -2840,9 +2854,9 @@ dependencies = [ [[package]] name = "blitz-paint" -version = "0.1.0-rc.2" +version = "0.1.0-rc.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d62c7953382622298402412535db1796aaa83c71600bfc77fa7627a39aa722d" +checksum = "3756d12f7c3781cfccfdf4a18366a93e5ddbd60216785aae178296340ee76918" dependencies = [ "anyrender", "anyrender_svg", @@ -2854,16 +2868,16 @@ dependencies = [ "parley", "peniko", "stylo", - "taffy 0.8.3", + "taffy 0.9.0", "tracing", "usvg", ] [[package]] name = "blitz-shell" -version = "0.1.0-rc.2" +version = "0.1.0-rc.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "347af5abefe16205d61a49101aeedeb9b4dafe4bb0c64858b267e448cfa0a471" +checksum = "53fe4abf8326d54d31e5be846d5177a8e9dc11392fadead4653dfd8f0ac4dd70" dependencies = [ "accesskit 0.17.1", "accesskit_winit 0.23.1", @@ -2880,9 +2894,9 @@ dependencies = [ [[package]] name = "blitz-traits" -version = "0.1.0-rc.2" +version = "0.1.0-rc.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cb0235930120526087ce9d69fa2d6828e3fb078c61dde43231acec7968376bf" +checksum = "4021acefe0ac35c70aef3f06481bb3f8c1049f61dec1fff09a98abe07fb4c463" dependencies = [ "bitflags 2.9.1", "bytes", @@ -4779,6 +4793,12 @@ dependencies = [ "tokio", ] +[[package]] +name = "debug_timer" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd6283985164a993d14300c81746aa6db2d889ed9fbb573fa20b40737c3a972c" + [[package]] name = "debugid" version = "0.8.0" @@ -5679,6 +5699,7 @@ dependencies = [ "anyrender", "anyrender_vello", "blitz-dom", + "blitz-html", "blitz-net", "blitz-paint", "blitz-shell", @@ -8179,9 +8200,9 @@ checksum = "36119f3a540b086b4e436bb2b588cf98a68863470e0e880f4d0842f112a3183a" [[package]] name = "grid" -version = "0.17.0" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71b01d27060ad58be4663b9e4ac9e2d4806918e8876af8912afbddd1a91d5eaa" +checksum = "12101ecc8225ea6d675bc70263074eab6169079621c2186fe0c66590b2df9681" [[package]] name = "group" @@ -8546,7 +8567,18 @@ dependencies = [ "log", "mac", "markup5ever 0.14.1", - "match_token", + "match_token 0.1.0", +] + +[[package]] +name = "html5ever" +version = "0.35.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55d958c2f74b664487a2035fe1dadb032c48718a03b63f3ab0b8537db8549ed4" +dependencies = [ + "log", + "markup5ever 0.35.0", + "match_token 0.35.0", ] [[package]] @@ -9741,7 +9773,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "02cb977175687f33fa4afa0c95c112b987ea1443e5a51c8f8ff27dc618270cc2" dependencies = [ "cssparser 0.29.6", - "html5ever", + "html5ever 0.29.1", "indexmap 2.10.0", "selectors 0.24.0", ] @@ -10356,6 +10388,17 @@ dependencies = [ "syn 2.0.104", ] +[[package]] +name = "match_token" +version = "0.35.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac84fd3f360fcc43dc5f5d186f02a94192761a080e8bc58621ad4d12296a58cf" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", +] + [[package]] name = "matchers" version = "0.1.0" @@ -14152,9 +14195,9 @@ dependencies = [ [[package]] name = "selectors" -version = "0.29.0" +version = "0.31.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d61a96a0a2d04f964888e003ec83e3172159a16e81b35de9f6ab85d8767cf2b1" +checksum = "5685b6ae43bfcf7d2e7dfcfb5d8e8f61b46442c902531e41a32a9a8bf0ee0fb6" dependencies = [ "bitflags 2.9.1", "cssparser 0.35.0", @@ -15367,9 +15410,9 @@ dependencies = [ [[package]] name = "stylo" -version = "0.4.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1cdb2ebcdd49e8e2524d3045202eb472c4261bb9956294fd52ccc1200b8e0af" +checksum = "2c0e43d53a35821d4a1d0a222f830d4be1b3b9e1711037e176e112aa32006827" dependencies = [ "app_units", "arrayvec", @@ -15399,7 +15442,7 @@ dependencies = [ "precomputed-hash", "rayon", "rayon-core", - "selectors 0.29.0", + "selectors 0.31.0", "serde", "servo_arc 0.4.1", "smallbitvec", @@ -15425,9 +15468,9 @@ dependencies = [ [[package]] name = "stylo_atoms" -version = "0.4.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a2e2d0a6532ae003a87e9a44d35e74175af06cbba191ba80947ba8e9ea369b3" +checksum = "94847461aae1c005d9d5c1fa46243fe7132b709cfdee5d34fa5e636afa146163" dependencies = [ "string_cache", "string_cache_codegen", @@ -15435,15 +15478,15 @@ dependencies = [ [[package]] name = "stylo_config" -version = "0.4.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a308fdc37610b1b9c6dbce4244a91f7bdf88bf8a13ccfbc50c212e09b29bc7d" +checksum = "4299e2bde00c3adede2698e647dcfcad9f4402252ef66be6ea2d781b4ec32816" [[package]] name = "stylo_derive" -version = "0.4.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8384a2ebb61abbde4466dfc9d5dcda134dfa939b77bfb2df878d1c7dffe081f1" +checksum = "0f252798e25b50eef5caff400fc39028e156ffbed74b4e3fd22e28aff10ed28f" dependencies = [ "darling", "proc-macro2", @@ -15454,9 +15497,9 @@ dependencies = [ [[package]] name = "stylo_dom" -version = "0.4.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6bce5a8c7b6d5657952caeeec50213d356d1ca2f2b042cf4594a897701282e9" +checksum = "f0e0c1bf4e21bc6c921b7b07e2ab1cd6e92bf9f9453f333a14000942f304b20b" dependencies = [ "bitflags 2.9.1", "stylo_malloc_size_of", @@ -15464,14 +15507,14 @@ dependencies = [ [[package]] name = "stylo_malloc_size_of" -version = "0.4.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc88bd0d890c656478a8bfaab59e0e25d405149ef1117917d792540ab75b47cc" +checksum = "91df5c23c5d3b0fb3e1b11c4b98c6a4b769678055a376954945c2fb20e7438cf" dependencies = [ "app_units", "cssparser 0.35.0", "euclid", - "selectors 0.29.0", + "selectors 0.31.0", "servo_arc 0.4.1", "smallbitvec", "smallvec", @@ -15482,32 +15525,33 @@ dependencies = [ [[package]] name = "stylo_static_prefs" -version = "0.4.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "500f379645e8a87fd03fe88607a5edcb0d8e4e423baa74ba52db198a06a0c261" +checksum = "62601d73eb8743eaed1f227bde2374f672ae8de7db1fedcbe5aca055e3de566b" [[package]] name = "stylo_taffy" -version = "0.1.0-rc.2" +version = "0.1.0-rc.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dce8876a33e0f3b16916b2b4da1cdbb64b9985d5ae61033d23024d95e45569ac" +checksum = "90b50aae96a5ef64f675eddc26adc60945748588519926d32077804004a48d9d" dependencies = [ "stylo", - "taffy 0.8.3", + "stylo_atoms", + "taffy 0.9.0", ] [[package]] name = "stylo_traits" -version = "0.4.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "244bfd473f321ff0258f5b2986e218d5f72507fa405fd131b8dbb5ebac166663" +checksum = "d000ad3fad6a3c0327beeb9b93ddcff7a38f2d8c2910f9a3107b219926fea300" dependencies = [ "app_units", "bitflags 2.9.1", "cssparser 0.35.0", "euclid", "malloc_size_of_derive", - "selectors 0.29.0", + "selectors 0.31.0", "serde", "servo_arc 0.4.1", "stylo_atoms", @@ -16225,12 +16269,12 @@ dependencies = [ [[package]] name = "taffy" -version = "0.8.3" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7aaef0ac998e6527d6d0d5582f7e43953bb17221ac75bb8eb2fcc2db3396db1c" +checksum = "a13e5d13f79d558b5d353a98072ca8ca0e99da429467804de959aa8c83c9a004" dependencies = [ "arrayvec", - "grid 0.17.0", + "grid 0.18.0", "serde", "slotmap", ] @@ -19362,7 +19406,7 @@ dependencies = [ "dpi", "dunce", "gtk", - "html5ever", + "html5ever 0.29.1", "http 1.3.1", "javascriptcore-rs", "jni 0.21.1", @@ -19545,6 +19589,16 @@ version = "0.8.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6fd8403733700263c6eb89f192880191f1b83e332f7a20371ddcf421c4a337c7" +[[package]] +name = "xml5ever" +version = "0.35.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee3f1e41afb31a75aef076563b0ad3ecc24f5bd9d12a72b132222664eb76b494" +dependencies = [ + "log", + "markup5ever 0.35.0", +] + [[package]] name = "xmlwriter" version = "0.1.0" diff --git a/Cargo.toml b/Cargo.toml index 2fcece372..9d5ef916a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -213,11 +213,12 @@ depinfo = { path = "packages/depinfo", version = "0.7.0-rc.0" } warnings = { version = "0.2.1" } # blitz -blitz-dom = { version = "=0.1.0-rc.2", default-features = false } -blitz-net = { version = "=0.1.0-rc.2" } -blitz-paint = { version = "=0.1.0-rc.2" } -blitz-traits = { version = "=0.1.0-rc.2" } -blitz-shell = { version = "=0.1.0-rc.2", default-features = false } +blitz-dom = { version = "=0.1.0-rc.3", default-features = false } +blitz-net = { version = "=0.1.0-rc.3" } +blitz-html = { version = "=0.1.0-rc.3" } +blitz-paint = { version = "=0.1.0-rc.3" } +blitz-traits = { version = "=0.1.0-rc.3" } +blitz-shell = { version = "=0.1.0-rc.3", default-features = false } anyrender = { version = "0.5", default-features = false } anyrender_vello = { version = "0.5", default-features = false } wgpu = { version = "24.0" } diff --git a/examples/rsx_usage.rs b/examples/rsx_usage.rs index 0e223d6e8..12dc7cbfc 100644 --- a/examples/rsx_usage.rs +++ b/examples/rsx_usage.rs @@ -77,6 +77,27 @@ fn app() -> Element { class: "my special div", h1 {"Headers and attributes!"} } + div { + h1 {"Style attributes!"} + p { + "hello" + b { + "world" + } + i { + "foo" + } + span { + style: "color: red;font-style:italic", + "red" + } + span { + color: "blue", + font_weight: "bold", + "attr_blue" + } + } + } div { // pass simple rust expressions in class: "{lazy_fmt}", diff --git a/packages/native-dom/src/mutation_writer.rs b/packages/native-dom/src/mutation_writer.rs index b61033770..104df09d4 100644 --- a/packages/native-dom/src/mutation_writer.rs +++ b/packages/native-dom/src/mutation_writer.rs @@ -1,6 +1,6 @@ //! Integration between Dioxus and Blitz use crate::{qual_name, trace, NodeId}; -use blitz_dom::{Attribute, BaseDocument, DocumentMutator}; +use blitz_dom::{BaseDocument, DocumentMutator}; use blitz_traits::events::DomEventKind; use dioxus_core::{ AttributeValue, ElementId, Template, TemplateAttribute, TemplateNode, WriteMutations, @@ -183,14 +183,6 @@ impl WriteMutations for MutationWriter<'_> { id: ElementId, ) { let node_id = self.state.element_to_node_id(id); - trace!("set_attribute node_id:{node_id} ns: {ns:?} name:{local_name}, value:{value:?}"); - - // Dioxus has overloaded the style namespace to accumulate style attributes without a `style` block - // TODO: accumulate style attributes into a single style element. - if ns == Some("style") { - return; - } - fn is_falsy(val: &AttributeValue) -> bool { match val { AttributeValue::None => true, @@ -202,31 +194,30 @@ impl WriteMutations for MutationWriter<'_> { } } - let name = qual_name(local_name, ns); - - // FIXME: more principled handling of special case attributes - 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 - } - }; - } + let falsy = is_falsy(value); + match value { + AttributeValue::None => { + set_attribute_inner(&mut self.docm, local_name, ns, None, falsy, node_id) + } + AttributeValue::Text(value) => { + set_attribute_inner(&mut self.docm, local_name, ns, Some(value), falsy, node_id) + } + AttributeValue::Float(value) => { + let value = value.to_string(); + set_attribute_inner(&mut self.docm, local_name, ns, Some(&value), falsy, node_id); + } + AttributeValue::Int(value) => { + let value = value.to_string(); + set_attribute_inner(&mut self.docm, local_name, ns, Some(&value), falsy, node_id); + } + AttributeValue::Bool(value) => { + let value = value.to_string(); + set_attribute_inner(&mut self.docm, local_name, ns, Some(&value), falsy, node_id); + } + _ => { + // FIXME: support all attribute types + } + }; } fn load_template(&mut self, template: Template, index: usize, id: ElementId) { @@ -283,8 +274,21 @@ fn create_template_node(docm: &mut DocumentMutator<'_>, node: &TemplateNode) -> 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 attrs = attrs.iter().filter_map(map_template_attr).collect(); + let node_id = docm.create_element(name, Vec::new()); + + for attr in attrs.iter() { + let TemplateAttribute::Static { + name, + value, + namespace, + } = attr + else { + continue; + }; + let falsy = *value == "false"; + set_attribute_inner(docm, name, *namespace, Some(value), falsy, node_id); + } let child_ids: Vec = children .iter() @@ -300,17 +304,39 @@ fn create_template_node(docm: &mut DocumentMutator<'_>, node: &TemplateNode) -> } } -fn map_template_attr(attr: &TemplateAttribute) -> Option { - let TemplateAttribute::Static { - name, - value, - namespace, - } = attr - else { - return None; - }; +fn set_attribute_inner( + docm: &mut DocumentMutator<'_>, + local_name: &'static str, + ns: Option<&'static str>, + value: Option<&str>, + is_falsy: bool, + node_id: usize, +) { + trace!("set_attribute node_id:{node_id} ns: {ns:?} name:{local_name}, value:{value:?}"); - let name = qual_name(name, *namespace); - let value = value.to_string(); - Some(Attribute { name, value }) + // Dioxus has overloaded the style namespace to accumulate style attributes without a `style` block + // TODO: accumulate style attributes into a single style element. + if ns == Some("style") { + match value { + Some(value) => docm.set_style_property(node_id, local_name, value), + None => docm.remove_style_property(node_id, local_name), + } + return; + } + + let name = qual_name(local_name, ns); + + // FIXME: more principled handling of special case attributes + match value { + None => docm.clear_attribute(node_id, name), + Some(value) => { + if local_name == "checked" && is_falsy { + docm.clear_attribute(node_id, name); + } else if local_name == "dangerous_inner_html" { + docm.set_inner_html(node_id, value); + } else { + docm.set_attribute(node_id, name, value); + } + } + } } diff --git a/packages/native/Cargo.toml b/packages/native/Cargo.toml index 9cd95b4ef..eabc0ff82 100644 --- a/packages/native/Cargo.toml +++ b/packages/native/Cargo.toml @@ -10,9 +10,10 @@ homepage = "https://dioxuslabs.com/learn/0.6/getting_started" keywords = ["dom", "ui", "gui", "react"] [features] -default = ["accessibility", "hot-reload", "tracing", "net", "svg", "system-fonts"] +default = ["accessibility", "hot-reload", "tracing", "net", "html", "svg", "system-fonts"] svg = ["blitz-dom/svg", "blitz-paint/svg"] net = ["dep:tokio", "dep:blitz-net"] +html = ["dep:blitz-html"] accessibility = ["blitz-shell/accessibility", "blitz-dom/accessibility"] tracing = ["dep:tracing", "blitz-shell/tracing", "blitz-dom/tracing"] hot-reload = ["dep:dioxus-cli-config", "dep:dioxus-devtools"] @@ -24,6 +25,7 @@ autofocus = [] anyrender = { workspace = true } anyrender_vello = { workspace = true } blitz-dom = { workspace = true } +blitz-html = { workspace = true, optional = true } blitz-net = { workspace = true, optional = true } blitz-paint = { workspace = true, optional = true } blitz-traits = { workspace = true } diff --git a/packages/native/src/lib.rs b/packages/native/src/lib.rs index 2bad1c483..a1f319b53 100644 --- a/packages/native/src/lib.rs +++ b/packages/native/src/lib.rs @@ -119,15 +119,20 @@ pub fn launch_cfg_with_props( let net_provider = DioxusNativeNetProvider::shared(proxy); Some(net_provider) }; - #[cfg(not(feature = "net"))] let net_provider = None; + #[cfg(feature = "html")] + let html_parser_provider = Some(std::sync::Arc::new(blitz_html::HtmlProvider) as _); + #[cfg(not(feature = "html"))] + let html_parser_provider = None; + // Create document + window from the baked virtualdom let doc = DioxusDocument::new( vdom, DocumentConfig { net_provider, + html_parser_provider, ..Default::default() }, );