Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add the basics of TextTrack #22392

Merged
merged 2 commits into from Dec 11, 2018
Merged
Changes from all commits
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

@@ -1,6 +1,7 @@
DOMContentLoaded
abort
activate
addtrack
beforeunload
button
canplay
@@ -69,6 +70,7 @@ range
readystatechange
reftest-wait
rejectionhandled
removetrack
reset
resize
right
@@ -12,6 +12,7 @@ use crate::dom::bindings::codegen::Bindings::HTMLMediaElementBinding::HTMLMediaE
use crate::dom::bindings::codegen::Bindings::HTMLSourceElementBinding::HTMLSourceElementMethods;
use crate::dom::bindings::codegen::Bindings::MediaErrorBinding::MediaErrorConstants::*;
use crate::dom::bindings::codegen::Bindings::MediaErrorBinding::MediaErrorMethods;
use crate::dom::bindings::codegen::Bindings::TextTrackBinding::{TextTrackKind, TextTrackMode};
use crate::dom::bindings::codegen::InheritTypes::{ElementTypeId, HTMLElementTypeId};
use crate::dom::bindings::codegen::InheritTypes::{HTMLMediaElementTypeId, NodeTypeId};
use crate::dom::bindings::error::{Error, ErrorResult};
@@ -33,6 +34,8 @@ use crate::dom::mediaerror::MediaError;
use crate::dom::node::{document_from_node, window_from_node, Node, NodeDamage, UnbindContext};
use crate::dom::performanceresourcetiming::InitiatorType;
use crate::dom::promise::Promise;
use crate::dom::texttrack::TextTrack;
use crate::dom::texttracklist::TextTrackList;
use crate::dom::timeranges::{TimeRanges, TimeRangesContainer};
use crate::dom::virtualmethods::VirtualMethods;
use crate::fetch::FetchCanceller;
@@ -191,6 +194,8 @@ pub struct HTMLMediaElement {
/// https://html.spec.whatwg.org/multipage/#dom-media-played
#[ignore_malloc_size_of = "Rc"]
played: Rc<DomRefCell<TimeRangesContainer>>,
/// https://html.spec.whatwg.org/multipage/#dom-media-texttracks
text_tracks_list: MutNullableDom<TextTrackList>,
}

/// <https://html.spec.whatwg.org/multipage/#dom-media-networkstate>
@@ -243,6 +248,7 @@ impl HTMLMediaElement {
seeking: Cell::new(false),
resource_url: DomRefCell::new(None),
played: Rc::new(DomRefCell::new(TimeRangesContainer::new())),
text_tracks_list: Default::default(),
}
}

@@ -1376,6 +1382,37 @@ impl HTMLMediaElementMethods for HTMLMediaElement {
fn Played(&self) -> DomRoot<TimeRanges> {
TimeRanges::new(self.global().as_window(), self.played.clone())
}

// https://html.spec.whatwg.org/multipage/#dom-media-texttracks
fn TextTracks(&self) -> DomRoot<TextTrackList> {
let window = window_from_node(self);
self.text_tracks_list
.or_init(|| TextTrackList::new(&window, &[]))
}

// https://html.spec.whatwg.org/multipage/#dom-media-addtexttrack
fn AddTextTrack(
&self,
kind: TextTrackKind,
label: DOMString,
language: DOMString,
) -> DomRoot<TextTrack> {
let window = window_from_node(self);
// Step 1 & 2
// FIXME(#22314, dlrobertson) set the ready state to Loaded
let track = TextTrack::new(
&window,
"".into(),
kind,
label,
language,
TextTrackMode::Hidden,
);
// Step 3 & 4
self.TextTracks().add(&track);
// Step 5
DomRoot::from_ref(&track)
}
}

