mirror of
https://github.com/videojs/video.js.git
synced 2025-02-12 12:16:27 +02:00
fix: make 'Esc' works for a vertical volume bar and menus (#6046)
Improve player accessibility by adding 'Esc' functionality to the volume panel and menu popups. Fixes #6004.
This commit is contained in:
parent
51b9861d5b
commit
62465b841e
@ -32,35 +32,33 @@
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
margin-left: -1px;
|
||||
|
||||
}
|
||||
|
||||
.video-js .vjs-volume-panel {
|
||||
&:hover .vjs-volume-control,
|
||||
&.vjs-hover .vjs-volume-control,
|
||||
&:active .vjs-volume-control,
|
||||
&:focus .vjs-volume-control,
|
||||
& .vjs-volume-control:hover ,
|
||||
& .vjs-volume-control:active ,
|
||||
& .vjs-mute-control:hover ~ .vjs-volume-control,
|
||||
& .vjs-volume-control:active,
|
||||
&.vjs-hover .vjs-mute-control ~ .vjs-volume-control,
|
||||
& .vjs-volume-control.vjs-slider-active {
|
||||
&.vjs-volume-horizontal {
|
||||
width: 5em;
|
||||
height: 3em;
|
||||
}
|
||||
|
||||
visibility: visible;
|
||||
opacity: 1;
|
||||
position: relative;
|
||||
|
||||
&.vjs-volume-vertical {
|
||||
left: -3.5em;
|
||||
@include transition(left 0s);
|
||||
}
|
||||
$transition-property: visibility 0.1s, opacity 0.1s, height 0.1s, width 0.1s, left 0s, top 0s;
|
||||
@include transition($transition-property);
|
||||
}
|
||||
|
||||
&.vjs-volume-panel-horizontal {
|
||||
&:hover,
|
||||
&.vjs-hover,
|
||||
&:active,
|
||||
&.vjs-slider-active {
|
||||
width: 9em;
|
||||
@ -83,6 +81,7 @@
|
||||
$transition-property: visibility 1s, opacity 1s, height 1s 1s, width 1s 1s, left 1s 1s, top 1s 1s;
|
||||
@include transition($transition-property)
|
||||
}
|
||||
|
||||
.video-js .vjs-volume-panel .vjs-volume-control.vjs-volume-horizontal {
|
||||
$transition-property: visibility 1s, opacity 1s, height 1s 1s, width 1s, left 1s 1s, top 1s 1s;
|
||||
@include transition($transition-property)
|
||||
|
@ -38,7 +38,7 @@
|
||||
max-height: 25em;
|
||||
}
|
||||
|
||||
.vjs-workinghover .vjs-menu-button-popup:hover .vjs-menu,
|
||||
.vjs-workinghover .vjs-menu-button-popup.vjs-hover .vjs-menu,
|
||||
.vjs-menu-button-popup .vjs-menu.vjs-lock-showing {
|
||||
display: block;
|
||||
}
|
||||
|
@ -168,6 +168,8 @@ class ClickableComponent extends Component {
|
||||
if (typeof this.tabIndex_ !== 'undefined') {
|
||||
this.el_.removeAttribute('tabIndex');
|
||||
}
|
||||
this.off('mouseover', this.handleMouseOver);
|
||||
this.off('mouseout', this.handleMouseOut);
|
||||
this.off(['tap', 'click'], this.handleClick);
|
||||
this.off('keydown', this.handleKeyDown);
|
||||
}
|
||||
|
@ -3,6 +3,10 @@
|
||||
*/
|
||||
import Component from '../component.js';
|
||||
import {isPlain} from '../utils/obj';
|
||||
import * as Events from '../utils/events.js';
|
||||
import * as Fn from '../utils/fn.js';
|
||||
import keycode from 'keycode';
|
||||
import document from 'global/document';
|
||||
|
||||
// Required children
|
||||
import './volume-control/volume-control.js';
|
||||
@ -42,6 +46,11 @@ class VolumePanel extends Component {
|
||||
super(player, options);
|
||||
|
||||
this.on(player, ['loadstart'], this.volumePanelState_);
|
||||
this.on(this.muteToggle, 'keyup', this.handleKeyPress);
|
||||
this.on(this.volumeControl, 'keyup', this.handleVolumeControlKeyUp);
|
||||
this.on('keydown', this.handleKeyPress);
|
||||
this.on('mouseover', this.handleMouseOver);
|
||||
this.on('mouseout', this.handleMouseOut);
|
||||
|
||||
// while the slider is active (the mouse has been pressed down and
|
||||
// is dragging) we do not want to hide the VolumeBar
|
||||
@ -109,6 +118,73 @@ class VolumePanel extends Component {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispose of the `volume-panel` and all child components.
|
||||
*/
|
||||
dispose() {
|
||||
this.handleMouseOut();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles `keyup` events on the `VolumeControl`, looking for ESC, which closes
|
||||
* the volume panel and sets focus on `MuteToggle`.
|
||||
*
|
||||
* @param {EventTarget~Event} event
|
||||
* The `keyup` event that caused this function to be called.
|
||||
*
|
||||
* @listens keyup
|
||||
*/
|
||||
handleVolumeControlKeyUp(event) {
|
||||
if (keycode.isEventKey(event, 'Esc')) {
|
||||
this.muteToggle.focus();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This gets called when a `VolumePanel` gains hover via a `mouseover` event.
|
||||
* Turns on listening for `mouseover` event. When they happen it
|
||||
* calls `this.handleMouseOver`.
|
||||
*
|
||||
* @param {EventTarget~Event} event
|
||||
* The `mouseover` event that caused this function to be called.
|
||||
*
|
||||
* @listens mouseover
|
||||
*/
|
||||
handleMouseOver(event) {
|
||||
this.addClass('vjs-hover');
|
||||
Events.on(document, 'keyup', Fn.bind(this, this.handleKeyPress));
|
||||
}
|
||||
|
||||
/**
|
||||
* This gets called when a `VolumePanel` gains hover via a `mouseout` event.
|
||||
* Turns on listening for `mouseout` event. When they happen it
|
||||
* calls `this.handleMouseOut`.
|
||||
*
|
||||
* @param {EventTarget~Event} event
|
||||
* The `mouseout` event that caused this function to be called.
|
||||
*
|
||||
* @listens mouseout
|
||||
*/
|
||||
handleMouseOut(event) {
|
||||
this.removeClass('vjs-hover');
|
||||
Events.off(document, 'keyup', Fn.bind(this, this.handleKeyPress));
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles `keyup` event on the document or `keydown` event on the `VolumePanel`,
|
||||
* looking for ESC, which hides the `VolumeControl`.
|
||||
*
|
||||
* @param {EventTarget~Event} event
|
||||
* The keypress that triggered this event.
|
||||
*
|
||||
* @listens keydown | keyup
|
||||
*/
|
||||
handleKeyPress(event) {
|
||||
if (keycode.isEventKey(event, 'Esc')) {
|
||||
this.handleMouseOut();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -5,8 +5,11 @@ import Button from '../button.js';
|
||||
import Component from '../component.js';
|
||||
import Menu from './menu.js';
|
||||
import * as Dom from '../utils/dom.js';
|
||||
import * as Fn from '../utils/fn.js';
|
||||
import * as Events from '../utils/events.js';
|
||||
import {toTitleCase} from '../utils/string-cases.js';
|
||||
import { IS_IOS } from '../utils/browser.js';
|
||||
import document from 'global/document';
|
||||
import keycode from 'keycode';
|
||||
|
||||
/**
|
||||
@ -49,9 +52,11 @@ class MenuButton extends Component {
|
||||
this.on(this.menuButton_, 'click', this.handleClick);
|
||||
this.on(this.menuButton_, 'keydown', this.handleKeyDown);
|
||||
this.on(this.menuButton_, 'mouseenter', () => {
|
||||
this.addClass('vjs-hover');
|
||||
this.menu.show();
|
||||
Events.on(document, 'keyup', Fn.bind(this, this.handleMenuKeyUp));
|
||||
});
|
||||
|
||||
this.on('mouseleave', this.handleMouseLeave);
|
||||
this.on('keydown', this.handleSubmenuKeyDown);
|
||||
}
|
||||
|
||||
@ -210,6 +215,14 @@ class MenuButton extends Component {
|
||||
return this.menuButton_.controlText(text, el);
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispose of the `menu-button` and all child components.
|
||||
*/
|
||||
dispose() {
|
||||
this.handleMouseLeave();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle a click on a `MenuButton`.
|
||||
* See {@link ClickableComponent#handleClick} for instances where this is called.
|
||||
@ -229,6 +242,19 @@ class MenuButton extends Component {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle `mouseleave` for `MenuButton`.
|
||||
*
|
||||
* @param {EventTarget~Event} event
|
||||
* The `mouseleave` event that caused this function to be called.
|
||||
*
|
||||
* @listens mouseleave
|
||||
*/
|
||||
handleMouseLeave(event) {
|
||||
this.removeClass('vjs-hover');
|
||||
Events.off(document, 'keyup', Fn.bind(this, this.handleMenuKeyUp));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the focus to the actual button, not to this element
|
||||
*/
|
||||
@ -275,6 +301,22 @@ class MenuButton extends Component {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle a `keyup` event on a `MenuButton`. The listener for this is added in
|
||||
* the constructor.
|
||||
*
|
||||
* @param {EventTarget~Event} event
|
||||
* Key press event
|
||||
*
|
||||
* @listens keyup
|
||||
*/
|
||||
handleMenuKeyUp(event) {
|
||||
// Escape hides popup menu
|
||||
if (keycode.isEventKey(event, 'Esc') || keycode.isEventKey(event, 'Tab')) {
|
||||
this.removeClass('vjs-hover');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method name now delegates to `handleSubmenuKeyDown`. This means
|
||||
* anyone calling `handleSubmenuKeyPress` will not see their method calls
|
||||
|
Loading…
x
Reference in New Issue
Block a user