/**
* @file text-track-menu-item.js
*/
import MenuItem from '../../menu/menu-item.js' ;
import Component from '../../component.js' ;
import window from 'global/window' ;
import document from 'global/document' ;
/**
* Le type d'élément de menu spécifique pour la sélection d'une langue dans un type de piste de texte
*
* @extends MenuItem
*/
class TextTrackMenuItem extends MenuItem {
/**
* 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.
*/
constructor(player, options) {
const track = options.track ;
const tracks = player.textTracks() ;
// Modifier les options pour l'init de la classe MenuItem parente.
options.label = track.label || track.language || 'Unknown' ;
options.selected = track.mode === 'showing' ;
super(player, options) ;
this.track = track ;
// Déterminer le(s) type(s) de pistes pertinent(s) pour ce composant et le filtrer
// des types vides.
this.kinds = (options.kinds || [options.kind || this.track.kind]).filter(Boolean) ;
const changeHandler = (...args) => {
this.handleTracksChange.apply(this, args) ;
};
const selectedLanguageChangeHandler = (...args) => {
this.handleSelectedLanguageChange.apply(this, args) ;
};
player.on(['loadstart', 'texttrackchange'], changeHandler) ;
tracks.addEventListener('change', changeHandler) ;
tracks.addEventListener('selectedlanguagechange', selectedLanguageChangeHandler) ;
this.on('dispose', function() {
player.off(['loadstart', 'texttrackchange'], changeHandler) ;
tracks.removeEventListener('change', changeHandler) ;
tracks.removeEventListener('selectedlanguagechange', selectedLanguageChangeHandler) ;
}) ;
// iOS7 n'envoie pas d'événements de changement aux TextTrackLists lorsqu'un événement de type
// le mode de la piste associée change. Sans quelque chose comme
// Object.observe() (qui n'existe pas non plus sur iOS7), ce n'est pas
// possibilité de détecter les modifications de l'attribut mode et du polyfill
// l'événement de changement. En guise de substitut, nous envoyons manuellement
// des événements de changement chaque fois que les contrôles modifient le mode.
if (tracks.onchange === undefined) {
laisser l'événement ;
this.on(['tap', 'click'], function() {
if (typeof window.Event !== 'object') {
// Android 2.3 génère une erreur de constructeur illégal pour window.Event
essayez {
event = new window.Event('change') ;
} catch (err) {
// continuer sans tenir compte de l'erreur
}
}
if (!event) {
event = document.createEvent('Event') ;
event.initEvent('change', true, true) ;
}
tracks.dispatchEvent(event) ;
}) ;
}
// définir l'état par défaut en fonction des pistes actuelles
this.handleTracksChange() ;
}
/**
* Cette fonction est appelée lorsqu'un `TextTrackMenuItem` est "cliqué". Voir
* {@link ClickableComponent} pour des informations plus détaillées sur ce que peut être un clic.
*
* @param {EventTarget~Event} event
* L'événement `keydown`, `tap` ou `click` qui a provoqué l'activation de cette fonction est le suivant
* appelé.
*
* @listens tap
* @listens click
*/
handleClick(event) {
const referenceTrack = this.track ;
const tracks = this.player_.textTracks() ;
super.handleClick(event) ;
if (!tracks) {
retour ;
}
for (let i = 0 ; i < tracks.length ; i++) {
const track = tracks[i] ;
// Si la piste de la liste des pistes de texte n'est pas du bon type,
// passer à l'étape suivante. Nous ne voulons pas affecter les pistes d'un ou de plusieurs types incompatibles.
if (this.kinds.indexOf(track.kind) === -1) {
continuer ;
}
// Si cette piste de texte est la piste du composant et qu'elle n'est pas affichée,
// l'afficher.
if (track === referenceTrack) {
if (track.mode !== 'showing') {
track.mode = 'showing' ;
}
// Si cette piste de texte n'est pas la piste du composant et qu'elle n'est pas
// désactivé, lui attribuer la valeur "désactivé".
} else if (track.mode !== 'disabled') {
track.mode = 'disabled' ;
}
}
}
/**
* Gestion des modifications de la liste des pistes de texte
*
* @param {EventTarget~Event} event
* L'événement `change` qui a provoqué l'appel de cette fonction.
*
* @listens TextTrackList#change
*/
handleTracksChange(event) {
const shouldBeSelected = this.track.mode === 'showing' ;
// Empêchez les appels redondants à selected(), car ils peuvent causer des problèmes d'accès à l'information
// les lecteurs d'écran lisent inutilement le texte de contrôle annexé
if (shouldBeSelected !== this.isSelected_) {
this.selected(shouldBeSelected) ;
}
}
handleSelectedLanguageChange(event) {
if (this.track.mode === 'showing') {
const selectedLanguage = this.player_.cache_.selectedLanguage ;
// Ne pas remplacer le type de piste dans la même langue
if (selectedLanguage && selectedLanguage.enabled &&
selectedLanguage.language === this.track.language &&
selectedLanguage.kind !== this.track.kind) {
retour ;
}
this.player_.cache_.selectedLanguage = {
activé : vrai,
langue : this.track.language,
kind : this.track.kind
};
}
}
dispose() {
// supprimer la référence à l'objet piste lors de l'élimination
this.track = null ;
super.dispose() ;
}
}
Component.registerComponent('TextTrackMenuItem', TextTrackMenuItem) ;
export default TextTrackMenuItem ;