kozan_core/html/
media_element.rs1use super::html_element::HtmlElement;
23
24#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
28pub enum MediaReadyState {
29 #[default]
31 HaveNothing = 0,
32 HaveMetadata = 1,
34 HaveCurrentData = 2,
36 HaveFutureData = 3,
38 HaveEnoughData = 4,
40}
41
42#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
46pub enum MediaNetworkState {
47 #[default]
49 Empty = 0,
50 Idle = 1,
52 Loading = 2,
54 NoSource = 3,
56}
57
58pub trait MediaElement: HtmlElement {
67 fn src(&self) -> String {
71 self.attribute("src").unwrap_or_default()
72 }
73
74 fn set_src(&self, src: impl Into<String>) {
75 self.set_attribute("src", src);
76 }
77
78 fn autoplay(&self) -> bool {
82 self.attribute("autoplay").is_some()
83 }
84
85 fn set_autoplay(&self, autoplay: bool) {
86 if autoplay {
87 self.set_attribute("autoplay", "");
88 } else {
89 self.remove_attribute("autoplay");
90 }
91 }
92
93 fn loop_playback(&self) -> bool {
95 self.attribute("loop").is_some()
96 }
97
98 fn set_loop_playback(&self, looping: bool) {
99 if looping {
100 self.set_attribute("loop", "");
101 } else {
102 self.remove_attribute("loop");
103 }
104 }
105
106 fn muted(&self) -> bool {
108 self.attribute("muted").is_some()
109 }
110
111 fn set_muted(&self, muted: bool) {
112 if muted {
113 self.set_attribute("muted", "");
114 } else {
115 self.remove_attribute("muted");
116 }
117 }
118
119 fn controls(&self) -> bool {
121 self.attribute("controls").is_some()
122 }
123
124 fn set_controls(&self, controls: bool) {
125 if controls {
126 self.set_attribute("controls", "");
127 } else {
128 self.remove_attribute("controls");
129 }
130 }
131
132 fn preload(&self) -> String {
136 self.attribute("preload")
137 .unwrap_or_else(|| "auto".to_string())
138 }
139
140 fn set_preload(&self, preload: impl Into<String>) {
141 self.set_attribute("preload", preload);
142 }
143
144 fn current_time(&self) -> f64 {
148 0.0
149 }
150
151 fn duration(&self) -> f64 {
153 f64::NAN
154 }
155
156 fn paused(&self) -> bool {
158 true
159 }
160
161 fn ready_state(&self) -> MediaReadyState {
163 MediaReadyState::HaveNothing
164 }
165
166 fn network_state(&self) -> MediaNetworkState {
168 MediaNetworkState::Empty
169 }
170
171 fn play(&self) {}
175
176 fn pause(&self) {}
178}
179
180#[cfg(test)]
181mod tests {
182 use super::*;
183 use crate::dom::document::Document;
184 use crate::html::HtmlAudioElement;
185
186 #[test]
187 fn audio_src() {
188 let doc = Document::new();
189 let audio = doc.create::<HtmlAudioElement>();
190 assert_eq!(audio.src(), "");
191
192 audio.set_src("music.mp3");
193 assert_eq!(audio.src(), "music.mp3");
194 }
195
196 #[test]
197 fn audio_boolean_attrs() {
198 let doc = Document::new();
199 let audio = doc.create::<HtmlAudioElement>();
200
201 assert!(!audio.autoplay());
202 assert!(!audio.loop_playback());
203 assert!(!audio.muted());
204 assert!(!audio.controls());
205
206 audio.set_autoplay(true);
207 audio.set_controls(true);
208 assert!(audio.autoplay());
209 assert!(audio.controls());
210 }
211
212 #[test]
213 fn audio_default_ready_and_network_state() {
214 let doc = Document::new();
215 let audio = doc.create::<HtmlAudioElement>();
216 assert_eq!(audio.ready_state(), MediaReadyState::HaveNothing);
218 assert_eq!(audio.network_state(), MediaNetworkState::Empty);
219 }
220}