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}