Fix keyboard settings menu keyboard navigation
This commit is contained in:
parent
00b1adab86
commit
2d9e4188b5
|
@ -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'
|
||||
|
|
|
@ -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 }
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue