Skip to main content

script/dom/webvtt/
rules_for_rendering.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 js::context::JSContext;
6use script_bindings::dom::UnrootedDom;
7use script_bindings::root::DomRoot;
8use script_bindings::str::DOMString;
9
10use crate::dom::bindings::codegen::Bindings::TextTrackBinding::{TextTrackMethods, TextTrackMode};
11use crate::dom::html::htmlmediaelement::HTMLMediaElement;
12use crate::dom::html::htmlvideoelement::HTMLVideoElement;
13use crate::dom::texttrack::TextTrack;
14use crate::dom::texttrackcue::TextTrackCue;
15use crate::script_bindings::inheritance::Castable;
16
17#[derive(PartialEq)]
18pub(crate) enum ShouldResetRenderingControls {
19    Yes,
20    No,
21}
22
23/// <https://html.spec.whatwg.org/multipage/#rules-for-updating-the-text-track-rendering>
24#[derive(Clone, Copy, JSTraceable, MallocSizeOf, PartialEq)]
25pub(crate) enum RulesForUpdatingTheTextTrackRendering {
26    /// <https://w3c.github.io/webvtt/#rules-for-updating-the-display-of-webvtt-text-tracks>
27    WebVTT,
28}
29
30impl RulesForUpdatingTheTextTrackRendering {
31    pub(crate) fn run(
32        &self,
33        cx: &mut JSContext,
34        media_element: &HTMLMediaElement,
35        text_tracks: Vec<DomRoot<TextTrack>>,
36        _language: Option<DOMString>,
37        _reset: ShouldResetRenderingControls,
38    ) {
39        debug_assert!(*self == RulesForUpdatingTheTextTrackRendering::WebVTT);
40        // https://w3c.github.io/webvtt/#rules-for-updating-the-display-of-webvtt-text-tracks
41        // Step 2. Let video be the media element or other playback mechanism.
42        if !media_element.is::<HTMLVideoElement>() {
43            // Step 1. If the media element is an audio element,
44            // or is another playback mechanism with no rendering area,
45            // abort these steps.
46            return;
47        };
48
49        // Step 3. Let output be an empty list of absolutely positioned CSS block boxes.
50        // Step 4. If the user agent is exposing a user interface for video,
51        // add to output one or more completely transparent positioned CSS block boxes
52        // that cover the same region as the user interface.
53        //
54        // All of these are handled by modifying the DOM, which in turn will invalidate
55        // the layout of the video element
56
57        // Step 5. If the last time these rules were run,
58        // the user agent was not exposing a user interface for video,
59        // but now it is, optionally let reset be true.
60        // Otherwise, let reset be false.
61        //
62        // Passed in as argument
63
64        // Step 6. Let tracks be the subset of video’s list of text tracks
65        // that have as their rules for updating the text track rendering
66        // these rules for updating the display of WebVTT text tracks,
67        // and whose text track mode is showing.
68        let tracks: Vec<DomRoot<TextTrack>> = text_tracks
69            .into_iter()
70            .filter(|text_track| {
71                let is_showing = text_track.Mode() == TextTrackMode::Showing;
72                debug_assert!(
73                    !is_showing ||
74                        text_track
75                            .rules_for_updating_the_text_track_rendering()
76                            .is_some_and(
77                                |rules| rules == RulesForUpdatingTheTextTrackRendering::WebVTT
78                            )
79                );
80                is_showing
81            })
82            .collect();
83
84        // Step 7. Let cues be an empty list of text track cues.
85        // Step 8. For each track track in tracks,
86        // append to cues all the cues from track’s list of cues
87        // that have their text track cue active flag set.
88        let _cues: Vec<DomRoot<TextTrackCue>> = tracks
89            .iter()
90            .flat_map(|track| {
91                track
92                    .cues(cx.no_gc())
93                    .into_iter()
94                    .filter(|cue| cue.is_active())
95                    .collect::<Vec<UnrootedDom<'_, TextTrackCue>>>()
96            })
97            .map(|cue| cue.as_rooted())
98            .collect();
99    }
100}