Skip to main content

rustolio_web/elements/html/attributes/
mod.rs

1//
2// SPDX-License-Identifier: MPL-2.0
3//
4// Copyright (c) 2026 Tobias Binnewies. All rights reserved.
5//
6// This Source Code Form is subject to the terms of the Mozilla Public
7// License, v. 2.0. If a copy of the MPL was not distributed with this
8// file, You can obtain one at http://mozilla.org/MPL/2.0/.
9//
10
11mod attribute;
12mod listener;
13
14pub use attribute::{Attribute, AttributeValue};
15pub use listener::{Listener, ListenerExt};
16
17pub mod traits {
18    pub use super::attribute::{
19        IntoBoolFnWrapper as _, IntoBoolWrapper as _, IntoStringFnWrapper as _,
20        IntoStringWrapper as _,
21    };
22    pub use super::listener::{ClosureIntoListener as _, ResultClosureIntoListener as _};
23}
24
25#[derive(Debug, Clone, Default)]
26pub struct Attributes {
27    pub(crate) attributes: Vec<Attribute>,
28
29    pub(crate) class_dynamic: bool,
30    pub(crate) class: Vec<AttributeValue>,
31
32    pub(crate) style_dynamic: bool,
33    pub(crate) style: Vec<AttributeValue>,
34
35    pub(crate) value: AttributeValue,
36    pub(crate) selected: AttributeValue,
37    pub(crate) checked: AttributeValue,
38
39    pub(crate) listener: Vec<Listener>,
40}
41
42impl Attributes {
43    pub fn new() -> Self {
44        Attributes::default()
45    }
46
47    pub fn add_attribute(&mut self, name: &'static str, value: impl Into<AttributeValue>) {
48        let value = value.into();
49        match name {
50            "class" => {
51                if let AttributeValue::Dynamic(_) = &value {
52                    self.class_dynamic = true;
53                }
54                self.class.push(value);
55            }
56            "style" => {
57                if let AttributeValue::Dynamic(_) = &value {
58                    self.style_dynamic = true;
59                }
60                self.style.push(value);
61            }
62            "value" => {
63                self.value = value;
64            }
65            "selected" => {
66                self.selected = value;
67            }
68            "checked" => {
69                self.checked = value;
70            }
71            _ => self.attributes.push(Attribute { name, value }),
72        };
73    }
74
75    pub fn add_listener(&mut self, listener: &Listener) {
76        self.listener.push(listener.clone());
77    }
78
79    pub fn extend(&mut self, other: Attributes) {
80        self.attributes.extend(other.attributes);
81        if other.class_dynamic {
82            self.class_dynamic = true;
83        }
84        self.class.extend(other.class);
85        if other.style_dynamic {
86            self.style_dynamic = true;
87        }
88        self.style.extend(other.style);
89        self.listener.extend(other.listener);
90        if other.value != AttributeValue::default() {
91            self.value = other.value;
92        }
93        if other.selected != AttributeValue::default() {
94            self.selected = other.selected;
95        }
96        if other.checked != AttributeValue::default() {
97            self.checked = other.checked;
98        }
99    }
100}