impl VirtualMethods for HTMLMediaElement {
@@ -460,6 +460,10 @@ pub mod text;
pub mod textcontrol;
pub mod textdecoder;
pub mod textencoder;
pub mod texttrack;
pub mod texttrackcue;
pub mod texttrackcuelist;
pub mod texttracklist;
pub mod timeranges;
pub mod touch;
pub mod touchevent;
@@ -0,0 +1,145 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */

use crate::dom::bindings::codegen::Bindings::TextTrackBinding::{
self, TextTrackKind, TextTrackMethods, TextTrackMode,
};
use crate::dom::bindings::error::{Error, ErrorResult};
use crate::dom::bindings::reflector::{reflect_dom_object, DomObject};
use crate::dom::bindings::root::{DomRoot, MutNullableDom};
use crate::dom::bindings::str::DOMString;
use crate::dom::eventtarget::EventTarget;
use crate::dom::texttrackcue::TextTrackCue;
use crate::dom::texttrackcuelist::TextTrackCueList;
use crate::dom::window::Window;
use dom_struct::dom_struct;
use std::cell::Cell;

#[dom_struct]
pub struct TextTrack {
eventtarget: EventTarget,
kind: TextTrackKind,
label: String,
language: String,
id: String,
mode: Cell<TextTrackMode>,
cue_list: MutNullableDom<TextTrackCueList>,
}

impl TextTrack {
pub fn new_inherited(
id: DOMString,
kind: TextTrackKind,
label: DOMString,
language: DOMString,
mode: TextTrackMode,
) -> TextTrack {
TextTrack {
eventtarget: EventTarget::new_inherited(),
kind: kind,
label: label.into(),
language: language.into(),
id: id.into(),
mode: Cell::new(mode),
cue_list: Default::default(),
}
}

pub fn new(
window: &Window,
id: DOMString,
kind: TextTrackKind,
label: DOMString,
language: DOMString,
mode: TextTrackMode,
) -> DomRoot<TextTrack> {
reflect_dom_object(
Box::new(TextTrack::new_inherited(id, kind, label, language, mode)),
window,
TextTrackBinding::Wrap,
)
}

pub fn get_cues(&self) -> DomRoot<TextTrackCueList> {
self.cue_list
.or_init(|| TextTrackCueList::new(&self.global().as_window(), &[]))
}

pub fn id(&self) -> &str {
&self.id
}
}

impl TextTrackMethods for TextTrack {
// https://html.spec.whatwg.org/multipage/#dom-texttrack-kind
fn Kind(&self) -> TextTrackKind {
self.kind
}

// https://html.spec.whatwg.org/multipage/#dom-texttrack-label
fn Label(&self) -> DOMString {
DOMString::from(self.label.clone())
}

// https://html.spec.whatwg.org/multipage/#dom-texttrack-language
fn Language(&self) -> DOMString {
DOMString::from(self.language.clone())
}

// https://html.spec.whatwg.org/multipage/#dom-texttrack-id
fn Id(&self) -> DOMString {
DOMString::from(self.id.clone())
}

// https://html.spec.whatwg.org/multipage/#dom-texttrack-mode
fn Mode(&self) -> TextTrackMode {
self.mode.get()
}

// https://html.spec.whatwg.org/multipage/#dom-texttrack-mode
fn SetMode(&self, value: TextTrackMode) {
self.mode.set(value)
}

// https://html.spec.whatwg.org/multipage/#dom-texttrack-cues
fn GetCues(&self) -> Option<DomRoot<TextTrackCueList>> {
match self.Mode() {
TextTrackMode::Disabled => None,
_ => Some(self.get_cues()),
}
}

// https://html.spec.whatwg.org/multipage/#dom-texttrack-addcue
fn AddCue(&self, cue: &TextTrackCue) -> ErrorResult {
// FIXME(#22314, dlrobertson) add Step 1 & 2
// Step 3
if let Some(old_track) = cue.get_track() {
// gecko calls RemoveCue when the given cue
// has an associated track, but doesn't return
// the error from it, so we wont either.
if let Err(_) = old_track.RemoveCue(cue) {
warn!("Failed to remove cues for the added cue's text track");
}
}
// Step 4
self.get_cues().add(cue);
Ok(())
}

// https://html.spec.whatwg.org/multipage/#dom-texttrack-removecue
fn RemoveCue(&self, cue: &TextTrackCue) -> ErrorResult {
// Step 1
let cues = self.get_cues();
let index = match cues.find(cue) {
Some(i) => Ok(i),
None => Err(Error::NotFound),
}?;
// Step 2
cues.remove(index);
Ok(())
}

// https://html.spec.whatwg.org/multipage/#handler-texttrack-oncuechange
event_handler!(oncuechange, GetOncuechange, SetOncuechange);
}
@@ -0,0 +1,111 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */

use crate::dom::bindings::cell::DomRefCell;
use crate::dom::bindings::codegen::Bindings::TextTrackCueBinding::{self, TextTrackCueMethods};
use crate::dom::bindings::num::Finite;
use crate::dom::bindings::reflector::reflect_dom_object;
use crate::dom::bindings::root::{Dom, DomRoot};
use crate::dom::bindings::str::DOMString;
use crate::dom::eventtarget::EventTarget;
use crate::dom::texttrack::TextTrack;
use crate::dom::window::Window;
use dom_struct::dom_struct;
use std::cell::Cell;

#[dom_struct]
pub struct TextTrackCue {
eventtarget: EventTarget,
id: DomRefCell<DOMString>,
track: Option<Dom<TextTrack>>,
start_time: Cell<f64>,
end_time: Cell<f64>,
pause_on_exit: Cell<bool>,
}

impl TextTrackCue {
// FIXME(#22314, dlrobertson) implement VTTCue.
#[allow(dead_code)]
pub fn new_inherited(id: DOMString, track: Option<&TextTrack>) -> TextTrackCue {
TextTrackCue {
eventtarget: EventTarget::new_inherited(),
id: DomRefCell::new(id),
track: track.map(Dom::from_ref),
start_time: Cell::new(0.),
end_time: Cell::new(0.),
pause_on_exit: Cell::new(false),
}
}

// FIXME(#22314, dlrobertson) implement VTTCue.
#[allow(dead_code)]
pub fn new(window: &Window, id: DOMString, track: Option<&TextTrack>) -> DomRoot<TextTrackCue> {
reflect_dom_object(
Box::new(TextTrackCue::new_inherited(id, track)),
window,
TextTrackCueBinding::Wrap,
)
}

pub fn id(&self) -> DOMString {
self.id.borrow().clone()
}

pub fn get_track(&self) -> Option<DomRoot<TextTrack>> {
self.track.as_ref().map(|t| DomRoot::from_ref(&**t))
}
}

impl TextTrackCueMethods for TextTrackCue {
// https://html.spec.whatwg.org/multipage/#dom-texttrackcue-id
fn Id(&self) -> DOMString {
self.id()
}

// https://html.spec.whatwg.org/multipage/#dom-texttrackcue-id
fn SetId(&self, value: DOMString) {
*self.id.borrow_mut() = value;
}

// https://html.spec.whatwg.org/multipage/#dom-texttrackcue-track
fn GetTrack(&self) -> Option<DomRoot<TextTrack>> {
self.get_track()
}

// https://html.spec.whatwg.org/multipage/#dom-texttrackcue-starttime
fn StartTime(&self) -> Finite<f64> {
Finite::wrap(self.start_time.get())
}

// https://html.spec.whatwg.org/multipage/#dom-texttrackcue-starttime
fn SetStartTime(&self, value: Finite<f64>) {
self.start_time.set(*value);
}

// https://html.spec.whatwg.org/multipage/#dom-texttrackcue-endtime
fn EndTime(&self) -> Finite<f64> {
Finite::wrap(self.end_time.get())
}

// https://html.spec.whatwg.org/multipage/#dom-texttrackcue-endtime
fn SetEndTime(&self, value: Finite<f64>) {
self.end_time.set(*value);
}

// https://html.spec.whatwg.org/multipage/#dom-texttrackcue-pauseonexit
fn PauseOnExit(&self) -> bool {
self.pause_on_exit.get()
}

// https://html.spec.whatwg.org/multipage/#dom-texttrackcue-pauseonexit
fn SetPauseOnExit(&self, value: bool) {
self.pause_on_exit.set(value);
}

// https://html.spec.whatwg.org/multipage/#handler-texttrackcue-onenter
event_handler!(onenter, GetOnenter, SetOnenter);

// https://html.spec.whatwg.org/multipage/#handler-texttrackcue-onexit
event_handler!(onexit, GetOnexit, SetOnexit);
}
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.