/**
 * @file menu.js
 */
從 '../component.js' 導入組件;
從“全局/文檔”導入文檔;
import * as Dom from '../utils/dom.js';
import * as Events from '../utils/events.js';
從“鍵碼”導入鍵碼;

/**
 * Menu組件用於構建彈出菜單,包括字幕和
 * 字幕選擇菜單。
 *
 * @extends 組件
 */
類菜單擴展組件{

  /**
   * 創建此類的一個實例。
   *
   * @param {Player} 播放器
   * 這個組件應該附加到的播放器
   *
   * @param {對象} [選項]
   * 選項名稱和值的對象
   *
   */
  構造函數(播放器,選項){
    超級(播放器,選項);

    如果(選項){
      this.menuButton_ = options.menuButton;
    }

    this.focusedChild_ = -1;

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

    // 所有菜單項實例共享菜單容器提供的相同模糊處理程序。
    this.boundHandleBlur_ = (e) => this.handleBlur(e);
    this.boundHandleTapClick_ = (e) => this.handleTapClick(e);
  }

  /**
   * 將事件偵聽器添加到 {@link MenuItem}。
   *
   * @param {Object} 組件
   * 要添加偵聽器的 `MenuItem` 實例。
   *
   */
  addEventListenerForItem(組件){
    if (!(component instanceof Component)) {
      返回;
    }

    this.on(component, 'blur', this.boundHandleBlur_);
    this.on(component, ['tap', 'click'], this.boundHandleTapClick_);
  }

  /**
   * 從 {@link MenuItem} 中移除事件偵聽器。
   *
   * @param {Object} 組件
   * 用於移除偵聽器的 `MenuItem` 實例。
   *
   */
  removeEventListenerForItem(組件){
    if (!(component instanceof Component)) {
      返回;
    }

    this.off(component, 'blur', this.boundHandleBlur_);
    this.off(component, ['tap', 'click'], this.boundHandleTapClick_);
  }

  /**
   * 該方法將在添加組件時間接調用
   * 在組件通過 addItem 添加到新菜單實例之前。
   * 在這種情況下,原始菜單實例將刪除該組件
   * 通過調用 `removeChild`。
   *
   * @param {Object} 組件
   * `MenuItem` 的實例
   */
  removeChild(組件){
    if (typeof component === 'string') {
      組件 = this.getChild(組件);
    }

    this.removeEventListenerForItem(組件);
    super.removeChild(組件);
  }

  /**
   * 添加一個 {@link MenuItem} 到菜單。
   *
   * @param {Object|string} 組件
   * 要添加的 `MenuItem` 的名稱或實例。
   *
   */
  添加項目(組件){
    const childComponent = this.addChild(component);

    如果(子組件){
      this.addEventListenerForItem(childComponent);
    }
  }

  /**
   * 創建“菜單”的 DOM 元素。
   *
   * @return {元素}
   * 創建的元素
   */
  創建El() {
    常量 contentElType = this.options_.contentElType || 'ul';

    this.contentEl_ = Dom.createEl(contentElType, {
      className: 'vjs-menu-content'
    });

    this.contentEl_.setAttribute('角色', '菜單');

    const el = super.createEl('div', {
      追加:this.contentEl_,
      類名:'vjs-menu'
    });

    el.appendChild(this.contentEl_);

    // 防止點擊冒泡。需要菜單按鈕,
    // 對父級的點擊很重要
    Events.on(el, 'click', function(event) {
      事件.preventDefault();
      event.stopImmediatePropagation();
    });

    返回 el;
  }

  處置(){
    this.contentEl_ = null;
    this.boundHandleBlur_ = null;
    this.boundHandleTapClick_ = null;

    super.dispose();
  }

  /**
   * 當 `MenuItem` 失去焦點時調用。
   *
   * @param {EventTarget~Event} 事件
   * 導致調用此函數的 `blur` 事件。
   *
   * @listens 模糊
   */
  句柄模糊(事件){
    常量 relatedTarget = event.relatedTarget ||文檔.activeElement;

    // 當用戶在菜單外點擊時關閉彈出菜單
    如果 (!this.children().some((元素) => {
      返回 element.el() === 相關目標;
    })) {
      const btn = this.menuButton_;

      如果 (btn && btn.buttonPressed_ && relatedTarget !== btn.el().firstChild) {
        btn.unpressButton();
      }
    }
  }

  /**
   * 當單擊或點擊 `MenuItem` 時調用。
   *
   * @param {EventTarget~Event} 事件
   * 導致調用此函數的 `click` 或 `tap` 事件。
   *
   * @listens 點擊,點擊
   */
  handleTapClick(事件){
    // 取消按下關聯的 MenuButton,並將焦點移回它
    如果(this.menuButton_){
      這個.menuButton_.unpressButton();

      const childComponents = this.children();

      如果 (!Array.isArray(childComponents)) {
        返回;
      }

      const foundComponent = childComponents.filter(component => component.el() === event.target)[0];

      如果(!foundComponent){
        返回;
      }

      // 如果項目是標題設置項目,則不要聚焦菜單按鈕
      // 因為焦點會移動到別處
      if (foundComponent.name() !== 'CaptionSettingsMenuItem') {
        這個.menuButton_.focus();
      }
    }
  }

  /**
   * 處理此菜單上的 `keydown` 事件。這個偵聽器被添加到構造函數中。
   *
   * @param {EventTarget~Event} 事件
   * 菜單上發生的 `keydown` 事件。
   *
   * @listens 按鍵
   */
  handleKeyDown(事件){

    // 向左和向下箭頭
    if (keycode.isEventKey(event, 'Left') || keycode.isEventKey(event, 'Down')) {
      事件.preventDefault();
      事件.stopPropagation();
      這個.stepForward();

    // 向上和向右箭頭
    } else if (keycode.isEventKey(event, 'Right') || keycode.isEventKey(event, 'Up')) {
      事件.preventDefault();
      事件.stopPropagation();
      這個.stepBack();
    }
  }

  /**
   * 移動到鍵盤用戶的下一個(下)菜單項。
   */
  向前一步() {
    讓 stepChild = 0;

    如果(this.focusedChild_!==未定義){
      stepChild = this.focusedChild_ + 1;
    }
    this.focus(stepChild);
  }

  /**
   * 移動到鍵盤用戶的上一個(更高)菜單項。
   */
  退後() {
    讓 stepChild = 0;

    如果(this.focusedChild_!==未定義){
      stepChild = this.focusedChild_ - 1;
    }
    this.focus(stepChild);
  }

  /**
   * 將焦點放在 `Menu` 中的 {@link MenuItem} 上。
   *
   * @param {對象|字符串} [item=0]
   * 子項集的索引。
   */
  焦點(項目= 0){
    const children = this.children().slice();
    const haveTitle = children.length && children[0].hasClass('vjs-menu-title');

    如果(有標題){
      兒童班次();
    }

    如果(孩子。長度> 0){
      如果(項目 < 0){
        項目 = 0;
      } else if (item >= children.length) {
        item = children.length - 1;
      }

      this.focusedChild_ = item;

      兒童[項目].el_.focus();
    }
  }
}

Component.registerComponent('Menu', Menu);
導出默認菜單;