arwa/html/
html_field_set_element.rs

1use std::convert::TryFrom;
2
3use delegate::delegate;
4use wasm_bindgen::JsCast;
5
6use crate::html::{GenericHtmlElement, HtmlElement, HtmlFormElement};
7use crate::{Element, GenericElement, GenericNode, GlobalEventHandlers, InvalidCast, Node};
8
9use crate::console::{Write, Writer};
10pub use web_sys::ValidityState;
11
12#[derive(Clone)]
13pub struct HtmlFieldSetElement {
14    inner: web_sys::HtmlFieldSetElement,
15}
16
17impl HtmlFieldSetElement {
18    delegate! {
19        target self.inner {
20            pub fn name(&self) -> String;
21
22            pub fn set_name(&self, name: &str);
23
24            pub fn disabled(&self) -> bool;
25
26            pub fn set_disabled(&self, disabled: bool);
27
28            pub fn will_validate(&self) -> bool;
29
30            pub fn check_validity(&self) -> bool;
31
32            pub fn report_validity(&self) -> bool;
33
34            pub fn set_custom_validity(&self, error: &str);
35
36            pub fn validity(&self) -> ValidityState;
37        }
38    }
39
40    pub fn form(&self) -> Option<HtmlFormElement> {
41        self.inner.form().map(|form| form.into())
42    }
43
44    pub fn validation_message(&self) -> String {
45        // There's no indication in the spec that this can actually fail, unwrap for now.
46        self.inner.validation_message().unwrap()
47    }
48
49    pub fn elements(&self) -> FieldSetElements {
50        FieldSetElements {
51            inner: self.inner.elements(),
52        }
53    }
54}
55
56impl_html_common_traits!(HtmlFieldSetElement);
57
58pub struct FieldSetElements {
59    inner: web_sys::HtmlCollection,
60}
61
62impl FieldSetElements {
63    pub fn get(&self, index: usize) -> Option<GenericHtmlElement> {
64        u32::try_from(index)
65            .ok()
66            .and_then(|index| self.inner.get_with_index(index))
67            .map(|e| {
68                let e: web_sys::HtmlElement = e.unchecked_into();
69
70                e.into()
71            })
72    }
73
74    pub fn find_by_id(&self, id: &str) -> Option<GenericHtmlElement> {
75        self.inner.get_with_name(id).map(|e| {
76            let e: web_sys::HtmlElement = e.unchecked_into();
77
78            e.into()
79        })
80    }
81
82    pub fn len(&self) -> usize {
83        self.inner.length() as usize
84    }
85
86    pub fn is_empty(&self) -> bool {
87        self.len() == 0
88    }
89
90    pub fn is_not_empty(&self) -> bool {
91        !self.is_empty()
92    }
93
94    pub fn first(&self) -> Option<GenericHtmlElement> {
95        self.get(0)
96    }
97
98    pub fn last(&self) -> Option<GenericHtmlElement> {
99        let len = self.len();
100
101        if len > 0 {
102            self.get(len - 1)
103        } else {
104            None
105        }
106    }
107
108    pub fn iter(&self) -> FieldSetElementsIter {
109        FieldSetElementsIter {
110            field_set_elements: self,
111            current: 0,
112        }
113    }
114}
115
116impl Write for FieldSetElements {
117    fn write(&self, writer: &mut Writer) {
118        writer.write_1(self.inner.as_ref());
119    }
120}
121
122impl IntoIterator for FieldSetElements {
123    type Item = GenericHtmlElement;
124    type IntoIter = FieldSetElementsIntoIter;
125
126    fn into_iter(self) -> Self::IntoIter {
127        FieldSetElementsIntoIter {
128            field_set_elements: self,
129            current: 0,
130        }
131    }
132}
133
134pub struct FieldSetElementsIter<'a> {
135    field_set_elements: &'a FieldSetElements,
136    current: usize,
137}
138
139impl<'a> Iterator for FieldSetElementsIter<'a> {
140    type Item = GenericHtmlElement;
141
142    fn next(&mut self) -> Option<Self::Item> {
143        let current = self.current;
144
145        self.current += 1;
146
147        self.field_set_elements.get(current)
148    }
149}
150
151pub struct FieldSetElementsIntoIter {
152    field_set_elements: FieldSetElements,
153    current: usize,
154}
155
156impl Iterator for FieldSetElementsIntoIter {
157    type Item = GenericHtmlElement;
158
159    fn next(&mut self) -> Option<Self::Item> {
160        let current = self.current;
161
162        self.current += 1;
163
164        self.field_set_elements.get(current)
165    }
166}