/**
 * @file slider.js
 * /
importiere Komponente aus '../component.js';
import * as Dom from '../utils/dom.js';
importiere {assign} von '../utils/obj';
importiere {IS_CHROME} aus '.. /utils/browser.js ';
Klammer aus '.. importieren /utils/clamp.js ';
import keycode from 'keycode';

/**
 * Die Basisfunktionalität für einen Slider. Kann vertikal oder horizontal sein.
 * Zum Beispiel ist die Lautstärkeleiste oder die Suchleiste in einem Video ein Schieberegler.
 *
 * @erweitert Komponente
 * /
Klasse Slider erweitert Komponente {

  /**
 * Eine Instanz dieser Klasse erstellen
 *
 * @param {Player} Spieler
 *        Der `Player`, dem diese Klasse zugeordnet werden soll.
 *
 * @param {Object} [Optionen]
 *        Der Schlüssel/Wertspeicher der Playeroptionen.
 * /
  constructor(spieler, optionen) {
    super(Spieler, Optionen);

    this.handleMouseDown_ = (e) => this.handleMouseDown (e);
    this.handleMouseUp_ = (e) => this.handleMouseUp (e);
    this.handleKeyDown_ = (e) => this.handleKeyDown(e);
    this.handleClick_ = (e) => this.handleClick(e);
    this.handleMouseMove_ = (e) => this.handleMouseMove (e);
    this.update_ = (e) => this.update(e);

    //Setze Eigenschaftsnamen auf die Leiste, damit sie mit der untergeordneten Slider-Klasse übereinstimmen, nach der Slider gesucht wird
    this.bar = this.getChild (this.options_.barName);

    //Lege je nach Slider-Typ eine horizontale oder vertikale Klasse auf dem Slider fest
    diese.vertical (!! this.options_.vertical);

    this.enable();
  }

  /**
   * Sind die Steuerelemente für diesen Slider derzeit aktiviert oder nicht?
   *
   * @return {boolean}
   *         true, wenn die Kontrollen aktiviert sind, sonst false
   * /
  aktiviert() {
    return this.enabled_;
  }

  /**
   * Aktiviere die Steuerelemente für diesen Slider, falls sie deaktiviert sind
   * /
  enable() {
    if (this.enabled()) {
      rückkehr;
    }

    this.on ('mousedown', this.handleMouseDown_);
    this.on ('touchstart', this.handleMouseDown_);
    this.on('keydown', this.handleKeyDown_);
    this.on ('klick', this.handleClick_);

    //TODO: veraltet, controlsvisible scheint nicht abgefeuert zu werden
    this.on (this.player_, 'controlsvisible', this.update);

    if (this.playerEvent) {
      this.on (this.player_, this.playerEvent, this.update);
    }

    this.removeClass('disabled');
    this.setAttribute ('tabindex', 0);

    this.enabled_ = true;
  }

  /**
   * Deaktiviere die Steuerelemente für diesen Slider, falls sie aktiviert sind
   * /
  deaktivieren() {
    if (!this.enabled()) {
      rückkehr;
    }
    const doc = this.bar.el_.ownerDocument;

    this.off ('mousedown', this.handleMouseDown_);
    this.off ('touchstart', this.handleMouseDown_);
    this.off('keydown', this.handleKeyDown_);
    this.off ('klick', this.handleClick_);
    this.off (this.player_, 'controlsvisible', this.update_);
    this.off(doc, 'mousemove', this.handleMouseMove_);
    this.off(doc, 'mouseup', this.handleMouseUp_);
    this.off(doc, 'touchmove', this.handleMouseMove_);
    this.off(doc, 'touchend', this.handleMouseUp_);
    this.removeAttribute ('tabindex');

    this.addClass('disabled');

    if (this.playerEvent) {
      this.off (this.player_, this.playerEvent, this.update);
    }
    this.enabled_ = false;
  }

  /**
   * Erstellen Sie das DOM-Element `Slider`s.
   *
   * @param {string} type
   * Art des zu erstellenden Elements.
   *
   * @param {Object} [props={}]
   * Liste der Eigenschaften in Objektform.
   *
   * @param {Object} [attributes={}]
   * Liste der Attribute in Objektform.
   *
   * @return {Element}
   *         Das Element, das erstellt wird.
   * /
  createEl (Typ, Requisiten = {}, Attribute = {}) {
    //Füge die Slider-Elementklasse zu allen Unterklassen hinzu
    props.className = props.Klassenname + 'vjs-slider';
    props = assign({
      tabIndex: 0
    }, props);

    attribute = assign({
      'Rolle': 'Slider',
      'aria-valuenow': 0,
      'aria-valuemin': 0,
      'aria-valuemax': 100,
      'TabIndex': 0
    }, attributes);

    gib super.createEL zurück (Typ, Requisiten, Attribute);
  }

  /**
   * Behandelt `mousedown`- oder `touchstart`-Ereignisse auf dem `Slider`.
   *
   * @param {EventTarget~Event} event
   *        mousedown"- oder "Touchstart"-Ereignis, das diese Funktion ausgelöst hat
   *
   * @listens mousedown
   * @listens touchstart
   * @fires Slider #slideractive
   * /
  handleMouseDown(event) {
    const doc = this.bar.el_.ownerDocument;

    if (event.type === 'mousedown') {
      event.preventDefault();
    }
    //Rufe preventDefault () nicht beim Touchstart in Chrome auf
    //um Konsolenwarnungen zu vermeiden. Verwenden Sie den Stil „Touch-Action: keine“
    //stattdessen, um unbeabsichtigtes Scrollen zu verhindern.
    //https://developers.google.com/web/updates/2017/01/scrolling-intervention
    if (event.type === 'touchstart' &&! IST_CHROM) {
      event.preventDefault();
    }
    dom.blockTextSelection ();

    this.addClass ('vjs-sliding');
    /**
     * Wird ausgelöst, wenn sich der Slider in einem aktiven Zustand befindet
     *
     * @event Slider #slideractive
     * @Typ {EventTarget~Event}
     * /
    this.trigger('slideractive');

    this.on (doc, 'mousemove', this.handleMouseMove_);
    this.on (doc, 'mouseup', this.handleMouseUp_);
    this.on (doc, 'touchmove', this.handleMouseMove_);
    this.on (doc, 'touchend', this.handleMouseUp_);

    this.handleMouseMove (Ereignis, wahr);
  }

  /**
   * Behandle die Ereignisse `mousemove`, `touchmove` und `mousedown` auf diesem `Slider`.
   * Die Ereignisse `mousemove` und `touchmove` lösen diese Funktion nur aus, wenn
   * `mousedown` und `touchstart`. Das liegt an {@link Slider #handleMouseDown} und
   * {@link Slider #handleMouseUp}.
   *
   * @param {EventTarget~Event} event
   * Das ausgelöste `mousedown`-, `mousemove`-, `touchstart`- oder `touchmove`-Ereignis
   *        diese Funktion
   * @param {boolean} mouseDown dies ist ein Flag, das auf true gesetzt werden sollte, wenn `handleMouseMove` direkt aufgerufen wird. Es erlaubt uns, Dinge zu überspringen, die nicht passieren sollten, wenn sie von der Maus nach unten kommen, aber bei einer normalen Mausbewegung passieren sollten. Der Standardwert ist false.
   *
   * @listens mousemove
   * @listens touchmove
   * /
  handleMouseMove (Ereignis) {}

  /**
   * Behandle die Ereignisse `mouseup` oder `touchend` auf dem `Slider`.
   *
   * @param {EventTarget~Event} event
   *        mouseup"- oder "Touchend"-Ereignis, das diese Funktion ausgelöst hat.
   *
   * @listens berührend
   * @listens mouseup
   * @fires Slider #sliderinactive
   * /
  handleMouseUp () {
    const doc = this.bar.el_.ownerDocument;

    dom.unblockTextSelection ();

    this.removeClass ('vjs-sliding');
    /**
     * Wird ausgelöst, wenn sich der Slider nicht mehr in einem aktiven Zustand befindet.
     *
     * @event Slider #sliderinactive
     * @Typ {EventTarget~Event}
     * /
    this.trigger('sliderinactive');

    this.off(doc, 'mousemove', this.handleMouseMove_);
    this.off(doc, 'mouseup', this.handleMouseUp_);
    this.off(doc, 'touchmove', this.handleMouseMove_);
    this.off(doc, 'touchend', this.handleMouseUp_);

    this.update();
  }

  /**
   * Aktualisiere den Fortschrittsbalken des `Slider`.
   *
   * @return {number}
   * Der Prozentsatz des Fortschritts, den der Fortschrittsbalken darstellt, als
   * Zahl von 0 bis 1.
   * /
  update() {
    //In VolumeBar init haben wir ein setTimeout für ein Update, das erscheint und aktualisiert
    //bis zum Ende des Ausführungsstapels. Der Spieler wird vorher zerstört
    //Das Update verursacht einen Fehler
    //Wenn es keine Bar gibt...
    wenn (! this.el_ ||! diese.bar) {
      rückkehr;
    }

    //Clamp-Fortschritt zwischen 0 und 1
    //und nur auf vier Dezimalstellen runden, da wir unten auf zwei runden
    const progress = this.getProgress ();

    if (fortschritt === this.progress_) {
      fortschritt zurückgeben;
    }

    this.progress_ = Fortschritt;

    this.requestNamedAnimationFrame ('Slider #update ', () => {
      //Stellen Sie die neue Balkenbreite oder -höhe ein
      const sizeKey = this.vertical ()? 'Höhe': 'Breite';

      //Konvertiere in einen Prozentsatz für den CSS-Wert
      this.bar.el () .style [sizeKey] = (Fortschritt * 100) .toFixed (2) + '%';
    });

    fortschritt zurückgeben;
  }

  /**
   * Ermitteln Sie den Prozentsatz des Balkens, der gefüllt werden soll
   * aber geklemmt und abgerundet.
   *
   * @return {number}
   * Prozentualer Füllstand des Sliders
   * /
  getFortschritt () {
    gib Number (clamp (this.getPercent (), 0, 1) .toFixed (4)) zurück;
  }

  /**
   * Entfernung für Slider berechnen
   *
   * @param {EventTarget~Event} event
   *        Das Ereignis, das diese Funktion ausgelöst hat.
   *
   * @return {number}
   * Die aktuelle Position des Sliders.
   * - position.x für vertikale `Slider`s
   * - position.y für horizontale `Slider`s
   * /
  CalculateDistance (Ereignis) {
    const position = dom.getPointerPosition (this.el_, Ereignis);

    wenn (this.vertical ()) {
      Position zurückgeben.;
    }
    Position zurückgeben.x;
  }

  /**
   * Behandelt ein `Keydown`-Ereignis auf dem `Slider`. Uhren für links, rechts, oben und unten
   * Pfeiltasten. Diese Funktion wird nur aufgerufen, wenn der Schieberegler den Fokus hat. Sehen
   * {@link Slider #handleFocus} und {@link Slider #handleBlur}.
   *
   * @param {EventTarget~Event} event
   * das `keydown`-Ereignis, das dazu geführt hat, dass diese Funktion ausgeführt wurde.
   *
   * @listens keydown
   * /
  handleKeyDown(event) {

    // Pfeile nach links und unten
    if (keycode.isEventKey(event, 'Left') || keycode.isEventKey(event, 'Down')) {
      event.preventDefault();
      event.stopPropagation();
      this.stepBack();

    // Pfeile nach oben und rechts
    } else if (keycode.isEventKey(event, 'Right') || keycode.isEventKey(event, 'Up')) {
      event.preventDefault();
      event.stopPropagation();
      this.stepForward();
    } sonst {

      // Übergeben Sie die Behandlung von nicht unterstützten Tasten nach oben
      super.handleKeyDown(event);
    }
  }

  /**
   * Listener für Klickereignisse auf dem Slider, der verwendet wird, um Klicks zu verhindern
   * vom Blubbern bis hin zu übergeordneten Elementen wie Schaltflächenmenüs.
   *
   * @param {Object} event
   * Ereignis, das dazu geführt hat, dass dieses Objekt ausgeführt wurde
   * /
  handleClick(event) {
    event.stopPropagation();
    event.preventDefault();
  }

  /**
   * Abrufen/einstellen, ob der Schieberegler horizontal oder vertikal ist
   *
   * @param {boolean} [bool]
   * - wahr, wenn der Schieberegler vertikal ist,
   * - false ist horizontal
   *
   * @return {boolean}
   * - wahr, wenn der Schieberegler vertikal ist, und
   * - falsch, wenn der Schieberegler horizontal ist, und
   * /
  vertikal (bool) {
    if (bool === undefiniert) {
      gib this.vertical_ || false zurück;
    }

    this.vertical_ =!! boolen;

    wenn (this.vertical_) {
      this.addClass ('vjs-slider-vertical');
    } sonst {
      this.addClass ('vjs-slider-horizontal');
    }
  }
}

component.registerComponent ('Schieberegler', Schieberegler);
Exportieren Sie den Standard-Slider;