Skip to main content

script/dom/webvtt/
texttrackcue.rs

1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
5use std::cell::Cell;
6use std::cmp::Ordering;
7
8use dom_struct::dom_struct;
9use script_bindings::cell::DomRefCell;
10use script_bindings::domstring::TracedDOMString;
11
12use crate::dom::bindings::codegen::Bindings::TextTrackCueBinding::TextTrackCueMethods;
13use crate::dom::bindings::num::Finite;
14use crate::dom::bindings::root::{DomRoot, MutNullableDom};
15use crate::dom::bindings::str::DOMString;
16use crate::dom::eventtarget::EventTarget;
17use crate::dom::node::Node;
18use crate::dom::texttrack::TextTrack;
19use crate::dom::webvtt::rules_for_rendering::RulesForUpdatingTheTextTrackRendering;
20
21#[dom_struct]
22pub(crate) struct TextTrackCue {
23    eventtarget: EventTarget,
24    /// <https://html.spec.whatwg.org/multipage/#text-track-cue-identifier>
25    id: DomRefCell<TracedDOMString>,
26    /// <https://html.spec.whatwg.org/multipage/#dom-texttrackcue-track>
27    text_track: MutNullableDom<TextTrack>,
28    /// <https://html.spec.whatwg.org/multipage/#text-track-cue-start-time>
29    start_time: Cell<f64>,
30    /// <https://html.spec.whatwg.org/multipage/#text-track-cue-end-time>
31    end_time: Cell<f64>,
32    /// <https://html.spec.whatwg.org/multipage/#text-track-cue-pause-on-exit-flag>
33    pause_on_exit: Cell<bool>,
34    /// <https://html.spec.whatwg.org/multipage/#text-track-cue-active-flag>
35    active: Cell<bool>,
36    /// <https://html.spec.whatwg.org/multipage/#text-track-cue-order>
37    /// > in the order they were last added to their respective
38    /// > text track list of cues, oldest first
39    initial_index_in_list: Cell<usize>,
40    /// <https://html.spec.whatwg.org/multipage/#rules-for-updating-the-text-track-rendering>
41    rules_for_updating_the_text_track_rendering: RulesForUpdatingTheTextTrackRendering,
42    /// <https://html.spec.whatwg.org/multipage/#text-track-cue-display-state>
43    display_state: MutNullableDom<Node>,
44}
45
46impl TextTrackCue {
47    pub(crate) fn new_inherited(
48        id: DOMString,
49        start_time: f64,
50        end_time: f64,
51        text_track: Option<&TextTrack>,
52        rules_for_updating_the_text_track_rendering: RulesForUpdatingTheTextTrackRendering,
53    ) -> TextTrackCue {
54        TextTrackCue {
55            eventtarget: EventTarget::new_inherited(),
56            id: DomRefCell::new(id.traced()),
57            text_track: MutNullableDom::new(text_track),
58            start_time: Cell::new(start_time),
59            end_time: Cell::new(end_time),
60            pause_on_exit: Cell::new(false),
61            active: Default::default(),
62            initial_index_in_list: Default::default(),
63            rules_for_updating_the_text_track_rendering,
64            display_state: Default::default(),
65        }
66    }
67
68    pub(crate) fn id(&self) -> DOMString {
69        self.id.borrow().clone().root()
70    }
71
72    pub(crate) fn get_text_track(&self) -> Option<DomRoot<TextTrack>> {
73        self.text_track.get()
74    }
75
76    pub(crate) fn set_text_track(&self, text_track: Option<&TextTrack>) {
77        self.text_track.set(text_track);
78    }
79
80    pub(crate) fn start_time(&self) -> f64 {
81        self.start_time.get()
82    }
83
84    pub(crate) fn end_time(&self) -> f64 {
85        self.end_time.get()
86    }
87
88    pub(crate) fn is_active(&self) -> bool {
89        self.active.get()
90    }
91
92    pub(crate) fn set_active(&self, active: bool) {
93        self.active.set(active)
94    }
95
96    pub(crate) fn set_initial_index_in_list(&self, initial_index_in_list: usize) {
97        self.initial_index_in_list.set(initial_index_in_list);
98    }
99
100    /// <https://html.spec.whatwg.org/multipage/#rules-for-updating-the-text-track-rendering>
101    pub(crate) fn rules_for_updating_the_text_track_rendering(
102        &self,
103    ) -> RulesForUpdatingTheTextTrackRendering {
104        // https://html.spec.whatwg.org/multipage/#text-track-model:rules-for-updating-the-text-track-rendering
105        // > A text track cue is associated with rules for updating the text track rendering,
106        // > as defined by the specification for the specific kind of text track cue.
107        // > These rules are used specifically when the object representing the cue
108        // > is added to a TextTrack object using the addCue() method.
109        self.rules_for_updating_the_text_track_rendering
110    }
111
112    pub(crate) fn display_state(&self) -> Option<DomRoot<Node>> {
113        self.display_state.get()
114    }
115
116    pub(crate) fn set_display_state(&self, display_state: Option<&Node>) {
117        self.display_state.set(display_state)
118    }
119}
120
121impl TextTrackCueMethods<crate::DomTypeHolder> for TextTrackCue {
122    /// <https://html.spec.whatwg.org/multipage/#dom-texttrackcue-id>
123    fn Id(&self) -> DOMString {
124        self.id()
125    }
126
127    /// <https://html.spec.whatwg.org/multipage/#dom-texttrackcue-id>
128    fn SetId(&self, value: DOMString) {
129        *self.id.borrow_mut() = value.traced();
130    }
131
132    /// <https://html.spec.whatwg.org/multipage/#dom-texttrackcue-track>
133    fn GetTrack(&self) -> Option<DomRoot<TextTrack>> {
134        self.get_text_track()
135    }
136
137    /// <https://html.spec.whatwg.org/multipage/#dom-texttrackcue-starttime>
138    fn StartTime(&self) -> Finite<f64> {
139        Finite::wrap(self.start_time.get())
140    }
141
142    /// <https://html.spec.whatwg.org/multipage/#dom-texttrackcue-starttime>
143    fn SetStartTime(&self, value: Finite<f64>) {
144        self.start_time.set(*value);
145        if let Some(text_track) = self.text_track.get() {
146            text_track.sort_cue_list();
147        }
148    }
149
150    /// <https://html.spec.whatwg.org/multipage/#dom-texttrackcue-endtime>
151    fn EndTime(&self) -> Finite<f64> {
152        Finite::wrap(self.end_time.get())
153    }
154
155    /// <https://html.spec.whatwg.org/multipage/#dom-texttrackcue-endtime>
156    fn SetEndTime(&self, value: Finite<f64>) {
157        self.end_time.set(*value);
158        if let Some(text_track) = self.text_track.get() {
159            text_track.sort_cue_list();
160        }
161    }
162
163    /// <https://html.spec.whatwg.org/multipage/#dom-texttrackcue-pauseonexit>
164    fn PauseOnExit(&self) -> bool {
165        self.pause_on_exit.get()
166    }
167
168    /// <https://html.spec.whatwg.org/multipage/#dom-texttrackcue-pauseonexit>
169    fn SetPauseOnExit(&self, value: bool) {
170        self.pause_on_exit.set(value);
171    }
172
173    // https://html.spec.whatwg.org/multipage/#handler-texttrackcue-onenter
174    event_handler!(enter, GetOnenter, SetOnenter);
175
176    // https://html.spec.whatwg.org/multipage/#handler-texttrackcue-onexit
177    event_handler!(exit, GetOnexit, SetOnexit);
178}
179
180impl PartialOrd for TextTrackCue {
181    #[inline]
182    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
183        Some(self.cmp(other))
184    }
185}
186
187impl Ord for TextTrackCue {
188    /// <https://html.spec.whatwg.org/multipage/#text-track-cue-order>
189    fn cmp(&self, other: &TextTrackCue) -> Ordering {
190        // > cues must be sorted by their start time, earliest first;
191        self.start_time
192            .get()
193            .total_cmp(&other.start_time.get())
194            .then_with(|| {
195                // > then, any cues with the same start time must be sorted by their end time, latest first;
196                self.end_time
197                    .get()
198                    .total_cmp(&other.end_time.get())
199                    .reverse()
200                    .then_with(|| {
201                        // > and finally, any cues with identical end times must be sorted in the order
202                        // > they were last added to their respective text track list of cues,
203                        // > oldest first (so e.g. for cues from a WebVTT file,
204                        // > that would initially be the order in which the cues were listed in the file).
205                        self.initial_index_in_list
206                            .get()
207                            .cmp(&other.initial_index_in_list.get())
208                    })
209            })
210    }
211}