/**
 * @file menu.js
 * /
importiere Komponente aus '../component.js';
dokument aus 'global/document' importieren;
import * as Dom from '../utils/dom.js';
import * as Events aus '../utils/events.js';
import keycode from 'keycode';

/**
 * Die Menükomponente wird verwendet, um Popup-Menüs zu erstellen, einschließlich Untertiteln und
 * Auswahlmenüs für Untertitel.
 *
 * @erweitert Komponente
 * /
class Menu erweitert Komponente {

  /**
   * Erstellen Sie eine Instanz dieser Klasse.
   *
   * @param {Player} Spieler
   * der Player, an den diese Komponente angeschlossen werden soll
   *
   * @param {Object} [Optionen]
   *        Objekt der Optionsnamen und -werte
   *
   * /
  constructor(spieler, optionen) {
    super(Spieler, Optionen);

    wenn (Optionen) {
      this.MenuButton_ = Optionen.MenuButton;
    }

    this.focusedChild_ = -1;

    this.on('keydown', (e) => this.handleKeyDown(e));

    //Alle Menüelementinstanzen verwenden denselben Blur-Handler, der vom Menücontainer bereitgestellt wird.
    this.boundHandleBlur_ = (e) => this.handleBlur (e);
    this.boundHandleTapClick_ = (e) => this.handleTapClick (e);
  }

  /**
   * Fügen Sie Event-Listener zum {@link MenuItem} hinzu.
   *
   * @param {Object} component
   * Die Instanz des `MenuItem`, zu der Listener hinzugefügt werden sollen.
   *
   * /
  addEventListenerForItem (Komponente) {
    if (!(component instanceof Component)) {
      rückkehr;
    }

    this.on (Komponente, 'Blur', this.boundHandleBlur_);
    this.on (Komponente, ['tippen', 'klicken'], this.boundHandleTapClick_);
  }

  /**
   * Entferne Event-Listener aus dem {@link MenuItem}.
   *
   * @param {Object} component
   * Die Instanz des `MenuItem` zum Entfernen von Listenern.
   *
   * /
  removeEventListenerForItem (Komponente) {
    if (!(component instanceof Component)) {
      rückkehr;
    }

    this.off (Komponente, 'Blur', this.boundHandleBlur_);
    this.off (Komponente, ['tippen', 'klicken'], this.boundHandleTapClick_);
  }

  /**
   * Diese Methode wird indirekt aufgerufen, wenn die Komponente hinzugefügt wurde
   * bevor die Komponente mit `addItem` zur neuen Menüinstanz hinzugefügt wird.
   * In diesem Fall entfernt die ursprüngliche Menüinstanz die Komponente
   * indem Sie `removeChild` aufrufen.
   *
   * @param {Object} component
   * Die Instanz des `MenuItem`
   * /
  removeChild(component) {
    if (typeof component === 'string') {
      component = this.getChild(component);
    }

    this.removeEventListenerForItem (Komponente);
    super.removeChild (Komponente);
  }

  /**
   * Füge ein {@link MenuItem} zum Menü hinzu.
   *
   * @param {object|String} -Komponente
   * Der Name oder die Instanz des `MenuItem`, das hinzugefügt werden soll.
   *
   * /
  addItem (Komponente) {
    const ChildComponent = this.addChild (Komponente);

    wenn (ChildComponent) {
      this.addEventListenerForItem (ChildComponent);
    }
  }

  /**
   * Erstellen Sie das DOM-Element von `Menu.
   *
   * @return {Element}
   * das Element, das erstellt wurde
   * /
  createEl() {
    const contentElType = this.options_.contentELType || 'ul';

    this.contentEL_ = dom.createEl (ContentElType, {
      Klassenname: 'vjs-menu-content'
    });

    this.contentel_.setAttribute ('Rolle', 'Menü');

    const el = super.createEl('div', {
      anhängen: this.Contentel_,
      Klassenname: 'vjs-menu'
    });

    el.appendChild(this.contentEl_);

    //Verhindert, dass Klicks sprudeln. Wird für Menüschaltflächen benötigt,
    //wo ein Klick auf das Elternteil von Bedeutung ist
    events.on (el), 'click', function (event) {
      event.preventDefault();
      event.stopImmediatePropagation ();
    });

    zurück el;
  }

  dispose() {
    this.contentEl_ = null;
    this.boundHandleBlur_ = null;
    this.boundHandleTapClick_ = null;

    super.dispose();
  }

  /**
   * Wird aufgerufen, wenn ein `MenuItem` den Fokus verliert.
   *
   * @param {EventTarget~Event} event
   * Das `blur`-Ereignis, das dazu geführt hat, dass diese Funktion aufgerufen wurde.
   *
   * @listens verwischen
   * /
  handleBlur (Ereignis) {
    const relatedTarget = event.relatedTarget || document.activeElement;

    //Schließt das Menü-Popup, wenn ein Benutzer außerhalb des Menüs klickt
    wenn (! this.children () .some (element) => {
      return element.el () === RelatedTarget;
    })) {
      const btn = this.MenuButton_;

      if (btn & btn.ButtonPressed_ & relatedTarget! == btn.el () .firstChild) {
        btn.unpressButton ();
      }
    }
  }

  /**
   * Wird aufgerufen, wenn auf ein `MenuItem` geklickt oder getippt wird.
   *
   * @param {EventTarget~Event} event
   * Das `click`- oder `tap`-Ereignis, das den Aufruf dieser Funktion verursacht hat.
   *
   * @listens klicken, tippen
   * /
  handleTapClick (Ereignis) {
    //Entdrücke den zugehörigen MenuButton und verschiebe den Fokus zurück darauf
    wenn (this.MenuButton_) {
      this.menuButton_.unpressButton ();

      const childComponents = this.children ();

      wenn (! Array.isArray (ChildComponents) {
        rückkehr;
      }

      const FoundComponent = ChildComponents.Filter (Komponente => component.el () === event.target) [0];

      wenn (! Komponente gefunden) {
        rückkehr;
      }

      //Fokussiere die Menütaste nicht, wenn das Element ein Element mit den Untertiteleinstellungen ist
      //weil sich der Fokus woanders verlagern wird
      wenn (FoundComponent.name ()! == 'CaptionSettingsMenuItem') {
        this.menuButton_.focus();
      }
    }
  }

  /**
   * Behandle ein `Keydown`-Ereignis in diesem Menü. Dieser Listener wird im Konstruktor hinzugefügt.
   *
   * @param {EventTarget~Event} event
   * Ein `Keydown`-Ereignis, das im Menü passiert ist.
   *
   * @listens keydown
   * /
  handleKeyDown(event) {

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

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

  /**
   * Gehe zum nächsten (unteren) Menüpunkt für Tastaturbenutzer.
   * /
  stepForward() {
    let stepChild = 0;

    if (this.focusedChild_ !== undefined) {
      stepChild = this.focusedChild_ + 1;
    }
    this.focus(stepChild);
  }

  /**
   * Wechselt zum vorherigen (höheren) Menüpunkt für Tastaturbenutzer.
   * /
  stepBack() {
    let stepChild = 0;

    if (this.focusedChild_ !== undefined) {
      stepChild = this.focusedChild_ - 1;
    }
    this.focus(stepChild);
  }

  /**
   * Setze den Fokus auf ein {@link MenuItem} im `Menu`.
   *
   * @param {object|Zeichenfolge} [item=0]
   * Index des untergeordneten Elements, auf das der Fokus gesetzt wurde.
   * /
  fokus (item = 0) {
    const children = this.children () .slice ();
    const haveTitle = children.length && children [0] .hasClass ('vjs-menu-title');

    wenn (haveTitle) {
      kinder.shift ();
    }

    wenn (Kinderlänge > 0) {
      wenn (Artikel < 0) {
        Artikel = 0;
      } sonst wenn (item >= children.length) {
        Artikel = Kinder. Länge - 1;
      }

      this.focusedChild_ = Objekt;

      Kinder [item] .el_.focus ();
    }
  }
}

component.registerComponent ('Menü', Menü);
Standardmenü exportieren;