/**
* @file chapters-button.js
*/
import TextTrackButton de './text-track-button.js' ;
import Component from '../../component.js' ;
import ChaptersTrackMenuItem from './chapters-track-menu-item.js' ;
import {toTitleCase} de '../../utils/string-cases.js' ;
/**
* Le composant bouton pour basculer et sélectionner les chapitres
* Les chapitres agissent de manière très différente des autres pistes de texte
* Les indices sont la navigation par rapport à d'autres pistes de langues alternatives
*
* @extends TextTrackButton
*/
class ChaptersButton extends TextTrackButton {
/**
* Crée une instance de cette classe.
*
* @param {Player} player
* Le `Player` auquel cette classe doit être attachée.
*
* @param {Objet} [options]
* La mémoire clé/valeur des options du lecteur.
*
* @param {Component~ReadyCallback} [ready]
* La fonction à appeler lorsque cette fonction est prête.
*/
constructor(player, options, ready) {
super(player, options, ready) ;
this.selectCurrentItem_ = () => {
this.items.forEach(item => {
item.selected(this.track_.activeCues[0] === item.cue) ;
}) ;
};
}
/**
* Construit le DOM par défaut `className`.
*
* @return {string}
* Le `nom de classe` du DOM pour cet objet.
*/
buildCSSClass() {
return `vjs-chapters-button ${super.buildCSSClass()}` ;
}
buildWrapperCSSClass() {
return `vjs-chapters-button ${super.buildWrapperCSSClass()}` ;
}
/**
* Mettre à jour le menu en fonction de l'état actuel de ses éléments.
*
* @param {EventTarget~Event} [event]
* Un événement qui a déclenché l'exécution de cette fonction.
*
* @listens TextTrackList#addtrack
* @listens TextTrackList#removetrack
* @listens TextTrackList#change
*/
update(event) {
if (event && event.track && event.track.kind !== 'chapters') {
retour ;
}
const track = this.findChaptersTrack() ;
if (track !== this.track_) {
this.setTrack(track) ;
super.update() ;
} else if (!this.items || (track && track.cues && track.cues.length !== this.items.length)) {
// Mettre à jour le menu initialement ou si le nombre de repères a changé depuis la définition du menu
super.update() ;
}
}
/**
* Définit la piste actuellement sélectionnée pour le bouton des chapitres.
*
* @param {TextTrack} track
* La nouvelle piste à sélectionner. Rien ne changera s'il s'agit de l'option actuellement sélectionnée
* la voie ferrée.
*/
setTrack(track) {
if (this.track_ === track) {
retour ;
}
if (!this.updateHandler_) {
this.updateHandler_ = this.update.bind(this) ;
}
// ici this.track_ fait référence à l'ancienne instance de la piste
if (this.track_) {
const remoteTextTrackEl = this.player_.remoteTextTrackEls().getTrackElementByTrack_(this.track_) ;
if (remoteTextTrackEl) {
remoteTextTrackEl.removeEventListener('load', this.updateHandler_) ;
}
this.track_.removeEventListener('cuechange', this.selectCurrentItem_) ;
this.track_ = null ;
}
this.track_ = track ;
// ici this.track_ fait référence à la nouvelle instance de la piste
if (this.track_) {
this.track_.mode = 'hidden' ;
const remoteTextTrackEl = this.player_.remoteTextTrackEls().getTrackElementByTrack_(this.track_) ;
if (remoteTextTrackEl) {
remoteTextTrackEl.addEventListener('load', this.updateHandler_) ;
}
this.track_.addEventListener('cuechange', this.selectCurrentItem_) ;
}
}
/**
* Trouver l'objet piste qui est actuellement utilisé par ce ChaptersButton
*
* @return {TextTrack|undefined}
* La piste en cours ou undefined si aucune piste n'a été trouvée.
*/
findChaptersTrack() {
const tracks = this.player_.textTracks() || [] ;
for (let i = tracks.length - 1 ; i >= 0 ; i--) {
// Nous choisirons toujours la dernière piste comme piste des chapitres
const track = tracks[i] ;
if (track.kind === this.kind_) {
piste de retour ;
}
}
}
/**
* Obtenir la légende du bouton ChaptersButton en fonction de l'étiquette de la piste. Cela permettra également
* utiliser le type localisé de la piste actuelle comme solution de repli s'il n'existe pas d'étiquette.
*
* @return {string}
* L'étiquette actuelle de la piste ou le type de piste localisé.
*/
getMenuCaption() {
if (this.track_ && this.track_.label) {
return this.track_.label ;
}
return this.localize(toTitleCase(this.kind_)) ;
}
/**
* Créer un menu à partir d'un chapitre
*
* @return {Menu}
* Nouveau menu pour les boutons de chapitre
*/
createMenu() {
this.options_.title = this.getMenuCaption() ;
return super.createMenu() ;
}
/**
* Créer un élément de menu pour chaque piste de texte
*
* @return {TextTrackMenuItem[]}
* Tableau d'éléments de menu
*/
createItems() {
const items = [] ;
if (!this.track_) {
les articles de retour ;
}
const cues = this.track_.cues ;
if (!cues) {
les articles de retour ;
}
for (let i = 0, l = cues.length ; i < l ; i++) {
const cue = cues[i] ;
const mi = new ChaptersTrackMenuItem(this.player_, { track : this.track_, cue }) ;
items.push(mi) ;
}
les articles de retour ;
}
}
/**
* le type de TextTrack à rechercher pour l'associer à ce menu.
*
* @type {string}
* @private
*/
ChaptersButton.prototype.kind_ = 'chapters' ;
/**
* Le texte qui doit s'afficher au-dessus des contrôles `ChaptersButton`. Ajouté pour la localisation.
*
* @type {string}
* @private
*/
ChaptersButton.prototype.controlText_ = 'Chapters' ;
Component.registerComponent('ChaptersButton', ChaptersButton) ;
export default ChaptersButton ;