Skip to content

Commit

Permalink
feat: playback rate button now opens the menu rather than changing th…
Browse files Browse the repository at this point in the history
…e playback rate (videojs#7779)

BREAKING CHANGE: This changes the behavior of the playback rate button.
  • Loading branch information
misteroneill authored and edirub committed Jun 8, 2023
1 parent 9ff7938 commit f64bf8a
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 54 deletions.
34 changes: 3 additions & 31 deletions src/js/control-bar/playback-rate-menu/playback-rate-menu-button.js
Original file line number Diff line number Diff line change
Expand Up @@ -92,36 +92,6 @@ class PlaybackRateMenuButton extends MenuButton {
return items;
}

/**
* Updates ARIA accessibility attributes
*/
updateARIAAttributes() {
// Current playback rate
this.el().setAttribute('aria-valuenow', this.player().playbackRate());
}

/**
* This gets called when an `PlaybackRateMenuButton` is "clicked". See
* {@link ClickableComponent} for more detailed information on what a click can be.
*
* @param {EventTarget~Event} [event]
* The `keydown`, `tap`, or `click` event that caused this function to be
* called.
*
* @listens tap
* @listens click
*/
handleClick(event) {
// select next rate option
const currentRate = this.player().playbackRate();
const rates = this.playbackRates();
const currentIndex = rates.indexOf(currentRate);
// this get the next rate and it will select first one if the last one currently selected
const newIndex = (currentIndex + 1) % rates.length;

this.player().playbackRate(rates[newIndex]);
}

/**
* On playbackrateschange, update the menu to account for the new items.
*
Expand Down Expand Up @@ -191,7 +161,9 @@ class PlaybackRateMenuButton extends MenuButton {
}

/**
* The text that should display over the `FullscreenToggle`s controls. Added for localization.
* The text that should display over the `PlaybackRateMenuButton`s controls.
*
* Added for localization.
*
* @type {string}
* @private
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
/* eslint-env qunit */
import PlaybackRateMenuButton from '../../../../src/js/control-bar/playback-rate-menu/playback-rate-menu-button';
import TestHelpers from '../../test-helpers.js';
import * as Events from '../../../../src/js/utils/events.js';

QUnit.module('PlaybackRateMenuButton', {
beforeEach(assert) {
this.player = TestHelpers.makePlayer({
playbackRates: [1, 2, 3]
});
this.button = this.player.controlBar.playbackRateMenuButton;
},
afterEach(assert) {
this.player.dispose();
Expand All @@ -20,33 +19,43 @@ QUnit.test('playback rate default value', function(assert) {
assert.strictEqual(currentRate, 1, 'Playbackrate begins with value 1"');
});

QUnit.test('clicking should move to the next available rate', function(assert) {
const playbackRateMenu = new PlaybackRateMenuButton(this.player);

const el = playbackRateMenu.menuButton_.el();

Events.trigger(el, 'click');

const currentRate = this.player.playbackRate();
QUnit.test('is visible when playback rates are configured and the tech supports playback rates', function(assert) {
assert.expect(1);
assert.notOk(this.button.hasClass('vjs-hidden'), 'does not have the vjs-hidden class');
});

assert.strictEqual(currentRate, 2, 'Playbackrate changes to value 2"');
QUnit.test('is not visible if no playback rates are configured', function(assert) {
assert.expect(1);
this.player.playbackRates([]);
assert.ok(this.button.hasClass('vjs-hidden'), 'has the vjs-hidden class');
});

QUnit.test('keep clicking should move to all possible rates in loop', function(assert) {
const playbackRateMenu = new PlaybackRateMenuButton(this.player);
QUnit.test('is not visible if the tech does not support playback rates', function(assert) {
assert.expect(1);
this.player.tech_.featuresPlaybackRate = false;

const el = playbackRateMenu.menuButton_.el();
// loadstart is needed to update the hidden state.
this.player.trigger('loadstart');
assert.ok(this.button.hasClass('vjs-hidden'), 'has the vjs-hidden class');
});

Events.trigger(el, 'click');
let currentRate = this.player.playbackRate();
QUnit.test('label is updated when playback rate changes', function(assert) {
assert.expect(4);
assert.strictEqual(this.button.labelEl_.textContent, '1x', 'the default label content is "1x"');
this.player.playbackRate(2);
assert.strictEqual(this.button.labelEl_.textContent, '2x', 'the label content is now "2x"');
this.player.playbackRate(3);
assert.strictEqual(this.button.labelEl_.textContent, '3x', 'the label content is now "3x"');
this.player.playbackRate(4);
assert.strictEqual(this.button.labelEl_.textContent, '4x', 'the playback rate (and label content) can change to values that are not in the rates available in the menu');
});

assert.strictEqual(currentRate, 2, 'Playbackrate changes to value 2"');
QUnit.test('menu is updated when playback rates configuration changes', function(assert) {
assert.expect(2);

Events.trigger(el, 'click');
currentRate = this.player.playbackRate();
assert.strictEqual(currentRate, 3, 'Playbackrate changes to value 3"');
const getItemLabels = () => this.button.menu.children().map(item => item.label);

Events.trigger(el, 'click');
currentRate = this.player.playbackRate();
assert.strictEqual(currentRate, 1, 'Playbackrate changes back to value 1"');
assert.deepEqual(getItemLabels(), ['3x', '2x', '1x'], 'the initial list of items is as expected');
this.player.playbackRates([1, 1.5, 2, 5]);
assert.deepEqual(getItemLabels(), ['5x', '2x', '1.5x', '1x'], 'the list of items was updated');
});

0 comments on commit f64bf8a

Please sign in to comment.