/**
* @file progress-control.js
*/
import Component from '../../component.js' ;
import * as Dom from '../../utils/dom.js' ;
import clamp from '../../utils/clamp.js' ;
import {bind, throttle, UPDATE_REFRESH_INTERVAL} from '../../utils/fn.js' ;
import {silencePromesse} de '../../utils/promesse' ;
import './seek-bar.js' ;
/**
* Le composant Progress Control contient la barre de recherche, la progression du chargement,
* et la progression du jeu.
*
* @extends Component
*/
class ProgressControl extends Component {
/**
* 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) {
super(player, options) ;
this.handleMouseMove = throttle(bind(this, this.handleMouseMove), UPDATE_REFRESH_INTERVAL) ;
this.throttledHandleMouseSeek = throttle(bind(this, this.handleMouseSeek), UPDATE_REFRESH_INTERVAL) ;
this.handleMouseUpHandler_ = (e) => this.handleMouseUp(e) ;
this.handleMouseDownHandler_ = (e) => this.handleMouseDown(e) ;
this.enable() ;
}
/**
* Créer l'élément DOM du `Composant`
*
* @return {Element}
* L'élément qui a été créé.
*/
createEl() {
return super.createEl('div', {
className : 'vjs-progress-control vjs-control'
}) ;
}
/**
* Lorsque la souris passe au-dessus du `ProgressControl`, la position du pointeur
* est transmise au composant `MouseTimeDisplay`.
*
* @param {EventTarget~Event} event
* L'événement `mousemove` qui a provoqué l'exécution de cette fonction.
*
* @listen mousemove
*/
handleMouseMove(event) {
const seekBar = this.getChild('seekBar') ;
if (!seekBar) {
retour ;
}
const playProgressBar = seekBar.getChild('playProgressBar') ;
const mouseTimeDisplay = seekBar.getChild('mouseTimeDisplay') ;
if (!playProgressBar && !mouseTimeDisplay) {
retour ;
}
const seekBarEl = seekBar.el() ;
const seekBarRect = Dom.findPosition(seekBarEl) ;
let seekBarPoint = Dom.getPointerPosition(seekBarEl, event).x ;
// Le skin par défaut a un espace de chaque côté de la `SeekBar`. Cela signifie que
// qu'il est possible de déclencher ce comportement en dehors des limites de la catégorie
// la `SeekBar`. Cela nous permet de nous y tenir à tout moment.
seekBarPoint = clamp(seekBarPoint, 0, 1) ;
if (mouseTimeDisplay) {
mouseTimeDisplay.update(seekBarRect, seekBarPoint) ;
}
if (playProgressBar) {
playProgressBar.update(seekBarRect, seekBar.getProgress()) ;
}
}
/**
* Une version réduite de l'écouteur {@link ProgressControl#handleMouseSeek}.
*
* @method ProgressControl#throttledHandleMouseSeek
* @param {EventTarget~Event} event
* L'événement `mousemove` qui a provoqué l'exécution de cette fonction.
*
* @listen mousemove
* @listen touchmove
*/
/**
* Gère les événements `mousemove` ou `touchmove` sur le `ProgressControl`.
*
* @param {EventTarget~Event} event
* événement `mousedown` ou `touchstart` qui a déclenché cette fonction
*
* @listens mousemove
* @listens touchmove
*/
handleMouseSeek(event) {
const seekBar = this.getChild('seekBar') ;
if (seekBar) {
seekBar.handleMouseMove(event) ;
}
}
/**
* Des contrôles sont actuellement activés pour ce contrôle de progression.
*
* @return {boolean}
* true si les contrôles sont activés, false sinon
*/
enabled() {
return this.enabled_ ;
}
/**
* Désactiver tous les contrôles sur le contrôle de progression et ses enfants
*/
disable() {
this.children().forEach((child) => child.disable && child.disable()) ;
if (!this.enabled()) {
retour ;
}
this.off(['mousedown', 'touchstart'], this.handleMouseDownHandler_) ;
this.off(this.el_, 'mousemove', this.handleMouseMove) ;
this.removeListenersAddedOnMousedownAndTouchstart() ;
this.addClass('disabled') ;
this.enabled_ = false ;
// Rétablir l'état normal de la lecture si les commandes sont désactivées pendant le balayage
if (this.player_.scrubbing()) {
const seekBar = this.getChild('seekBar') ;
this.player_.scrubbing(false) ;
if (seekBar.videoWasPlaying) {
silencePromesse(this.player_.play()) ;
}
}
}
/**
* Activer tous les contrôles sur le contrôle de progression et ses enfants
*/
enable() {
this.children().forEach((child) => child.enable && child.enable()) ;
if (this.enabled()) {
retour ;
}
this.on(['mousedown', 'touchstart'], this.handleMouseDownHandler_) ;
this.on(this.el_, 'mousemove', this.handleMouseMove) ;
this.removeClass('disabled') ;
this.enabled_ = true ;
}
/**
* Écouteurs de nettoyage après que l'utilisateur a fini d'interagir avec les contrôles de progression
*/
removeListenersAddedOnMousedownAndTouchstart() {
const doc = this.el_.ownerDocument ;
this.off(doc, 'mousemove', this.throttledHandleMouseSeek) ;
this.off(doc, 'touchmove', this.throttledHandleMouseSeek) ;
this.off(doc, 'mouseup', this.handleMouseUpHandler_) ;
this.off(doc, 'touchend', this.handleMouseUpHandler_) ;
}
/**
* Gère les événements `mousedown` ou `touchstart` sur le `ProgressControl`.
*
* @param {EventTarget~Event} event
* événement `mousedown` ou `touchstart` qui a déclenché cette fonction
*
* @listens mousedown
* @listens touchstart
*/
handleMouseDown(event) {
const doc = this.el_.ownerDocument ;
const seekBar = this.getChild('seekBar') ;
if (seekBar) {
seekBar.handleMouseDown(event) ;
}
this.on(doc, 'mousemove', this.throttledHandleMouseSeek) ;
this.on(doc, 'touchmove', this.throttledHandleMouseSeek) ;
this.on(doc, 'mouseup', this.handleMouseUpHandler_) ;
this.on(doc, 'touchend', this.handleMouseUpHandler_) ;
}
/**
* Gère les événements `mouseup` ou `touchend` sur le `ProgressControl`.
*
* @param {EventTarget~Event} event
* l'événement `mouseup` ou `touchend` qui a déclenché cette fonction.
*
* @listens touchend
* @listens mouseup
*/
handleMouseUp(event) {
const seekBar = this.getChild('seekBar') ;
if (seekBar) {
seekBar.handleMouseUp(event) ;
}
this.removeListenersAddedOnMousedownAndTouchstart() ;
}
}
/**
* Options par défaut pour `ProgressControl` (contrôle de progression)
*
* @type {Objet}
* @private
*/
ProgressControl.prototype.options_ = {
enfants : [
seekBar" (barre de recherche)
]
};
Component.registerComponent('ProgressControl', ProgressControl) ;
export default ProgressControl ;