/**
* @file menu-button.js
* /
importiere Button aus '../button.js';
importiere Komponente aus '../component.js';
importiere das Menü aus '. /menu.js ';
import * as Dom from '../utils/dom.js';
import * as Events aus '../utils/events.js';
importiere {toTitleCase} aus '../utils/string-cases.js';
importiere {IS_IOS} aus '.. /utils/browser.js ';
dokument aus 'global/document' importieren;
import keycode from 'keycode';
/**
* Eine `MenuButton`-Klasse für jedes Popup {@link Menu}.
*
* @erweitert Komponente
* /
Klasse MenuButton erweitert Komponente {
/**
* Erzeugt eine Instanz dieser Klasse.
*
* @param {Player} Spieler
* Der `Player`, dem diese Klasse zugeordnet werden soll.
*
* @param {Object} [options={}]
* Der Schlüssel/Wertspeicher der Playeroptionen.
* /
constructor(player, options = {}) {
super(Spieler, Optionen);
this.MenuButton_ = neuer Button (Spieler, Optionen);
this.menuButton_.controlText (this.controlText_);
this.menuButton_.el_.setAttribute ('aria-haspopup', 'wahr');
//Füge buildCssClass-Werte zur Schaltfläche hinzu, nicht zum Wrapper
const buttonClass = Button.prototype.buildCSSClass();
this.menuButton_.el_.className = this.buildCSSClass () + '' + ButtonClass;
this.menuButton_.removeClass ('vjs-control');
this.addChild (this.MenuButton_);
this.update();
this.enabled_ = true;
const handleClick = (e) => this.handleClick (e);
this.handleMenuKeyUp_ = (e) => this.handleMenuKeyUp (e);
this.on (this.menuButton_, 'tippen', HandleClick);
this.on (this.menuButton_, 'klick', handleClick);
this.on (this.MenuButton_, 'keydown', (e) => this.handleKeyDown (e));
this.on (this.menuButton_, 'mouseenter', () => {
this.addClass('vjs-hover');
this.menu.show();
events.on (document, 'keyup', this.handleMenuKeyup_);
});
this.on ('mouseleave', (e) => this.handleMouseleave (e));
this.on ('keydown', (e) => this.handleSubmenuKeyDown (e));
}
/**
* Aktualisierung des Menüs auf der Grundlage des aktuellen Zustands seiner Elemente.
* /
update() {
const menu = this.createMenu ();
wenn (this.menu) {
this.menu.dispose ();
this.removeChild (this.menu);
}
this.menu = Menü;
this.addChild (Menü);
/**
* Verfolge den Status der Menütaste
*
* @Typ {Boolean}
* @privat
* /
this.buttonPressed_ = false;
this.menuButton_.el_.setAttribute('aria-expanded', 'false');
wenn (this.items && this.items.length <= this.hideThreshold_) {
this.hide();
this.menu.contentel_.removeAttribute ('Rolle');
} sonst {
this.show();
this.menu.contentel_.setAttribute ('Rolle', 'Menü');
}
}
/**
* Erstellen Sie das Menü und fügen Sie alle Elemente hinzu.
*
* @return {Menu}
* Das konstruierte Menü
* /
createMenu() {
const menu = neues Menü (this.player_, {MenuButton: this});
/**
* Blenden Sie das Menü aus, wenn die Anzahl der Elemente unter oder gleich diesem Schwellenwert ist. Dies ist standardmäßig
* auf 0 und jedes Mal, wenn wir Elemente hinzufügen, die ausgeblendet werden können, erhöhen wir sie. Wir listen auf
* ist hier, weil wir jedes Mal, wenn wir `createMenu` starten, den Wert zurücksetzen müssen.
*
* @protected
* @Typ {Zahl}
* /
this.hideThreshold_ = 0;
//Füge einen Eintrag in der Titelliste oben hinzu
wenn (this.options_.title) {
const titleEl = dom.createEl ('li', {
Klassenname: 'vjs-menu-title',
TextInhalt: toTitleCase (this.options_.title),
tabIndex: -1
});
const titleComponent = neue Komponente (this.player_, {el: titleEL});
menu.AddItem (TitleComponent);
}
this.items = this.createItems ();
wenn (this.items) {
//Menüelemente zum Menü hinzufügen
für (sei i = 0; i < this.items.length; i++) {
menu.addItem (this.items [i]);
}
}
Rückgabemenü;
}
/**
* Erstellen Sie die Liste der Menüpunkte. Spezifisch für jede Unterklasse.
*
* @Abstrakt
* /
Artikel erstellen () {}
/**
* Erstellen Sie das DOM-Element von `MenuButtons.
*
* @return {Element}
* Das Element, das erstellt wird.
* /
createEl() {
return super.createEl('div', {
Klassenname: this.buildWrapperCssClass ()
}, {
});
}
/**
* Erlaube Unterkomponenten, CSS-Klassennamen für das Wrapper-Element zu stapeln
*
* @return {string}
* Das konstruierte Wrapper-DOM `className`
* /
buildWrapperCSSClass() {
let menuButtonClass = 'vjs-menu-button';
// Wenn die Option "inline" übergeben wird, wollen wir ganz andere Stile verwenden.
if (this.options_.inline === true) {
menuButtonClass += '-inline';
} sonst {
menuButtonClass += '-popup';
}
// TODO: Korrigiere das CSS so, dass dies nicht notwendig ist
const buttonClass = Button.prototype.buildCSSClass();
`vjs-menu-button $ {menuButtonClass} $ {buttonClass} $ {super.buildCssClass ()} `zurückgeben;
}
/**
* Erzeugt den Standard-DOM "Klassenname".
*
* @return {string}
* Der DOM `className` für dieses Objekt.
* /
buildCSSClass() {
let menuButtonClass = 'vjs-menu-button';
// Wenn die Option "inline" übergeben wird, wollen wir ganz andere Stile verwenden.
if (this.options_.inline === true) {
menuButtonClass += '-inline';
} sonst {
menuButtonClass += '-popup';
}
`vjs-menu-button $ {menuButtonClass} $ {super.buildCssClass ()} `zurückgeben;
}
/**
* Ruft den lokalisierten Steuertext ab, der aus Gründen der Barrierefreiheit verwendet wird, oder legt ihn fest.
*
* > HINWEIS: Dies wird aus dem internen `MenuButton_` -Element kommen.
*
* @param {string} [text]
* Kontrolltext für das Element.
*
* @param {Element} [el=this.MenuButton_.el ()]
* Element, auf das der Titel gesetzt wird.
*
* @return {string}
* - Der Kontrolltext, wenn er
* /
ControlText (text, el = this.MenuButton_.el ()) {
gib this.menuButton_.controlText (text, el) zurück;
}
/**
* Entsorgen Sie die `Menü-Button` und alle untergeordneten Komponenten.
* /
dispose() {
this.handleMouseLeave ();
super.dispose();
}
/**
* Bearbeite einen Klick auf einen `MenuButton`.
* Siehe {@link ClickableComponent#handleClick} für Instanzen, in denen dies aufgerufen wird.
*
* @param {EventTarget~Event} event
* Das `Keydown`-, `Tap`- oder `Click`-Ereignis, das diese Funktion ausgelöst hat
* genannt.
*
* @listens tap
* @listens klicken
* /
handleClick(event) {
if (this.buttonPressed_) {
this.unpressButton();
} sonst {
this.pressButton();
}
}
/**
* Benütze `mouseleave` für `MenuButton`.
*
* @param {EventTarget~Event} event
* Das `mouseleave`-Ereignis, das den Aufruf dieser Funktion verursacht hat.
*
* @listens Mauszeiger
* /
handleMouseLeave (Ereignis) {
this.removeClass('vjs-hover');
events.off (document, 'keyup', this.handleMenuKeyup_);
}
/**
* Stellen Sie den Fokus auf die eigentliche Schaltfläche, nicht auf dieses Element
* /
focus() {
this.menuButton_.focus();
}
/**
* Entferne den Fokus von der eigentlichen Schaltfläche, nicht von diesem Element
* /
blur() {
this.menuButton_.blur ();
}
/**
* Benutze die Tabulator-, Escape-, Abwärts- und Aufwärtspfeiltasten für `MenuButton`. Sehen
* {@link ClickableComponent#handleKeyDown} für Instanzen, in denen dies aufgerufen wird.
*
* @param {EventTarget~Event} event
* Das "Keydown"-Ereignis, das zum Aufruf dieser Funktion geführt hat.
*
* @listens keydown
* /
handleKeyDown(event) {
// Escape oder Tabulator heben das Drücken der "Taste" auf
if (keycode.isEventKey(event, 'Esc') || keycode.isEventKey(event, 'Tab')) {
if (this.buttonPressed_) {
this.unpressButton();
}
// Nicht preventDefault für Tabulator-Taste - wir wollen trotzdem den Fokus verlieren
if (!keycode.isEventKey(event, 'Tab')) {
event.preventDefault();
// Fokus zurück auf die Schaltfläche der Menütaste setzen
this.menuButton_.focus();
}
//Nach oben oder nach unten 'drücken' Sie auch die Taste, um das Menü zu öffnen
} sonst if (keyCode.isEventKey (event, 'Up') || keycode.isEventKey (event, 'Down')) {
wenn (! diese.Taste gedrückt _) {
event.preventDefault();
this.pressButton();
}
}
}
/**
* Behandelt ein `keyup`-Ereignis auf einem `MenuButton`. Der Hörer dafür wird hinzugefügt in
* der Konstrukteur.
*
* @param {EventTarget~Event} event
* Wichtigstes Presseereignis
*
* @listens keyup
* /
handleMenuKeyUp (Ereignis) {
//Escape versteckt das Popup-Menü
if (keycode.isEventKey(event, 'Esc') || keycode.isEventKey(event, 'Tab')) {
this.removeClass('vjs-hover');
}
}
/**
* Dieser Methodenname delegiert jetzt an `handleSubmenuKeyDown`. Dies bedeutet
* jeder, der `handleSubmenuKeyPress` aufruft, wird seine Methodenaufrufe nicht sehen
* hör auf zu arbeiten.
*
* @param {EventTarget~Event} event
* Das Ereignis, das zum Aufruf dieser Funktion geführt hat.
* /
handleSubmenuKeypress (Ereignis) {
this.handleSubmenuKeyDown (Ereignis);
}
/**
* Behandelt ein `Keydown`-Ereignis in einem Untermenü. Der Hörer dafür wird hinzugefügt in
* der Konstrukteur.
*
* @param {EventTarget~Event} event
* Wichtigstes Presseereignis
*
* @listens keydown
* /
handleSubmenuKeyDown (Ereignis) {
// Escape oder Tabulator heben das Drücken der "Taste" auf
if (keycode.isEventKey(event, 'Esc') || keycode.isEventKey(event, 'Tab')) {
if (this.buttonPressed_) {
this.unpressButton();
}
// Nicht preventDefault für Tabulator-Taste - wir wollen trotzdem den Fokus verlieren
if (!keycode.isEventKey(event, 'Tab')) {
event.preventDefault();
// Fokus zurück auf die Schaltfläche der Menütaste setzen
this.menuButton_.focus();
}
} sonst {
//HINWEIS: Dies ist ein Sonderfall, in dem wir nicht unbehandelt bleiben.
//Keydown-Ereignisse bis zum Component-Handler, denn das ist
//nur das Keydown-Behandling des `MenuItem` beenden
//im `Menu`, das bereits ungenutzte Tasten weitergibt.
}
}
/**
* Versetzt den aktuellen `MenuButton` in einen gedrückten Zustand.
* /
Drücken Sie die Taste () {
if (this.enabled_) {
this.buttonPressed_ = wahr;
this.menu.show();
this.menu.lockShowing ();
this.menuButton_.el_.setAttribute ('aria-expanded', 'wahr');
//setze den Fokus in das Untermenü, außer auf iOS, wo es dazu führt
//unerwünschtes Scrollverhalten, wenn sich der Spieler in einem Iframe befindet
wenn (IS_IOS && dom.isFrame ()) {
//Komm früh zurück, damit das Menü nicht fokussiert ist
rückkehr;
}
this.menu.focus ();
}
}
/**
* Nimmt den aktuellen `MenuButton` aus einem gedrückten Zustand.
* /
Drücken Sie die Taste () {
if (this.enabled_) {
this.buttonPressed_ = false;
this.menu.unlockShowing ();
this.menu.hide ();
this.menuButton_.el_.setAttribute('aria-expanded', 'false');
}
}
/**
* Deaktiviere den `MenuButton`. Lassen Sie nicht zu, dass es angeklickt wird.
* /
deaktivieren() {
this.unpressButton();
this.enabled_ = false;
this.addClass('vjs-disabled');
this.menuButton_.disable ();
}
/**
* Aktiviere den `MenuButton`. Lassen Sie es anklicken.
* /
enable() {
this.enabled_ = true;
this.removeClass('vjs-disabled');
this.menuButton_.enable ();
}
}
component.registerComponent ('MenuButton', MenuButton);
Standard-MenuButton exportieren;