From 26f5b0363c76582643c16f4bf1add6d8f42213dc Mon Sep 17 00:00:00 2001 From: Philipp Mildenberger Date: Sun, 5 Nov 2023 07:55:52 +0100 Subject: [PATCH] Fix `Fill` (use new helper context functions) and some smaller fixes --- crates/xilem_html/src/lib.rs | 2 +- crates/xilem_html/src/svg/common_attrs.rs | 59 ++++++++++------------- crates/xilem_html/src/svg/pointer.rs | 4 +- 3 files changed, 27 insertions(+), 38 deletions(-) diff --git a/crates/xilem_html/src/lib.rs b/crates/xilem_html/src/lib.rs index 2fdb8ec80..30295e37c 100644 --- a/crates/xilem_html/src/lib.rs +++ b/crates/xilem_html/src/lib.rs @@ -11,13 +11,13 @@ mod app; mod attribute; mod attribute_value; mod context; -pub mod svg; mod diff; pub mod elements; pub mod events; pub mod interfaces; mod one_of; mod optional_action; +pub mod svg; mod vecmap; mod view; mod view_ext; diff --git a/crates/xilem_html/src/svg/common_attrs.rs b/crates/xilem_html/src/svg/common_attrs.rs index 47d45bfb2..b40771cbb 100644 --- a/crates/xilem_html/src/svg/common_attrs.rs +++ b/crates/xilem_html/src/svg/common_attrs.rs @@ -5,13 +5,12 @@ use std::borrow::Cow; use std::{any::Any, marker::PhantomData}; use peniko::Brush; -use wasm_bindgen::JsCast; use xilem_core::{Id, MessageResult}; use crate::IntoAttributeValue; use crate::{ context::{ChangeFlags, Cx}, - view::{DomNode, View, ViewMarker}, + view::{View, ViewMarker}, }; pub struct Fill { @@ -63,18 +62,14 @@ fn brush_to_string(brush: &Brush) -> String { } } -macro_rules! impl_dom_interface_for_ty { - ($dom_interface:ident, $ty:ident) => { - impl> - $crate::interfaces::$dom_interface for $ty - { - } - }; -} - macro_rules! impl_dom_interfaces_for_ty { ($ty:ident: $($dom_interface:ident,)*) => { - $(impl_dom_interface_for_ty!($dom_interface, $ty);)* + $( + impl> + $crate::interfaces::$dom_interface for $ty + { + } + )* } } @@ -95,18 +90,17 @@ impl crate::interfaces::sealed::Sealed for Fill {} // TODO: make generic over A (probably requires Phantom) impl> View for Fill { - type State = V::State; + type State = (Cow<'static, str>, V::State); type Element = V::Element; fn build(&self, cx: &mut Cx) -> (Id, Self::State, Self::Element) { + let brush_svg_repr = Cow::from(brush_to_string(&self.brush)); + cx.add_new_attribute_to_current_element( + &"fill".into(), + &brush_svg_repr.clone().into_attribute_value(), + ); let (id, child_state, element) = self.child.build(cx); - element - .as_node_ref() - .dyn_ref::() - .unwrap() - .set_attribute("fill", &brush_to_string(&self.brush)) - .unwrap(); - (id, child_state, element) + (id, (brush_svg_repr, child_state), element) } fn rebuild( @@ -114,31 +108,28 @@ impl> View for Fill { cx: &mut Cx, prev: &Self, id: &mut Id, - state: &mut Self::State, + (brush_svg_repr, child_state): &mut Self::State, element: &mut V::Element, ) -> ChangeFlags { - let prev_id = *id; - let mut changed = self.child.rebuild(cx, &prev.child, id, state, element); - if self.brush != prev.brush || prev_id != *id { - element - .as_node_ref() - .dyn_ref::() - .unwrap() - .set_attribute("fill", &brush_to_string(&self.brush)) - .unwrap(); - changed.insert(ChangeFlags::OTHER_CHANGE); + if self.brush != prev.brush { + *brush_svg_repr = Cow::from(brush_to_string(&self.brush)); } - changed + cx.add_new_attribute_to_current_element( + &"fill".into(), + &brush_svg_repr.clone().into_attribute_value(), + ); + self.child + .rebuild(cx, &prev.child, id, child_state, element) } fn message( &self, id_path: &[Id], - state: &mut Self::State, + (_, child_state): &mut Self::State, message: Box, app_state: &mut T, ) -> MessageResult { - self.child.message(id_path, state, message, app_state) + self.child.message(id_path, child_state, message, app_state) } } diff --git a/crates/xilem_html/src/svg/pointer.rs b/crates/xilem_html/src/svg/pointer.rs index 6921dafda..8c67d5e64 100644 --- a/crates/xilem_html/src/svg/pointer.rs +++ b/crates/xilem_html/src/svg/pointer.rs @@ -139,9 +139,7 @@ impl A + Send, V: View> View app_state: &mut T, ) -> MessageResult { match message.downcast() { - Ok(msg) => { - MessageResult::Action((self.callback)(app_state, *msg)) - } + Ok(msg) => MessageResult::Action((self.callback)(app_state, *msg)), Err(message) => self .child .message(id_path, &mut state.child_state, message, app_state),