UNPKG

shaka-player

Version:
161 lines (138 loc) 4.33 kB
/*! @license * Shaka Player * Copyright 2016 Google LLC * SPDX-License-Identifier: Apache-2.0 */ goog.provide('shaka.ui.TextStyleMenu'); goog.require('shaka.ui.SettingsMenu'); goog.require('shaka.ui.Utils'); goog.require('shaka.util.Dom'); goog.requireType('shaka.ui.Controls'); goog.requireType('shaka.ui.TextStylePreview'); /** * Abstract base for text style configuration menus (position, size, etc.). * Subclasses implement the template methods getItems / getLabelForItem / * onItemSelected / getPreviewConfigForItem / getCurrentValueLabel. * * @extends {shaka.ui.SettingsMenu} * @template T * @abstract * @export */ shaka.ui.TextStyleMenu = class extends shaka.ui.SettingsMenu { /** * @param {!HTMLElement} parent * @param {!shaka.ui.Controls} controls * @param {string} icon */ constructor(parent, controls, icon) { super(parent, controls, icon); this.eventManager.listenMulti( this.player, [ 'loading', 'unloading', 'configurationchanged', 'trackschanged', ], () => { this.updateCurrentSelection_(); this.checkAvailability(); }); } /** @override */ checkAvailability() { const tracks = this.player.getTextTracks() || []; const hasTrack = tracks.some((track) => track.active); const available = hasTrack && !this.isSubMenuOpened && this.controls.getConfig().captionsStyles; shaka.ui.Utils.setDisplay(this.button, available); this.button.ariaPressed = available ? 'true' : 'false'; } /** @override */ onMenuOpen() { this.controls.showTextStylePreview(); } /** @override */ onMenuClose() { this.controls.hideTextStylePreview(); } /** * @return {!Array<T>} * @protected */ getItems() { return []; } /** * @param {T} item * @return {string} * @protected */ getLabelForItem(item) { return ''; } /** * @param {T} item * @protected */ onItemSelected(item) {} /** * @param {T} item * @return {!shaka.ui.TextStylePreview.Configuration} * @protected */ getPreviewConfigForItem(item) { return {}; } /** * @return {string} * @protected */ getCurrentValueLabel() { return ''; } /** * Clears and rebuilds the menu items, then refreshes the selection indicator. * Call from the subclass constructor and from updateLocalizedStrings() when * item labels are localized strings. * @protected */ rebuildMenu() { shaka.ui.Utils.clearMenuKeepingBackButton(this.menu); for (const item of this.getItems()) { const button = shaka.util.Dom.createButton(); button.setAttribute('role', 'menuitemradio'); button.setAttribute('aria-checked', 'false'); const span = shaka.util.Dom.createHTMLElement('span'); span.textContent = this.getLabelForItem(item); button.appendChild(span); this.eventManager.listen(button, 'click', () => { this.onItemSelected(item); this.updateCurrentSelection_(); }); shaka.ui.Utils.addHoverAndFocusListeners( this.eventManager, button, () => this.controls.updateTextStylePreview( this.getPreviewConfigForItem(item)), () => this.controls.resetTextStylePreview()); this.menu.appendChild(button); } this.updateCurrentSelection_(); shaka.ui.Utils.focusOnTheChosenItem(this.menu); } /** @private */ updateCurrentSelection_() { const checkmarkIcon = shaka.ui.Utils.getDescendantIfExists( this.menu, 'shaka-ui-icon shaka-chosen-item'); if (checkmarkIcon) { const prevButton = checkmarkIcon.parentElement; prevButton.setAttribute('aria-checked', 'false'); const prevSpan = prevButton.getElementsByTagName('span')[0]; if (prevSpan) { prevSpan.classList.remove('shaka-chosen-item'); } prevButton.removeChild(checkmarkIcon); } const currentLabel = this.getCurrentValueLabel(); const span = Array.from(this.menu.querySelectorAll('span')) .find((el) => el.textContent === currentLabel); if (span) { const button = span.parentElement; button.appendChild(shaka.ui.Utils.checkmarkIcon()); shaka.ui.Utils.setChosenItem(button, span); } this.currentSelection.textContent = currentLabel; } };