Files
shaka-player/ui/text_selection.js
T
michellezhuo 562168a1f6 Set UITextDisplayer as TextDisplayFactory in default config
In player, SimpleTextDisplayer was set as the default TextDisplayer. In
our UI, it changes the configuration to use the UITextDisplayer, and
UITextDisplayer gets constructed with the player. Later in our demo, it
resets the config, so an extra SimpleTextDisplayer gets constructed.
This introduces an extra TextTrack created by SimpleTextDisplayer.

This change sets the UITextDisplayer as the default TextDisplayer in
player's default config.

Closes #2516

Change-Id: I3f653be9fad8b2edbc2fb9de84e8abb327dcfc51
2020-05-04 20:40:18 -07:00

214 lines
6.1 KiB
JavaScript

/** @license
* Copyright 2016 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
goog.provide('shaka.ui.TextSelection');
goog.require('shaka.ui.Enums');
goog.require('shaka.ui.LanguageUtils');
goog.require('shaka.ui.Locales');
goog.require('shaka.ui.Localization');
goog.require('shaka.ui.OverflowMenu');
goog.require('shaka.ui.SettingsMenu');
goog.require('shaka.util.Dom');
/**
* @extends {shaka.ui.SettingsMenu}
* @final
* @export
*/
shaka.ui.TextSelection = class extends shaka.ui.SettingsMenu {
/**
* @param {!HTMLElement} parent
* @param {!shaka.ui.Controls} controls
*/
constructor(parent, controls) {
super(parent,
controls, shaka.ui.Enums.MaterialDesignIcons.CLOSED_CAPTIONS);
this.button.classList.add('shaka-caption-button');
this.menu.classList.add('shaka-text-languages');
if (this.player && this.player.isTextTrackVisible()) {
this.button.setAttribute('aria-pressed', 'true');
} else {
this.button.setAttribute('aria-pressed', 'false');
}
this.addOffOption_();
this.eventManager.listen(
this.localization, shaka.ui.Localization.LOCALE_UPDATED, () => {
this.updateLocalizedStrings_();
// If captions/subtitles are off, this string needs localization.
// TODO: is there a more efficient way of updating just the strings
// we need instead of running the whole language update?
this.updateTextLanguages_();
});
this.eventManager.listen(
this.localization, shaka.ui.Localization.LOCALE_CHANGED, () => {
this.updateLocalizedStrings_();
// If captions/subtitles are off, this string needs localization.
// TODO: is there a more efficient way of updating just the strings
// we need instead of running the whole language update?
this.updateTextLanguages_();
});
this.eventManager.listen(this.player, 'texttrackvisibility', () => {
this.onCaptionStateChange_();
});
this.eventManager.listen(this.player, 'textchanged', () => {
this.updateTextLanguages_();
});
this.eventManager.listen(this.player, 'trackschanged', () => {
this.onTracksChanged_();
});
// Initialize caption state with a fake event.
this.onCaptionStateChange_();
// Set up all the strings in the user's preferred language.
this.updateLocalizedStrings_();
this.updateTextLanguages_();
this.onTracksChanged_();
}
/**
* @private
*/
addOffOption_() {
const off = shaka.util.Dom.createButton();
off.setAttribute('aria-selected', 'true');
this.menu.appendChild(off);
off.appendChild(shaka.ui.Utils.checkmarkIcon());
/** @private {!HTMLElement} */
this.captionsOffSpan_ = shaka.util.Dom.createHTMLElement('span');
this.captionsOffSpan_.classList.add('shaka-auto-span');
off.appendChild(this.captionsOffSpan_);
}
/** @private */
onCaptionStateChange_() {
if (this.player.isTextTrackVisible()) {
this.icon.classList.add('shaka-captions-on');
this.icon.classList.remove('shaka-captions-off');
this.button.setAttribute('aria-pressed', 'true');
} else {
this.icon.classList.add('shaka-captions-off');
this.icon.classList.remove('shaka-captions-on');
this.button.setAttribute('aria-pressed', 'false');
}
this.controls.dispatchEvent(
new shaka.util.FakeEvent('captionselectionupdated'));
}
/** @private */
updateTextLanguages_() {
const tracks = this.player.getTextTracks();
shaka.ui.LanguageUtils.updateTracks(tracks, this.menu,
(track) => this.onTextTrackSelected_(track),
// Don't mark current text language as chosen unless captions are
// enabled
this.player.isTextTrackVisible(),
this.currentSelection,
this.localization,
this.controls.getConfig().trackLabelFormat);
// Add the Off button
const offButton = shaka.util.Dom.createButton();
offButton.classList.add('shaka-turn-captions-off-button');
this.eventManager.listen(offButton, 'click', () => {
this.player.setTextTrackVisibility(false);
this.updateTextLanguages_();
});
offButton.appendChild(this.captionsOffSpan_);
this.menu.appendChild(offButton);
if (!this.player.isTextTrackVisible()) {
offButton.setAttribute('aria-selected', 'true');
offButton.appendChild(shaka.ui.Utils.checkmarkIcon());
this.captionsOffSpan_.classList.add('shaka-chosen-item');
this.currentSelection.textContent =
this.localization.resolve(shaka.ui.Locales.Ids.OFF);
}
shaka.ui.Utils.focusOnTheChosenItem(this.menu);
this.controls.dispatchEvent(
new shaka.util.FakeEvent('captionselectionupdated'));
}
/**
* @param {!shaka.extern.Track} track
* @return {!Promise}
* @private
*/
async onTextTrackSelected_(track) {
await this.player.setTextTrackVisibility(true);
if (this.player) { // May have become null while awaiting
this.player.selectTextLanguage(track.language, track.roles[0]);
}
}
/**
* @private
*/
updateLocalizedStrings_() {
const LocIds = shaka.ui.Locales.Ids;
this.button.setAttribute(shaka.ui.Constants.ARIA_LABEL,
this.localization.resolve(LocIds.CAPTIONS));
this.backButton.setAttribute(shaka.ui.Constants.ARIA_LABEL,
this.localization.resolve(LocIds.BACK));
this.nameSpan.textContent =
this.localization.resolve(LocIds.CAPTIONS);
this.backSpan.textContent =
this.localization.resolve(LocIds.CAPTIONS);
this.captionsOffSpan_.textContent =
this.localization.resolve(LocIds.OFF);
}
/** @private */
onTracksChanged_() {
const hasText = this.player.getTextTracks().length > 0;
shaka.ui.Utils.setDisplay(this.button, hasText);
this.updateTextLanguages_();
}
};
/**
* @implements {shaka.extern.IUIElement.Factory}
* @final
*/
shaka.ui.TextSelection.Factory = class {
/** @override */
create(rootElement, controls) {
return new shaka.ui.TextSelection(rootElement, controls);
}
};
shaka.ui.OverflowMenu.registerElement(
'captions', new shaka.ui.TextSelection.Factory());