mirror of
https://github.com/zhw2590582/ArtPlayer.git
synced 2026-10-27 01:21:20 -08:00
refactor(core): CORE-17 type input events and own interaction lifetimes
This commit is contained in:
1 parent
88aef830df
commit
a842058136
72 files changed
+31156
-1219
No files matched your search
@@ -0,0 +1,94 @@
|
||||
import type { HotkeyCallback, HotkeyHost } from './input/hotkey-types'
|
||||
import { defaultHotkeys } from './input/hotkey-defaults'
|
||||
import { acceptsHotkey } from './input/keyboard-focus'
|
||||
import { getScope, isClosing } from './lifecycle/instance'
|
||||
import { isMobile } from './utils/compatibility'
|
||||
|
||||
interface State {
|
||||
defaults?: () => void
|
||||
subscribed: boolean
|
||||
}
|
||||
const states = new WeakMap<object, State>()
|
||||
|
||||
export default class Hotkey<Host extends HotkeyHost> {
|
||||
declare art: Host
|
||||
declare keys: Record<string, HotkeyCallback<Host>[]>
|
||||
|
||||
constructor(art: Host) {
|
||||
this.art = art
|
||||
this.keys = {}
|
||||
states.set(this, { subscribed: false })
|
||||
if (!isMobile)
|
||||
this.init()
|
||||
}
|
||||
|
||||
init(): void {
|
||||
const art = this.art
|
||||
if (isClosing(art))
|
||||
return
|
||||
const state = states.get(this)!
|
||||
if (art.option.hotkey) {
|
||||
if (!state.defaults) {
|
||||
const callbacks = defaultHotkeys(art)
|
||||
state.defaults = () => {
|
||||
for (const key of Object.keys(callbacks))
|
||||
this.add(key, callbacks[key]!)
|
||||
}
|
||||
}
|
||||
state.defaults()
|
||||
}
|
||||
if (state.subscribed)
|
||||
return
|
||||
state.subscribed = true
|
||||
const onKeydown = (event: KeyboardEvent) => {
|
||||
if (isClosing(art))
|
||||
return
|
||||
if (art.isFocus && acceptsHotkey(event, art.template.$player.ownerDocument)) {
|
||||
const callbacks = Object.prototype.hasOwnProperty.call(this.keys, event.code) ? this.keys[event.code] : undefined
|
||||
if (callbacks) {
|
||||
event.preventDefault()
|
||||
// Keep the historical live-array mutation and callback receiver contracts.
|
||||
for (let index = 0; index < callbacks.length; index++) {
|
||||
if (isClosing(art))
|
||||
return
|
||||
callbacks[index]!.call(art, event)
|
||||
}
|
||||
if (isClosing(art))
|
||||
return
|
||||
art.emit('hotkey', event)
|
||||
}
|
||||
}
|
||||
if (!isClosing(art))
|
||||
art.emit('keydown', event)
|
||||
}
|
||||
art.on('document:keydown', onKeydown)
|
||||
getScope(art).add(() => {
|
||||
state.subscribed = false
|
||||
art.off('document:keydown', onKeydown)
|
||||
})
|
||||
}
|
||||
|
||||
add(key: string, callback: HotkeyCallback<Host>): this {
|
||||
const existing = Object.prototype.hasOwnProperty.call(this.keys, key) ? this.keys[key] : undefined
|
||||
if (existing) {
|
||||
if (!existing.includes(callback))
|
||||
existing.push(callback)
|
||||
}
|
||||
else {
|
||||
Object.defineProperty(this.keys, key, { value: [callback], enumerable: true, configurable: true, writable: true })
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
remove(key: string, callback: HotkeyCallback<Host>): this {
|
||||
const existing = Object.prototype.hasOwnProperty.call(this.keys, key) ? this.keys[key] : undefined
|
||||
if (existing) {
|
||||
const index = existing.indexOf(callback)
|
||||
if (index !== -1)
|
||||
existing.splice(index, 1)
|
||||
if (existing.length === 0)
|
||||
delete this.keys[key]
|
||||
}
|
||||
return this
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user