Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix volume menu keyboard access. #3034

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/css/components/_volume.scss
Original file line number Diff line number Diff line change
Expand Up @@ -113,12 +113,16 @@
}

.vjs-volume-menu-button-vertical:hover .vjs-menu-content,
.vjs-volume-menu-button-vertical:focus .vjs-menu-content,
.vjs-volume-menu-button-vertical.vjs-slider-active .vjs-menu-content,
.vjs-volume-menu-button-vertical .vjs-lock-showing .vjs-menu-content {
height: 8em;
width: 2.9em;
}

.vjs-volume-menu-button-horizontal:hover .vjs-menu-content,
.vjs-volume-menu-button-horizontal:focus .vjs-menu-content,
.vjs-volume-menu-button-horizontal .vjs-slider-active .vjs-menu-content,
.vjs-volume-menu-button-horizontal .vjs-lock-showing .vjs-menu-content {
height: 2.9em;
width: 8em;
Expand Down
32 changes: 20 additions & 12 deletions src/js/control-bar/volume-menu-button.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,21 @@
*/
import * as Fn from '../utils/fn.js';
import Component from '../component.js';
import Menu from '../menu/menu.js';
import MenuButton from '../menu/menu-button.js';
import Popup from '../popup/popup.js';
import PopupButton from '../popup/popup-button.js';
import MuteToggle from './mute-toggle.js';
import VolumeBar from './volume-control/volume-bar.js';
import document from 'global/document';

/**
* Button for volume menu
* Button for volume popup
*
* @param {Player|Object} player
* @param {Object=} options
* @extends MenuButton
* @extends PopupButton
* @class VolumeMenuButton
*/
class VolumeMenuButton extends MenuButton {
class VolumeMenuButton extends PopupButton {

constructor(player, options={}){
// Default to inline
Expand Down Expand Up @@ -66,6 +66,14 @@ class VolumeMenuButton extends MenuButton {
this.on(this.volumeBar, ['sliderinactive', 'blur'], function(){
this.removeClass('vjs-slider-active');
});

this.on(this.volumeBar, ['focus'], function(){
this.addClass('vjs-lock-showing');
});

this.on(this.volumeBar, ['blur'], function(){
this.removeClass('vjs-lock-showing');
});
}

/**
Expand All @@ -88,27 +96,27 @@ class VolumeMenuButton extends MenuButton {
/**
* Allow sub components to stack CSS class names
*
* @return {Menu} The volume menu button
* @method createMenu
* @return {Popup} The volume popup button
* @method createPopup
*/
createMenu() {
let menu = new Menu(this.player_, {
createPopup() {
let popup = new Popup(this.player_, {
contentElType: 'div'
});

let vb = new VolumeBar(this.player_, this.options_.volumeBar);

menu.addChild(vb);
popup.addChild(vb);

this.volumeBar = vb;

this.attachVolumeBarEvents();

return menu;
return popup;
}

/**
* Handle click on volume menu and calls super
* Handle click on volume popup and calls super
*
* @method handleClick
*/
Expand Down
91 changes: 91 additions & 0 deletions src/js/popup/popup-button.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/**
* @file popup-button.js
*/
import ClickableComponent from '../clickable-component.js';
import Component from '../component.js';
import Popup from './popup.js';
import * as Dom from '../utils/dom.js';
import * as Fn from '../utils/fn.js';
import toTitleCase from '../utils/to-title-case.js';

/**
* A button class with a popup control
*
* @param {Player|Object} player
* @param {Object=} options
* @extends ClickableComponent
* @class PopupButton
*/
class PopupButton extends ClickableComponent {

constructor(player, options={}){
super(player, options);

this.update();
}

/**
* Update popup
*
* @method update
*/
update() {
let popup = this.createPopup();

if (this.popup) {
this.removeChild(this.popup);
}

this.popup = popup;
this.addChild(popup);

if (this.items && this.items.length === 0) {
this.hide();
} else if (this.items && this.items.length > 1) {
this.show();
}
}

/**
* Create popup - Override with specific functionality for component
*
* @return {Popup} The constructed popup
* @method createPopup
*/
createPopup() {}

/**
* Create the component's DOM element
*
* @return {Element}
* @method createEl
*/
createEl() {
return super.createEl('div', {
className: this.buildCSSClass()
});
}

/**
* Allow sub components to stack CSS class names
*
* @return {String} The constructed class name
* @method buildCSSClass
*/
buildCSSClass() {
var menuButtonClass = 'vjs-menu-button';

// If the inline option is passed, we want to use different styles altogether.
if (this.options_.inline === true) {
menuButtonClass += '-inline';
} else {
menuButtonClass += '-popup';
}

return `vjs-menu-button ${menuButtonClass} ${super.buildCSSClass()}`;
}

}

Component.registerComponent('PopupButton', PopupButton);
export default PopupButton;
59 changes: 59 additions & 0 deletions src/js/popup/popup.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/**
* @file popup.js
*/
import Component from '../component.js';
import * as Dom from '../utils/dom.js';
import * as Fn from '../utils/fn.js';
import * as Events from '../utils/events.js';

/**
* The Popup component is used to build pop up controls.
*
* @extends Component
* @class Popup
*/
class Popup extends Component {

/**
* Add a popup item to the popup
*
* @param {Object|String} component Component or component type to add
* @method addItem
*/
addItem(component) {
this.addChild(component);
component.on('click', Fn.bind(this, function(){
this.unlockShowing();
}));
}

/**
* Create the component's DOM element
*
* @return {Element}
* @method createEl
*/
createEl() {
let contentElType = this.options_.contentElType || 'ul';
this.contentEl_ = Dom.createEl(contentElType, {
className: 'vjs-menu-content'
});
var el = super.createEl('div', {
append: this.contentEl_,
className: 'vjs-menu'
});
el.appendChild(this.contentEl_);

// Prevent clicks from bubbling up. Needed for Popup Buttons,
// where a click on the parent is significant
Events.on(el, 'click', function(event){
event.preventDefault();
event.stopImmediatePropagation();
});

return el;
}
}

Component.registerComponent('Popup', Popup);
export default Popup;