Fix keyboard settings menu keyboard navigation

pull/6449/head
Chocobozzz 2024-06-11 09:15:54 +02:00
parent 00b1adab86
commit 2d9e4188b5
No known key found for this signature in database
GPG Key ID: 583A612D890159BE
4 changed files with 93 additions and 10 deletions

View File

@ -15,6 +15,7 @@ import './shared/control-bar/p2p-info-button'
import './shared/control-bar/peertube-link-button'
import './shared/control-bar/theater-button'
import './shared/control-bar/peertube-live-display'
import './shared/settings/menu-focus-fixed'
import './shared/settings/resolution-menu-button'
import './shared/settings/resolution-menu-item'
import './shared/settings/settings-dialog'

View File

@ -0,0 +1,79 @@
import videojs from 'video.js'
const Menu = videojs.getComponent('Menu')
const Component = videojs.getComponent('Component')
// Default menu doesn't check if the child is disabled/hidden
class MenuFocusFixed extends Menu {
private focusedChild_: number
handleKeyDown (event: KeyboardEvent) {
if (event.key === 'Escape') {
event.preventDefault()
event.stopPropagation()
this.trigger('escaped-key')
return
}
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-expect-error
return super.handleKeyDown(event)
}
stepForward () {
let stepChild = 0
if (this.focusedChild_ !== undefined) {
stepChild = this.focusedChild_ + 1
}
this.focus(stepChild)
}
stepBack () {
let stepChild = 0
if (this.focusedChild_ !== undefined) {
stepChild = this.focusedChild_ - 1
}
this.focus(stepChild)
}
focus (item = 0): void {
const children = this.children().slice()
const haveTitle = children.length && children[0].hasClass('vjs-menu-title')
if (haveTitle) {
children.shift()
}
if (children.length > 0) {
if (item < 0) {
item = 0
} else if (item >= children.length) {
item = children.length - 1
}
const el = children[item].el() as HTMLElement
if (el.classList.contains('vjs-hidden')) {
if (this.focusedChild_ < item) {
if (item === children.length - 1) return
return this.focus(item + 1)
} else {
if (item === 0) return
return this.focus(item - 1)
}
}
this.focusedChild_ = item
el.focus()
}
}
}
Component.registerComponent('MenuFocusFixed', MenuFocusFixed)
export { MenuFocusFixed }

View File

@ -4,9 +4,9 @@ import { SettingsDialog } from './settings-dialog'
import { SettingsMenuItem } from './settings-menu-item'
import { SettingsPanel } from './settings-panel'
import { SettingsPanelChild } from './settings-panel-child'
import { MenuFocusFixed } from './menu-focus-fixed'
const Button = videojs.getComponent('Button')
const Menu = videojs.getComponent('Menu')
const Component = videojs.getComponent('Component')
export interface SettingsButtonOptions extends videojs.ComponentOptions {
@ -19,7 +19,7 @@ export interface SettingsButtonOptions extends videojs.ComponentOptions {
class SettingsButton extends Button {
dialog: SettingsDialog
dialogEl: HTMLElement
menu: videojs.Menu
menu: MenuFocusFixed
panel: SettingsPanel
panelChild: SettingsPanelChild
@ -122,6 +122,7 @@ class SettingsButton extends Button {
bindEvents () {
document.addEventListener('click', this.documentClickHandler)
if (this.isInIframe()) {
window.addEventListener('blur', this.documentClickHandler)
}
@ -153,8 +154,7 @@ class SettingsButton extends Button {
this.setDialogSize(this.getComponentSize(this.menu))
const firstChild = this.menu.children()[0]
if (firstChild) firstChild.focus()
this.menu.focus()
}
hideDialog () {
@ -209,7 +209,12 @@ class SettingsButton extends Button {
}
buildMenu () {
this.menu = new Menu(this.player())
this.menu = new MenuFocusFixed(this.player())
this.menu.on('escaped-key', () => {
this.hideDialog()
this.focus()
})
this.menu.addClass('vjs-main-menu')
const entries = this.settingsButtonOptions.entries

View File

@ -144,7 +144,7 @@ class SettingsMenuItem extends MenuItem {
createEl () {
const el = videojs.dom.createEl('li', {
className: 'vjs-menu-item',
tabIndex: -1
tabIndex: 0
})
this.settingsSubMenuTitleEl_ = videojs.dom.createEl('div', {
@ -191,8 +191,7 @@ class SettingsMenuItem extends MenuItem {
this.settingsButton.setDialogSize(this.size)
const firstChild = this.subMenu.menu.children()[0]
if (firstChild) firstChild.focus()
this.subMenu.menu.focus()
} else {
videojs.dom.addClass(this.settingsSubMenuEl_, 'vjs-hidden')
}
@ -249,8 +248,7 @@ class SettingsMenuItem extends MenuItem {
this.setMargin()
mainMenuEl.style.opacity = '1'
const firstChild = this.mainMenu.children()[0]
if (firstChild) firstChild.focus()
this.mainMenu.focus()
}, 0)
}