public inbox for yew-devel@lists.proxmox.com
 help / color / mirror / Atom feed
* [yew-devel] [PATCH yew-widget-toolkit 1/2] dom: add convenience functions to get often used elements
@ 2025-05-02 12:49 Dominik Csapak
  2025-05-02 12:49 ` [yew-devel] [PATCH yew-widget-toolkit 2/2] tree wide: use get_window/document/body Dominik Csapak
  2025-05-05  8:13 ` [yew-devel] [PATCH yew-widget-toolkit 1/2] dom: add convenience functions to get often used elements Dietmar Maurer
  0 siblings, 2 replies; 5+ messages in thread
From: Dominik Csapak @ 2025-05-02 12:49 UTC (permalink / raw)
  To: yew-devel

Namely window/document/body. We use them throughout our codebase with
inline unwraps, instead we can use these helpers instead.

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
---
 src/dom/mod.rs | 20 +++++++++++++++++++-
 1 file changed, 19 insertions(+), 1 deletion(-)

diff --git a/src/dom/mod.rs b/src/dom/mod.rs
index f61dd21..679fab7 100644
--- a/src/dom/mod.rs
+++ b/src/dom/mod.rs
@@ -13,7 +13,7 @@ pub use dom_size_observer::{DomSizeObserver, IntoSizeCallback, SizeCallback};
 mod dom_visibility_observer;
 pub use dom_visibility_observer::DomVisibilityObserver;
 
-use web_sys::Node;
+use web_sys::{window, Document, HtmlElement, Node, Window};
 use yew::prelude::*;
 
 /// A Trait to convert structs into HtmlElement when possible
@@ -77,3 +77,21 @@ pub fn get_system_prefer_dark_mode() -> bool {
         false
     }
 }
+
+/// Convenience function to get the [`Window`] object.
+/// Panics if not in a browser context
+pub fn get_window() -> Window {
+    window().unwrap()
+}
+
+/// Convenience function to get the [`Document`] object.
+/// Panics if not in a browser context
+pub fn get_document() -> Document {
+    get_window().document().unwrap()
+}
+
+/// Convenience function to get the a reference to the <body> tag as [`HtmlElement`].
+/// Panics if not in a browser context
+pub fn get_body() -> HtmlElement {
+    get_document().body().unwrap()
+}
-- 
2.39.5



_______________________________________________
yew-devel mailing list
yew-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/yew-devel


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [yew-devel] [PATCH yew-widget-toolkit 2/2] tree wide: use get_window/document/body
  2025-05-02 12:49 [yew-devel] [PATCH yew-widget-toolkit 1/2] dom: add convenience functions to get often used elements Dominik Csapak
@ 2025-05-02 12:49 ` Dominik Csapak
  2025-05-05  8:13 ` [yew-devel] [PATCH yew-widget-toolkit 1/2] dom: add convenience functions to get often used elements Dietmar Maurer
  1 sibling, 0 replies; 5+ messages in thread
From: Dominik Csapak @ 2025-05-02 12:49 UTC (permalink / raw)
  To: yew-devel

instead of unwrapping it everytime inline.

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
---
 src/dom/align.rs                          |  4 ++--
 src/dom/focus.rs                          | 26 ++++++---------------
 src/dom/mod.rs                            |  6 ++---
 src/state/theme.rs                        | 13 ++++-------
 src/touch/side_dialog.rs                  |  6 ++---
 src/widget/data_table/data_table.rs       | 10 +++-----
 src/widget/data_table/header_widget.rs    |  6 ++---
 src/widget/data_table/resizable_header.rs |  4 ++--
 src/widget/dialog.rs                      | 28 ++++++++++-------------
 src/widget/form/managed_field.rs          |  7 ++----
 src/widget/menu/mod.rs                    |  6 ++---
 src/widget/rtl_switcher.rs                | 11 +++++----
 src/widget/split_pane.rs                  |  4 ++--
 src/widget/theme_loader.rs                |  7 ++----
 14 files changed, 50 insertions(+), 88 deletions(-)

diff --git a/src/dom/align.rs b/src/dom/align.rs
index 6d7450a..12a2625 100644
--- a/src/dom/align.rs
+++ b/src/dom/align.rs
@@ -6,7 +6,7 @@
 use js_sys::Error;
 use web_sys::{window, HtmlElement};
 
-use crate::dom::{element_direction_rtl, DomSizeObserver, IntoHtmlElement};
+use crate::dom::{element_direction_rtl, get_window, DomSizeObserver, IntoHtmlElement};
 
 /// Defines a point on a rectangle
 ///
