1use std::cell::Cell;
6
7use dom_struct::dom_struct;
8use js::rust::HandleObject;
9
10use crate::dom::bindings::cell::DomRefCell;
11use crate::dom::bindings::codegen::Bindings::VTTCueBinding::{
12 self, AlignSetting, AutoKeyword, DirectionSetting, LineAlignSetting, PositionAlignSetting,
13 VTTCueMethods,
14};
15use crate::dom::bindings::error::{Error, ErrorResult};
16use crate::dom::bindings::num::Finite;
17use crate::dom::bindings::reflector::reflect_dom_object_with_proto;
18use crate::dom::bindings::root::{Dom, DomRoot};
19use crate::dom::bindings::str::DOMString;
20use crate::dom::documentfragment::DocumentFragment;
21use crate::dom::texttrackcue::TextTrackCue;
22use crate::dom::vttregion::VTTRegion;
23use crate::dom::window::Window;
24use crate::script_runtime::CanGc;
25
26#[dom_struct]
27pub(crate) struct VTTCue {
28 texttrackcue: TextTrackCue,
29 region: DomRefCell<Option<Dom<VTTRegion>>>,
30 vertical: Cell<DirectionSetting>,
31 snap_to_lines: Cell<bool>,
32 line: DomRefCell<LineAndPositionSetting>,
33 line_align: Cell<LineAlignSetting>,
34 position: DomRefCell<LineAndPositionSetting>,
35 position_align: Cell<PositionAlignSetting>,
36 size: Cell<f64>,
37 align: Cell<AlignSetting>,
38 text: DomRefCell<DOMString>,
39}
40
41impl VTTCue {
42 pub(crate) fn new_inherited(start_time: f64, end_time: f64, text: DOMString) -> Self {
43 VTTCue {
44 texttrackcue: TextTrackCue::new_inherited(
45 DOMString::default(),
46 start_time,
47 end_time,
48 None,
49 ),
50 region: DomRefCell::new(None),
51 vertical: Cell::new(DirectionSetting::default()),
52 snap_to_lines: Cell::new(true),
53 line: DomRefCell::new(LineAndPositionSetting::Auto),
54 line_align: Cell::new(LineAlignSetting::Start),
55 position: DomRefCell::new(LineAndPositionSetting::Auto),
56 position_align: Cell::new(PositionAlignSetting::Auto),
57 size: Cell::new(100_f64),
58 align: Cell::new(AlignSetting::Center),
59 text: DomRefCell::new(text),
60 }
61 }
62
63 fn new(
64 window: &Window,
65 proto: Option<HandleObject>,
66 start_time: f64,
67 end_time: f64,
68 text: DOMString,
69 can_gc: CanGc,
70 ) -> DomRoot<Self> {
71 reflect_dom_object_with_proto(
72 Box::new(Self::new_inherited(start_time, end_time, text)),
73 window,
74 proto,
75 can_gc,
76 )
77 }
78}
79
80impl VTTCueMethods<crate::DomTypeHolder> for VTTCue {
81 fn Constructor(
83 window: &Window,
84 proto: Option<HandleObject>,
85 can_gc: CanGc,
86 start_time: Finite<f64>,
87 end_time: Finite<f64>,
88 text: DOMString,
89 ) -> DomRoot<Self> {
90 VTTCue::new(window, proto, *start_time, *end_time, text, can_gc)
91 }
92
93 fn GetRegion(&self) -> Option<DomRoot<VTTRegion>> {
95 self.region
96 .borrow()
97 .as_ref()
98 .map(|r| DomRoot::from_ref(&**r))
99 }
100
101 fn SetRegion(&self, value: Option<&VTTRegion>) {
103 *self.region.borrow_mut() = value.map(Dom::from_ref)
104 }
105
106 fn Vertical(&self) -> DirectionSetting {
108 self.vertical.get()
109 }
110
111 fn SetVertical(&self, value: DirectionSetting) {
113 self.vertical.set(value);
114 }
115
116 fn SnapToLines(&self) -> bool {
118 self.snap_to_lines.get()
119 }
120
121 fn SetSnapToLines(&self, value: bool) {
123 self.snap_to_lines.set(value)
124 }
125
126 fn Line(&self) -> VTTCueBinding::LineAndPositionSetting {
128 VTTCueBinding::LineAndPositionSetting::from(self.line.borrow().clone())
129 }
130
131 fn SetLine(&self, value: VTTCueBinding::LineAndPositionSetting) {
133 *self.line.borrow_mut() = value.into();
134 }
135
136 fn LineAlign(&self) -> LineAlignSetting {
138 self.line_align.get()
139 }
140
141 fn SetLineAlign(&self, value: LineAlignSetting) {
143 self.line_align.set(value);
144 }
145
146 fn Position(&self) -> VTTCueBinding::LineAndPositionSetting {
148 VTTCueBinding::LineAndPositionSetting::from(self.position.borrow().clone())
149 }
150
151 fn SetPosition(&self, value: VTTCueBinding::LineAndPositionSetting) -> ErrorResult {
153 if let VTTCueBinding::LineAndPositionSetting::Double(x) = value {
154 if *x < 0_f64 || *x > 100_f64 {
155 return Err(Error::IndexSize);
156 }
157 }
158
159 *self.position.borrow_mut() = value.into();
160 Ok(())
161 }
162
163 fn PositionAlign(&self) -> PositionAlignSetting {
165 self.position_align.get()
166 }
167
168 fn SetPositionAlign(&self, value: PositionAlignSetting) {
170 self.position_align.set(value);
171 }
172
173 fn Size(&self) -> Finite<f64> {
175 Finite::wrap(self.size.get())
176 }
177
178 fn SetSize(&self, value: Finite<f64>) -> ErrorResult {
180 if *value < 0_f64 || *value > 100_f64 {
181 return Err(Error::IndexSize);
182 }
183
184 self.size.set(*value);
185 Ok(())
186 }
187
188 fn Align(&self) -> AlignSetting {
190 self.align.get()
191 }
192
193 fn SetAlign(&self, value: AlignSetting) {
195 self.align.set(value);
196 }
197
198 fn Text(&self) -> DOMString {
200 self.text.borrow().clone()
201 }
202
203 fn SetText(&self, value: DOMString) {
205 *self.text.borrow_mut() = value;
206 }
207
208 fn GetCueAsHTML(&self) -> DomRoot<DocumentFragment> {
210 todo!()
211 }
212}
213
214#[derive(Clone, JSTraceable, MallocSizeOf)]
215enum LineAndPositionSetting {
216 Double(f64),
217 Auto,
218}
219
220impl From<VTTCueBinding::LineAndPositionSetting> for LineAndPositionSetting {
221 fn from(value: VTTCueBinding::LineAndPositionSetting) -> Self {
222 match value {
223 VTTCueBinding::LineAndPositionSetting::Double(x) => LineAndPositionSetting::Double(*x),
224 VTTCueBinding::LineAndPositionSetting::AutoKeyword(_) => LineAndPositionSetting::Auto,
225 }
226 }
227}
228
229impl From<LineAndPositionSetting> for VTTCueBinding::LineAndPositionSetting {
230 fn from(value: LineAndPositionSetting) -> Self {
231 match value {
232 LineAndPositionSetting::Double(x) => {
233 VTTCueBinding::LineAndPositionSetting::Double(Finite::wrap(x))
234 },
235 LineAndPositionSetting::Auto => {
236 VTTCueBinding::LineAndPositionSetting::AutoKeyword(AutoKeyword::Auto)
237 },
238 }
239 }
240}