Source: ui/playback_rate_selection.js

  1. /*! @license
  2. * Shaka Player
  3. * Copyright 2016 Google LLC
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. goog.provide('shaka.ui.PlaybackRateSelection');
  7. goog.require('shaka.ui.Controls');
  8. goog.require('shaka.ui.Enums');
  9. goog.require('shaka.ui.Locales');
  10. goog.require('shaka.ui.Localization');
  11. goog.require('shaka.ui.OverflowMenu');
  12. goog.require('shaka.ui.SettingsMenu');
  13. goog.require('shaka.ui.Utils');
  14. goog.require('shaka.util.Dom');
  15. goog.requireType('shaka.ui.Controls');
  16. /**
  17. * @extends {shaka.ui.SettingsMenu}
  18. * @final
  19. * @export
  20. */
  21. shaka.ui.PlaybackRateSelection = class extends shaka.ui.SettingsMenu {
  22. /**
  23. * @param {!HTMLElement} parent
  24. * @param {!shaka.ui.Controls} controls
  25. */
  26. constructor(parent, controls) {
  27. super(parent, controls, shaka.ui.Enums.MaterialDesignIcons.PLAYBACK_RATE);
  28. this.button.classList.add('shaka-playbackrate-button');
  29. this.menu.classList.add('shaka-playback-rates');
  30. this.button.classList.add('shaka-tooltip-status');
  31. this.eventManager.listen(
  32. this.localization, shaka.ui.Localization.LOCALE_UPDATED, () => {
  33. this.updateLocalizedStrings_();
  34. });
  35. this.eventManager.listen(
  36. this.localization, shaka.ui.Localization.LOCALE_CHANGED, () => {
  37. this.updateLocalizedStrings_();
  38. });
  39. this.eventManager.listen(this.player, 'loaded', () => {
  40. this.updatePlaybackRateSelection_();
  41. });
  42. this.eventManager.listen(this.player, 'ratechange', () => {
  43. this.updatePlaybackRateSelection_();
  44. });
  45. // Set up all the strings in the user's preferred language.
  46. this.updateLocalizedStrings_();
  47. this.addPlaybackRates_();
  48. this.updatePlaybackRateSelection_();
  49. }
  50. /**
  51. * @private
  52. */
  53. updateLocalizedStrings_() {
  54. const LocIds = shaka.ui.Locales.Ids;
  55. this.backButton.ariaLabel = this.localization.resolve(LocIds.BACK);
  56. this.button.ariaLabel = this.localization.resolve(LocIds.PLAYBACK_RATE);
  57. this.nameSpan.textContent = this.localization.resolve(LocIds.PLAYBACK_RATE);
  58. this.backSpan.textContent = this.localization.resolve(LocIds.PLAYBACK_RATE);
  59. }
  60. /**
  61. * Update checkmark icon and related class and attribute for the chosen rate
  62. * button.
  63. * @private
  64. */
  65. updatePlaybackRateSelection_() {
  66. const rate = this.player.getPlaybackRate();
  67. // Remove the old checkmark icon and related tags and classes if it exists.
  68. const checkmarkIcon = shaka.ui.Utils.getDescendantIfExists(
  69. this.menu, 'material-icons-round shaka-chosen-item');
  70. if (checkmarkIcon) {
  71. const previouslySelectedButton = checkmarkIcon.parentElement;
  72. previouslySelectedButton.removeAttribute('aria-selected');
  73. const previouslySelectedSpan =
  74. previouslySelectedButton.getElementsByTagName('span')[0];
  75. previouslySelectedSpan.classList.remove('shaka-chosen-item');
  76. previouslySelectedButton.removeChild(checkmarkIcon);
  77. }
  78. // Find the button that represents the newly selected playback rate.
  79. // Add the checkmark icon, related tags and classes to the newly selected
  80. // button.
  81. const span = Array.from(this.menu.querySelectorAll('span')).find((el) => {
  82. return el.textContent == (rate + 'x');
  83. });
  84. if (span) {
  85. const button = span.parentElement;
  86. button.appendChild(shaka.ui.Utils.checkmarkIcon());
  87. button.ariaSelected = 'true';
  88. span.classList.add('shaka-chosen-item');
  89. }
  90. // Set the label to display the current playback rate in the overflow menu,
  91. // in the format of '1x', '1.5x', etc.
  92. this.currentSelection.textContent = rate + 'x';
  93. this.button.setAttribute('shaka-status', rate + 'x');
  94. }
  95. /** @private */
  96. addPlaybackRates_() {
  97. for (const rate of this.controls.getConfig().playbackRates) {
  98. const button = shaka.util.Dom.createButton();
  99. const span = shaka.util.Dom.createHTMLElement('span');
  100. span.textContent = rate + 'x';
  101. button.appendChild(span);
  102. this.eventManager.listen(button, 'click', () => {
  103. if (rate == this.video.defaultPlaybackRate) {
  104. this.player.cancelTrickPlay();
  105. } else {
  106. this.player.trickPlay(rate, /* useTrickPlayTrack= */ false);
  107. }
  108. });
  109. this.menu.appendChild(button);
  110. }
  111. shaka.ui.Utils.focusOnTheChosenItem(this.menu);
  112. }
  113. };
  114. /**
  115. * @implements {shaka.extern.IUIElement.Factory}
  116. * @final
  117. */
  118. shaka.ui.PlaybackRateSelection.Factory = class {
  119. /** @override */
  120. create(rootElement, controls) {
  121. return new shaka.ui.PlaybackRateSelection(rootElement, controls);
  122. }
  123. };
  124. shaka.ui.OverflowMenu.registerElement(
  125. 'playback_rate', new shaka.ui.PlaybackRateSelection.Factory());
  126. shaka.ui.Controls.registerElement(
  127. 'playback_rate', new shaka.ui.PlaybackRateSelection.Factory());