@@ -381,7 +381,7 @@ fn get_containing_block(element: &HtmlElement) -> Option<HtmlElement> {
             break;
         }
         if let Some(html) = node.into_html_element() {
-            if let Ok(Some(style)) = window().unwrap().get_computed_style(&html) {
+            if let Ok(Some(style)) = get_window().get_computed_style(&html) {
                 match style.get_property_value("transform") {
                     Ok(transform) if transform != "none" => return Some(html),
                     _ => {}
diff --git a/src/dom/focus.rs b/src/dom/focus.rs
index 101bab9..bf4a82d 100644
--- a/src/dom/focus.rs
+++ b/src/dom/focus.rs
@@ -7,6 +7,8 @@ use wasm_bindgen::JsCast;
 
 use yew::prelude::*;
 
+use crate::dom::get_document;
+
 const FOCUSABLE_SELECTOR: &str = "a:not([disabled]), button:not([disabled]), input[type=text]:not([disabled]), [tabindex]:not([disabled])";
 const FOCUSABLE_SELECTOR_ALL: &str = "a, button, input, [tabindex]";
 
@@ -49,10 +51,7 @@ pub fn focus_next_el(el: web_sys::HtmlElement, backwards: bool) {
             return;
         }
 
-        let window = web_sys::window().unwrap();
-        let document = window.document().unwrap();
-
-        let index = match document.active_element() {
+        let index = match get_document().active_element() {
             Some(active_element) => list.index_of(&active_element, 0),
             None => -1,
         };
@@ -108,9 +107,7 @@ pub fn roving_tabindex_next_el(el: web_sys::HtmlElement, backwards: bool, roving
     }
 
     fn get_active_index(list: &[web_sys::HtmlElement]) -> i32 {
-        let window = web_sys::window().unwrap();
-        let document = window.document().unwrap();
-        let active_el = document.active_element();
+        let active_el = get_document().active_element();
         let active_node: Option<&web_sys::Node> = active_el.as_deref();
 
         let mut index = 0;
@@ -157,10 +154,7 @@ pub fn focus_inside_el(el: web_sys::HtmlElement) -> bool {
             return false;
         }
 
-        let window = web_sys::window().unwrap();
-        let document = window.document().unwrap();
-
-        let index = match document.active_element() {
+        let index = match get_document().active_element() {
             Some(active_element) => list.index_of(&active_element, 0),
             None => -1,
         };
@@ -174,10 +168,7 @@ pub fn focus_inside_el(el: web_sys::HtmlElement) -> bool {
 ///
 /// This is the case if the focused element is an input, textarea or is marked as 'contenteditable'.
 pub fn focus_inside_input() -> bool {
-    let window = web_sys::window().unwrap();
-    let document = window.document().unwrap();
-
-    match document.active_element() {
+    match get_document().active_element() {
         Some(el) => match el.dyn_into::<web_sys::HtmlElement>() {
             Ok(el) => {
                 let tag = el.tag_name().to_lowercase();
@@ -204,10 +195,7 @@ pub fn update_roving_tabindex_el(el: web_sys::HtmlElement) {
             return;
         }
 
-        let window = web_sys::window().unwrap();
-        let document = window.document().unwrap();
-
-        let active_el = document.active_element();
+        let active_el = get_document().active_element();
         let active_node: Option<&web_sys::Node> = active_el.as_deref();
 
         let mut index = 0;
diff --git a/src/dom/mod.rs b/src/dom/mod.rs
index 679fab7..e76537b 100644
--- a/src/dom/mod.rs
+++ b/src/dom/mod.rs
@@ -58,8 +58,7 @@ impl IntoHtmlElement for web_sys::HtmlElement {
 pub fn element_direction_rtl<T: IntoHtmlElement>(node: T) -> Option<bool> {
     let el = node.into_html_element()?;
 
-    let window = web_sys::window().unwrap();
-    if let Ok(Some(style)) = window.get_computed_style(&el) {
+    if let Ok(Some(style)) = get_window().get_computed_style(&el) {
         if let Ok(direction) = style.get_property_value("direction") {
             return Some(direction == "rtl");
         }
@@ -70,8 +69,7 @@ pub fn element_direction_rtl<T: IntoHtmlElement>(node: T) -> Option<bool> {
 
 /// Returns if the system prefers dark mode
 pub fn get_system_prefer_dark_mode() -> bool {
-    let window = web_sys::window().unwrap();
-    if let Ok(Some(list)) = window.match_media("(prefers-color-scheme: dark)") {
+    if let Ok(Some(list)) = get_window().match_media("(prefers-color-scheme: dark)") {
         list.matches()
     } else {
         false
diff --git a/src/state/theme.rs b/src/state/theme.rs
index 0b6b65f..c3b298e 100644
--- a/src/state/theme.rs
+++ b/src/state/theme.rs
@@ -9,7 +9,7 @@ use web_sys::MediaQueryList;
 
 use yew::prelude::*;
 
-use crate::dom::get_system_prefer_dark_mode;
+use crate::dom::{get_document, get_system_prefer_dark_mode, get_window};
 use crate::state::local_storage;
 
 /// Theme mode - dark, light or auto (use system settings).
@@ -276,8 +276,7 @@ impl ThemeObserver {
         let theme = Theme::load();
         let system_prefer_dark = get_system_prefer_dark_mode();
 
-        let window = web_sys::window().unwrap();
-        let media_query = match window.match_media("(prefers-color-scheme: dark)") {
+        let media_query = match get_window().match_media("(prefers-color-scheme: dark)") {
             Ok(Some(media_query)) => media_query,
             _ => panic!("window.match_media() failed!"),
         };
@@ -322,9 +321,7 @@ impl ThemeObserver {
             }) as Box<dyn Fn()>
         });
 
-        let window = web_sys::window().unwrap();
-        let document = window.document().unwrap();
-        let _ = document.add_event_listener_with_callback(
+        let _ = get_document().add_event_listener_with_callback(
             "pwt-theme-changed",
             theme_changed_closure.as_ref().unchecked_ref(),
         );
@@ -337,9 +334,7 @@ impl ThemeObserver {
             None => return,
         };
 
-        let window = web_sys::window().unwrap();
-        let document = window.document().unwrap();
-        let _ = document.remove_event_listener_with_callback(
+        let _ = get_document().remove_event_listener_with_callback(
             "pwt-theme-changed",
             theme_changed_closure.as_ref().unchecked_ref(),
         );
diff --git a/src/touch/side_dialog.rs b/src/touch/side_dialog.rs
index 9d36ca5..15f6db4 100644
--- a/src/touch/side_dialog.rs
+++ b/src/touch/side_dialog.rs
@@ -7,7 +7,7 @@ use yew::html::{IntoEventCallback, IntoPropValue};
 use yew::prelude::*;
 use yew::virtual_dom::{Key, VComp, VNode};
 
-use crate::dom::IntoHtmlElement;
+use crate::dom::{get_document, IntoHtmlElement};
 use crate::prelude::*;
 use crate::state::{SharedState, SharedStateObserver};
 use crate::widget::Container;
@@ -185,9 +185,7 @@ impl Component for PwtSideDialog {
     fn create(ctx: &Context<Self>) -> Self {
         let props = ctx.props();
 
-        let window = web_sys::window().unwrap();
-        let document = window.document().unwrap();
-        let last_active = document
+        let last_active = get_document()
             .active_element()
             .and_then(|el| el.dyn_into::<HtmlElement>().ok());
 
diff --git a/src/widget/data_table/data_table.rs b/src/widget/data_table/data_table.rs
index 8f664af..076cc98 100644
--- a/src/widget/data_table/data_table.rs
+++ b/src/widget/data_table/data_table.rs
@@ -12,7 +12,7 @@ use yew::prelude::*;
 use yew::virtual_dom::{Key, VComp, VNode};
 
 use crate::dom::focus::{focus_inside_el, focus_inside_input, focus_next_el};
-use crate::dom::{DomSizeObserver, IntoHtmlElement};
+use crate::dom::{get_document, DomSizeObserver, IntoHtmlElement};
 use crate::prelude::*;
 use crate::props::{
     AsClassesMut, AsCssStylesMut, CallbackMut, CssLength, CssStyles, IntoEventCallbackMut,
@@ -815,9 +815,7 @@ impl<S: DataStore> PwtDataTable<S> {
 
     fn get_row_el(&self, key: &Key) -> Option<web_sys::Element> {
         let id = self.get_unique_item_id(key);
-        let window = web_sys::window().unwrap();
-        let document = window.document().unwrap();
-        document.get_element_by_id(&id)
+        get_document().get_element_by_id(&id)
     }
 
     fn focus_cell(&mut self, key: &Key) {
@@ -856,9 +854,7 @@ impl<S: DataStore> PwtDataTable<S> {
     }
 
     fn find_focused_cell(&self) -> Option<(Key, Option<usize>)> {
-        let window = web_sys::window().unwrap();
-        let document = window.document().unwrap();
-        let active_el = document.active_element()?;
+        let active_el = get_document().active_element()?;
         dom_find_focus_pos(active_el, &self.unique_id)
     }
 
diff --git a/src/widget/data_table/header_widget.rs b/src/widget/data_table/header_widget.rs
index 70bdf8b..2162b6b 100644
--- a/src/widget/data_table/header_widget.rs
+++ b/src/widget/data_table/header_widget.rs
@@ -10,6 +10,7 @@ use yew::html::Scope;
 use yew::prelude::*;
 use yew::virtual_dom::{Key, VComp, VNode};
 
+use crate::dom::get_document;
 use crate::prelude::*;
 use crate::widget::menu::{Menu, MenuCheckbox, MenuEvent, MenuItem};
 use crate::widget::{get_unique_element_id, Container, Fa};
@@ -427,12 +428,9 @@ impl<T: 'static> PwtHeaderWidget<T> {
     }
 
     fn focus_active_cell(&self) {
-        let window = web_sys::window().unwrap();
-        let document = window.document().unwrap();
-
         let get_cell_el = |cell_idx| -> Option<web_sys::HtmlElement> {
             let id = self.unique_cell_id(cell_idx);
-            let el = document.get_element_by_id(&id)?;
+            let el = get_document().get_element_by_id(&id)?;
             match el.dyn_into::<web_sys::HtmlElement>() {
                 Ok(el) => Some(el),
                 Err(_) => None,
diff --git a/src/widget/data_table/resizable_header.rs b/src/widget/data_table/resizable_header.rs
index 7243dc7..c741f39 100644
--- a/src/widget/data_table/resizable_header.rs
+++ b/src/widget/data_table/resizable_header.rs
@@ -9,9 +9,9 @@ use yew::prelude::*;
 use yew::virtual_dom::{Key, VComp, VNode};
 
 use crate::css::ColorScheme;
-use crate::dom::element_direction_rtl;
 use crate::dom::focus::FocusTracker;
 use crate::dom::DomSizeObserver;
+use crate::dom::{element_direction_rtl, get_window};
 use crate::prelude::*;
 use crate::props::{BuilderFn, IntoOptionalBuilderFn};
 use crate::widget::menu::{Menu, MenuButton};
@@ -244,7 +244,7 @@ impl Component for PwtResizableHeader {
             Msg::StartResize => {
                 self.rtl = element_direction_rtl(&self.node_ref);
 
-                let window = web_sys::window().unwrap();
+                let window = get_window();
                 let link = ctx.link();
                 let onpointermove = link.callback(|e: Event| {
                     let event = e.dyn_ref::<web_sys::PointerEvent>().unwrap_throw();
diff --git a/src/widget/dialog.rs b/src/widget/dialog.rs
index 68fc91b..aba77cc 100644
--- a/src/widget/dialog.rs
+++ b/src/widget/dialog.rs
@@ -5,14 +5,14 @@ use gloo_events::EventListener;
 use gloo_timers::callback::Timeout;
 use wasm_bindgen::prelude::Closure;
 use wasm_bindgen::{JsCast, UnwrapThrowExt};
-use web_sys::{window, HtmlElement};
+use web_sys::HtmlElement;
 
 use yew::html::{IntoEventCallback, IntoPropValue};
 use yew::prelude::*;
 use yew::virtual_dom::{Key, VComp, VNode};
 
 use crate::dom::align::{align_to_viewport, align_to_xy, Point};
-use crate::dom::IntoHtmlElement;
+use crate::dom::{get_document, get_window, IntoHtmlElement};
 use crate::prelude::*;
 use crate::props::{AsCssStylesMut, CssStyles};
 use crate::widget::{ActionIcon, Panel};
@@ -154,8 +154,7 @@ impl PwtDialog {
 impl Drop for PwtDialog {
     fn drop(&mut self) {
         if let Some(center_function) = self.center_function.take() {
-            let window = web_sys::window().unwrap();
-            window
+            get_window()
                 .remove_event_listener_with_callback(
                     "resize",
                     center_function.as_ref().unchecked_ref(),
@@ -172,9 +171,7 @@ impl Component for PwtDialog {
     fn create(ctx: &Context<Self>) -> Self {
         ctx.link().send_message(Msg::Open);
 
-        let window = web_sys::window().unwrap();
-        let document = window.document().unwrap();
-        let last_active = document
+        let last_active = get_document()
             .active_element()
             .and_then(|el| el.dyn_into::<HtmlElement>().ok());
 
@@ -184,7 +181,7 @@ impl Component for PwtDialog {
                 link.send_message(Msg::Center);
             });
 
-            window
+            get_window()
                 .add_event_listener_with_callback(
                     "resize",
                     center_function.as_ref().unchecked_ref(),
@@ -253,10 +250,10 @@ impl Component for PwtDialog {
                         self.dragging_state = DragState::Dragging(
                             x,
                             y,
-                            EventListener::new(&window().unwrap(), "pointermove", move |event| {
+                            EventListener::new(&get_window(), "pointermove", move |event| {
                                 onmousemove.emit(event.clone().dyn_into().unwrap());
                             }),
-                            EventListener::new(&window().unwrap(), "pointerup", move |event| {
+                            EventListener::new(&get_window(), "pointerup", move |event| {
                                 onpointerup.emit(event.clone().dyn_into().unwrap());
                             }),
                             event.pointer_id(),
@@ -267,7 +264,7 @@ impl Component for PwtDialog {
             }
             Msg::PointerMove(event) => match &self.dragging_state {
                 DragState::Dragging(offset_x, offset_y, _, _, id) if *id == event.pointer_id() => {
-                    let window = window().unwrap();
+                    let window = get_window();
                     let width = window.inner_width().unwrap().as_f64().unwrap();
                     let height = window.inner_height().unwrap().as_f64().unwrap();
                     let x = (event.client_x() as f64).max(0.0).min(width) - offset_x;
@@ -324,10 +321,10 @@ impl Component for PwtDialog {
                     DragState::Dragging(
                         offset.0,
                         offset.1,
-                        EventListener::new(&window().unwrap(), "pointermove", move |event| {
+                        EventListener::new(&get_window(), "pointermove", move |event| {
                             onpointermove.emit(event.clone().dyn_into().unwrap());
                         }),
-                        EventListener::new(&window().unwrap(), "pointerup", move |event| {
+                        EventListener::new(&get_window(), "pointerup", move |event| {
                             onpointerup.emit(event.clone().dyn_into().unwrap());
                         }),
                         event.pointer_id(),
@@ -342,9 +339,8 @@ impl Component for PwtDialog {
                         let old_height = rect.height();
 
                         let viewport_height =
-                            window().unwrap().inner_height().unwrap().as_f64().unwrap();
-                        let viewport_width =
-                            window().unwrap().inner_width().unwrap().as_f64().unwrap();
+                            get_window().inner_height().unwrap().as_f64().unwrap();
+                        let viewport_width = get_window().inner_width().unwrap().as_f64().unwrap();
 
                         // restrict to viewport
                         let client_x = (event.client_x() as f64).clamp(5.0, viewport_width - 5.0);
diff --git a/src/widget/form/managed_field.rs b/src/widget/form/managed_field.rs
index 0ca7ae0..c0358fc 100644
--- a/src/widget/form/managed_field.rs
+++ b/src/widget/form/managed_field.rs
@@ -6,7 +6,7 @@ use yew::html::Scope;
 use yew::prelude::*;
 
 use super::{FieldHandle, FieldOptions, FormContext, FormContextObserver, SubmitValidateFn};
-use crate::props::FieldBuilder;
+use crate::{dom::get_document, props::FieldBuilder};
 
 /// Managed field state.
 ///
@@ -515,9 +515,6 @@ impl<MF: ManagedField + 'static> Component for ManagedFieldMaster<MF> {
             */
 
             if let Some(label_id) = &props.label_id {
-                let window = web_sys::window().unwrap();
-                let document = window.document().unwrap();
-
                 let label_clicked_closure = Closure::wrap({
                     let link = ctx.link().clone();
                     Box::new(move || {
@@ -525,7 +522,7 @@ impl<MF: ManagedField + 'static> Component for ManagedFieldMaster<MF> {
                     }) as Box<dyn Fn()>
                 });
 
-                if let Some(el) = document.get_element_by_id(label_id) {
+                if let Some(el) = get_document().get_element_by_id(label_id) {
                     let _ = el.add_event_listener_with_callback(
                         "click",
                         label_clicked_closure.as_ref().unchecked_ref(),
diff --git a/src/widget/menu/mod.rs b/src/widget/menu/mod.rs
index 0231430..60c6bd3 100644
--- a/src/widget/menu/mod.rs
+++ b/src/widget/menu/mod.rs
@@ -10,6 +10,7 @@ use yew::prelude::*;
 use yew::virtual_dom::{VComp, VNode};
 
 use crate::dom::focus::{get_first_focusable, FocusTracker};
+use crate::dom::get_document;
 use crate::prelude::*;
 use crate::widget::{get_unique_element_id, Container};
 
@@ -739,10 +740,7 @@ fn dom_focus_inside_submenu(event: &FocusEvent, item_id: &str) -> bool {
 }
 
 fn dom_focus_submenu(item_id: &str) {
-    let window = web_sys::window().unwrap();
-    let document = window.document().unwrap();
-
-    let el = match document.get_element_by_id(item_id) {
+    let el = match get_document().get_element_by_id(item_id) {
         Some(el) => el,
         None => return,
     };
diff --git a/src/widget/rtl_switcher.rs b/src/widget/rtl_switcher.rs
index 5332bf9..abeb3d5 100644
--- a/src/widget/rtl_switcher.rs
+++ b/src/widget/rtl_switcher.rs
@@ -2,7 +2,10 @@ use pwt_macros::widget;
 use yew::{Classes, Component, Properties};
 
 use super::form::Checkbox;
-use crate::props::{FieldBuilder, WidgetBuilder};
+use crate::{
+    dom::get_document,
+    props::{FieldBuilder, WidgetBuilder},
+};
 
 /// A checkbox to switch between Left-to-Right and Right-to-Left layouts
 #[widget(pwt=crate, comp=PwtRtlSwitcher, @input, @element)]
@@ -51,8 +54,7 @@ impl Component for PwtRtlSwitcher {
     fn update(&mut self, _ctx: &yew::Context<Self>, msg: Self::Message) -> bool {
         match msg {
             Msg::ToggleRtl => {
-                let document = web_sys::window().unwrap().document().unwrap();
-                let elements = document.get_elements_by_tag_name("html");
+                let elements = get_document().get_elements_by_tag_name("html");
                 if let Some(html) = elements.get_with_index(0) {
                     if self.rtl {
                         if let Err(err) = html.remove_attribute("dir") {
@@ -74,8 +76,7 @@ impl Component for PwtRtlSwitcher {
     }
 
     fn create(_ctx: &yew::Context<Self>) -> Self {
-        let document = web_sys::window().unwrap().document().unwrap();
-        let elements = document.get_elements_by_tag_name("html");
+        let elements = get_document().get_elements_by_tag_name("html");
         let rtl = elements
             .get_with_index(0)
             .and_then(|html| html.get_attribute("dir"))
diff --git a/src/widget/split_pane.rs b/src/widget/split_pane.rs
index 106602f..49b42b7 100644
--- a/src/widget/split_pane.rs
+++ b/src/widget/split_pane.rs
@@ -9,7 +9,7 @@ use crate::css::{Display, FlexFillFirstChild, Overflow};
 use crate::props::{ContainerBuilder, EventSubscriber, WidgetBuilder, WidgetStyleBuilder};
 
 use super::Container;
-use crate::dom::element_direction_rtl;
+use crate::dom::{element_direction_rtl, get_window};
 
 use pwt_macros::widget;
 
@@ -540,7 +540,7 @@ impl Component for PwtSplitPane {
 
                 self.rtl = element_direction_rtl(&props.std_props.node_ref);
 
-                let window = web_sys::window().unwrap();
+                let window = get_window();
                 let link = ctx.link();
                 let onpointermove = link.callback(move |e: Event| {
                     let event = e.dyn_ref::<web_sys::PointerEvent>().unwrap_throw();
diff --git a/src/widget/theme_loader.rs b/src/widget/theme_loader.rs
index f8a0d40..6d09a01 100644
--- a/src/widget/theme_loader.rs
+++ b/src/widget/theme_loader.rs
@@ -4,6 +4,7 @@ use pwt_macros::builder;
 use yew::prelude::*;
 use yew::virtual_dom::{Key, VComp, VNode};
 
+use crate::dom::get_document;
 use crate::impl_to_html;
 use crate::state::{Theme, ThemeDensity, ThemeObserver};
 
@@ -38,11 +39,7 @@ pub struct PwtThemeLoader {
 }
 
 fn get_document_root() -> Option<web_sys::Element> {
-    let window = web_sys::window()?;
-
-    let document = window.document()?;
-
-    document.document_element()
+    get_document().document_element()
 }
 
 fn set_css_density(density: ThemeDensity) {
-- 
2.39.5



_______________________________________________
yew-devel mailing list
yew-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/yew-devel


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [yew-devel] [PATCH yew-widget-toolkit 1/2] dom: add convenience functions to get often used elements
  2025-05-02 12:49 [yew-devel] [PATCH yew-widget-toolkit 1/2] dom: add convenience functions to get often used elements Dominik Csapak
  2025-05-02 12:49 ` [yew-devel] [PATCH yew-widget-toolkit 2/2] tree wide: use get_window/document/body Dominik Csapak
@ 2025-05-05  8:13 ` Dietmar Maurer
  2025-05-05  8:27   ` Shannon Sterz
  1 sibling, 1 reply; 5+ messages in thread
From: Dietmar Maurer @ 2025-05-05  8:13 UTC (permalink / raw)
  To: Yew framework devel list at Proxmox, Dominik Csapak

We can use gloo_utils instead?

> On 2.5.2025 14:49 CEST Dominik Csapak <d.csapak@proxmox.com> wrote:
> 
>  
> Namely window/document/body. We use them throughout our codebase with
> inline unwraps, instead we can use these helpers instead.
> 
> Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
> ---
>  src/dom/mod.rs | 20 +++++++++++++++++++-
>  1 file changed, 19 insertions(+), 1 deletion(-)
> 
> diff --git a/src/dom/mod.rs b/src/dom/mod.rs
> index f61dd21..679fab7 100644
> --- a/src/dom/mod.rs
> +++ b/src/dom/mod.rs
> @@ -13,7 +13,7 @@ pub use dom_size_observer::{DomSizeObserver, IntoSizeCallback, SizeCallback};
>  mod dom_visibility_observer;
>  pub use dom_visibility_observer::DomVisibilityObserver;
>  
> -use web_sys::Node;
> +use web_sys::{window, Document, HtmlElement, Node, Window};
>  use yew::prelude::*;
>  
>  /// A Trait to convert structs into HtmlElement when possible
> @@ -77,3 +77,21 @@ pub fn get_system_prefer_dark_mode() -> bool {
>          false
>      }
>  }
> +
> +/// Convenience function to get the [`Window`] object.
> +/// Panics if not in a browser context
> +pub fn get_window() -> Window {
> +    window().unwrap()
> +}
> +
> +/// Convenience function to get the [`Document`] object.
> +/// Panics if not in a browser context
> +pub fn get_document() -> Document {
> +    get_window().document().unwrap()
> +}
> +
> +/// Convenience function to get the a reference to the <body> tag as [`HtmlElement`].
> +/// Panics if not in a browser context
> +pub fn get_body() -> HtmlElement {
> +    get_document().body().unwrap()
> +}
> -- 
> 2.39.5
> 
> 
> 
> _______________________________________________
> yew-devel mailing list
> yew-devel@lists.proxmox.com
> https://lists.proxmox.com/cgi-bin/mailman/listinfo/yew-devel


_______________________________________________
yew-devel mailing list
yew-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/yew-devel


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [yew-devel] [PATCH yew-widget-toolkit 1/2] dom: add convenience functions to get often used elements
  2025-05-05  8:13 ` [yew-devel] [PATCH yew-widget-toolkit 1/2] dom: add convenience functions to get often used elements Dietmar Maurer
@ 2025-05-05  8:27   ` Shannon Sterz
  2025-05-05  8:36     ` Dominik Csapak
  0 siblings, 1 reply; 5+ messages in thread
From: Shannon Sterz @ 2025-05-05  8:27 UTC (permalink / raw)
  To: Yew framework devel list at Proxmox, Dietmar Maurer

On Mon May 5, 2025 at 10:13 AM CEST, Dietmar Maurer wrote:
> We can use gloo_utils instead?
>

I'd also prefer gloo_utils here, especially because that also uses the
`UnwraptThrowExt` traits, which is a bit nicer [1] and pwt already
depends on it indirectly anyway (through, e.g., gloo-history).

[1]: https://docs.rs/gloo-utils/latest/src/gloo_utils/lib.rs.html

>> On 2.5.2025 14:49 CEST Dominik Csapak <d.csapak@proxmox.com> wrote:
>>
>>
>> Namely window/document/body. We use them throughout our codebase with
>> inline unwraps, instead we can use these helpers instead.
>>
>> Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
>> ---
>>  src/dom/mod.rs | 20 +++++++++++++++++++-
>>  1 file changed, 19 insertions(+), 1 deletion(-)
>>
>> diff --git a/src/dom/mod.rs b/src/dom/mod.rs
>> index f61dd21..679fab7 100644
>> --- a/src/dom/mod.rs
>> +++ b/src/dom/mod.rs
>> @@ -13,7 +13,7 @@ pub use dom_size_observer::{DomSizeObserver, IntoSizeCallback, SizeCallback};
>>  mod dom_visibility_observer;
>>  pub use dom_visibility_observer::DomVisibilityObserver;
>>
>> -use web_sys::Node;
>> +use web_sys::{window, Document, HtmlElement, Node, Window};
>>  use yew::prelude::*;
>>
>>  /// A Trait to convert structs into HtmlElement when possible
>> @@ -77,3 +77,21 @@ pub fn get_system_prefer_dark_mode() -> bool {
>>          false
>>      }
>>  }
>> +
>> +/// Convenience function to get the [`Window`] object.
>> +/// Panics if not in a browser context
>> +pub fn get_window() -> Window {
>> +    window().unwrap()
>> +}
>> +
>> +/// Convenience function to get the [`Document`] object.
>> +/// Panics if not in a browser context
>> +pub fn get_document() -> Document {
>> +    get_window().document().unwrap()
>> +}
>> +
>> +/// Convenience function to get the a reference to the <body> tag as [`HtmlElement`].
>> +/// Panics if not in a browser context
>> +pub fn get_body() -> HtmlElement {
>> +    get_document().body().unwrap()
>> +}
>> --
>> 2.39.5
>>
>>
>>
>> _______________________________________________
>> yew-devel mailing list
>> yew-devel@lists.proxmox.com
>> https://lists.proxmox.com/cgi-bin/mailman/listinfo/yew-devel
>
>
> _______________________________________________
> yew-devel mailing list
> yew-devel@lists.proxmox.com
> https://lists.proxmox.com/cgi-bin/mailman/listinfo/yew-devel



_______________________________________________
yew-devel mailing list
yew-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/yew-devel


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [yew-devel] [PATCH yew-widget-toolkit 1/2] dom: add convenience functions to get often used elements
  2025-05-05  8:27   ` Shannon Sterz
@ 2025-05-05  8:36     ` Dominik Csapak
  0 siblings, 0 replies; 5+ messages in thread
From: Dominik Csapak @ 2025-05-05  8:36 UTC (permalink / raw)
  To: yew-devel

On 5/5/25 10:27, Shannon Sterz wrote:
> On Mon May 5, 2025 at 10:13 AM CEST, Dietmar Maurer wrote:
>> We can use gloo_utils instead?
>>
> 
> I'd also prefer gloo_utils here, especially because that also uses the
> `UnwraptThrowExt` traits, which is a bit nicer [1] and pwt already
> depends on it indirectly anyway (through, e.g., gloo-history).
> 
> [1]: https://docs.rs/gloo-utils/latest/src/gloo_utils/lib.rs.html


yes, sure, i somehow thought that this was not the case

in that case, i'll only send one patch that uses gloo_uitls::* inline everywhere

> 
>>> On 2.5.2025 14:49 CEST Dominik Csapak <d.csapak@proxmox.com> wrote:
>>>
>>>
>>> Namely window/document/body. We use them throughout our codebase with
>>> inline unwraps, instead we can use these helpers instead.
>>>
>>> Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
>>> ---
>>>   src/dom/mod.rs | 20 +++++++++++++++++++-
>>>   1 file changed, 19 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/src/dom/mod.rs b/src/dom/mod.rs
>>> index f61dd21..679fab7 100644
>>> --- a/src/dom/mod.rs
>>> +++ b/src/dom/mod.rs
>>> @@ -13,7 +13,7 @@ pub use dom_size_observer::{DomSizeObserver, IntoSizeCallback, SizeCallback};
>>>   mod dom_visibility_observer;
>>>   pub use dom_visibility_observer::DomVisibilityObserver;
>>>
>>> -use web_sys::Node;
>>> +use web_sys::{window, Document, HtmlElement, Node, Window};
>>>   use yew::prelude::*;
>>>
>>>   /// A Trait to convert structs into HtmlElement when possible
>>> @@ -77,3 +77,21 @@ pub fn get_system_prefer_dark_mode() -> bool {
>>>           false
>>>       }
>>>   }
>>> +
>>> +/// Convenience function to get the [`Window`] object.
>>> +/// Panics if not in a browser context
>>> +pub fn get_window() -> Window {
>>> +    window().unwrap()
>>> +}
>>> +
>>> +/// Convenience function to get the [`Document`] object.
>>> +/// Panics if not in a browser context
>>> +pub fn get_document() -> Document {
>>> +    get_window().document().unwrap()
>>> +}
>>> +
>>> +/// Convenience function to get the a reference to the <body> tag as [`HtmlElement`].
>>> +/// Panics if not in a browser context
>>> +pub fn get_body() -> HtmlElement {
>>> +    get_document().body().unwrap()
>>> +}
>>> --
>>> 2.39.5
>>>
>>>
>>>
>>> _______________________________________________
>>> yew-devel mailing list
>>> yew-devel@lists.proxmox.com
>>> https://lists.proxmox.com/cgi-bin/mailman/listinfo/yew-devel
>>
>>
>> _______________________________________________
>> yew-devel mailing list
>> yew-devel@lists.proxmox.com
>> https://lists.proxmox.com/cgi-bin/mailman/listinfo/yew-devel
> 
> 
> 
> _______________________________________________
> yew-devel mailing list
> yew-devel@lists.proxmox.com
> https://lists.proxmox.com/cgi-bin/mailman/listinfo/yew-devel
> 
> 



_______________________________________________
yew-devel mailing list
yew-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/yew-devel


^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2025-05-05  8:36 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-05-02 12:49 [yew-devel] [PATCH yew-widget-toolkit 1/2] dom: add convenience functions to get often used elements Dominik Csapak
2025-05-02 12:49 ` [yew-devel] [PATCH yew-widget-toolkit 2/2] tree wide: use get_window/document/body Dominik Csapak
2025-05-05  8:13 ` [yew-devel] [PATCH yew-widget-toolkit 1/2] dom: add convenience functions to get often used elements Dietmar Maurer
2025-05-05  8:27   ` Shannon Sterz
2025-05-05  8:36     ` Dominik Csapak

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal