mirror of
https://github.com/the1812/Bilibili-Evolved.git
synced 2025-11-04 21:22:45 +08:00
Extract FocusTarget (fix #4732)
This commit is contained in:
parent
1899c12f25
commit
8f701e9434
@ -28,9 +28,9 @@
|
|||||||
v-for="(a, index) of actions"
|
v-for="(a, index) of actions"
|
||||||
:key="a.key"
|
:key="a.key"
|
||||||
:action="a"
|
:action="a"
|
||||||
@previous-item="previousItem($event, index)"
|
@previous-item="previousItem()"
|
||||||
@next-item="nextItem($event, index)"
|
@next-item="nextItem()"
|
||||||
@delete-item="onDeleteItem($event, index)"
|
@delete-item="onDeleteItem()"
|
||||||
@action="
|
@action="
|
||||||
index === actions.length - 1 && onClearHistory()
|
index === actions.length - 1 && onClearHistory()
|
||||||
onAction(a)
|
onAction(a)
|
||||||
@ -49,12 +49,12 @@
|
|||||||
class="suggest-item disabled"
|
class="suggest-item disabled"
|
||||||
></VLoading>
|
></VLoading>
|
||||||
<ActionItem
|
<ActionItem
|
||||||
v-for="(a, index) of actions"
|
v-for="a of actions"
|
||||||
:key="a.key"
|
:key="a.key"
|
||||||
:action="a"
|
:action="a"
|
||||||
@previous-item="previousItem($event, index)"
|
@previous-item="previousItem()"
|
||||||
@next-item="nextItem($event, index)"
|
@next-item="nextItem()"
|
||||||
@delete-item="onDeleteItem($event, index)"
|
@delete-item="onDeleteItem()"
|
||||||
@action="onAction(a)"
|
@action="onAction(a)"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@ -66,6 +66,7 @@ import Fuse from 'fuse.js'
|
|||||||
import { VIcon, VLoading, VEmpty } from '@/ui'
|
import { VIcon, VLoading, VEmpty } from '@/ui'
|
||||||
import { registerAndGetData } from '@/plugins/data'
|
import { registerAndGetData } from '@/plugins/data'
|
||||||
import { select } from '@/core/spin-query'
|
import { select } from '@/core/spin-query'
|
||||||
|
import { ascendingSort } from '@/core/utils/sort'
|
||||||
import { matchUrlPattern } from '@/core/utils'
|
import { matchUrlPattern } from '@/core/utils'
|
||||||
import ActionItem from './ActionItem.vue'
|
import ActionItem from './ActionItem.vue'
|
||||||
import {
|
import {
|
||||||
@ -75,7 +76,7 @@ import {
|
|||||||
} from './launch-bar-action'
|
} from './launch-bar-action'
|
||||||
import { searchProvider, search } from './search-provider'
|
import { searchProvider, search } from './search-provider'
|
||||||
import { historyProvider } from './history-provider'
|
import { historyProvider } from './history-provider'
|
||||||
import { ascendingSort } from '@/core/utils/sort'
|
import { FocusTarget } from './focus-target'
|
||||||
|
|
||||||
const [actionProviders] = registerAndGetData(LaunchBarActionProviders, [
|
const [actionProviders] = registerAndGetData(LaunchBarActionProviders, [
|
||||||
searchProvider,
|
searchProvider,
|
||||||
@ -144,10 +145,12 @@ export default Vue.extend({
|
|||||||
ActionItem,
|
ActionItem,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
|
const focusTarget = new FocusTarget(0)
|
||||||
return {
|
return {
|
||||||
recommended,
|
recommended,
|
||||||
actions: [],
|
actions: [],
|
||||||
keyword: '',
|
keyword: '',
|
||||||
|
focusTarget,
|
||||||
noActions: false,
|
noActions: false,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -160,9 +163,15 @@ export default Vue.extend({
|
|||||||
keyword() {
|
keyword() {
|
||||||
this.getActions()
|
this.getActions()
|
||||||
},
|
},
|
||||||
|
actions() {
|
||||||
|
this.focusTarget.reset(this.actions.length)
|
||||||
|
},
|
||||||
},
|
},
|
||||||
async mounted() {
|
async mounted() {
|
||||||
this.getActions()
|
await this.getActions()
|
||||||
|
this.focusTarget.addEventListener('index-change', () => {
|
||||||
|
this.handleIndexUpdate()
|
||||||
|
})
|
||||||
if (!matchUrlPattern(/^https?:\/\/search\.bilibili\.com/)) {
|
if (!matchUrlPattern(/^https?:\/\/search\.bilibili\.com/)) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -211,47 +220,47 @@ export default Vue.extend({
|
|||||||
if (e.isComposing) {
|
if (e.isComposing) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
this.$refs.list.querySelector('.suggest-item:last-child').focus()
|
this.focusTarget.previous()
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
},
|
},
|
||||||
handleDown(e: KeyboardEvent) {
|
handleDown(e: KeyboardEvent) {
|
||||||
if (e.isComposing) {
|
if (e.isComposing) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
this.$refs.list.querySelector('.suggest-item').focus()
|
this.focusTarget.next()
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
},
|
},
|
||||||
previousItem(element: HTMLElement, index: number) {
|
handleIndexUpdate() {
|
||||||
if (index === 0) {
|
if (!this.focusTarget.hasFocus) {
|
||||||
this.focus()
|
this.focusInput()
|
||||||
} else {
|
return
|
||||||
;(element.previousElementSibling as HTMLElement).focus()
|
|
||||||
}
|
}
|
||||||
|
this.focusSuggestItem(this.focusTarget.index + 1)
|
||||||
},
|
},
|
||||||
nextItem(element: HTMLElement, index: number) {
|
previousItem() {
|
||||||
const lastItemIndex = this.actions.length - 1
|
this.focusTarget.previous()
|
||||||
if (index !== lastItemIndex) {
|
},
|
||||||
;(element.nextElementSibling as HTMLElement).focus()
|
nextItem() {
|
||||||
} else {
|
this.focusTarget.next()
|
||||||
this.focus()
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
search,
|
search,
|
||||||
onDeleteItem(element: HTMLElement, index: number) {
|
onDeleteItem() {
|
||||||
this.previousItem(element, index)
|
this.focusTarget.previous()
|
||||||
this.getActions()
|
this.getActions()
|
||||||
},
|
},
|
||||||
onClearHistory() {
|
onClearHistory() {
|
||||||
this.focus()
|
this.focusInput()
|
||||||
this.getActions()
|
this.getActions()
|
||||||
},
|
},
|
||||||
onAction() {
|
onAction() {
|
||||||
// this.focus()
|
|
||||||
this.handleSelect()
|
this.handleSelect()
|
||||||
},
|
},
|
||||||
focus() {
|
focusInput() {
|
||||||
this.$refs.input.focus()
|
this.$refs.input.focus()
|
||||||
},
|
},
|
||||||
|
focusSuggestItem(nth: number) {
|
||||||
|
this.$refs.list.querySelector(`.suggest-item:nth-child(${nth})`)?.focus()
|
||||||
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
38
src/components/launch-bar/focus-target.ts
Normal file
38
src/components/launch-bar/focus-target.ts
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
export class FocusTarget extends EventTarget {
|
||||||
|
/**
|
||||||
|
* -1: Input Focus
|
||||||
|
* > -1: Item Focus
|
||||||
|
*/
|
||||||
|
private itemIndex = -1
|
||||||
|
private itemLength = 0
|
||||||
|
|
||||||
|
constructor(length: number, index = -1) {
|
||||||
|
super()
|
||||||
|
this.itemLength = length
|
||||||
|
this.index = index
|
||||||
|
}
|
||||||
|
|
||||||
|
get index() {
|
||||||
|
return this.itemIndex
|
||||||
|
}
|
||||||
|
private set index(value: number) {
|
||||||
|
this.itemIndex = lodash.clamp(value, -1, this.itemLength - 1)
|
||||||
|
this.dispatchEvent(new CustomEvent('index-change', { detail: this }))
|
||||||
|
}
|
||||||
|
get hasFocus() {
|
||||||
|
return this.itemIndex > -1
|
||||||
|
}
|
||||||
|
|
||||||
|
reset(length: number, index = this.index) {
|
||||||
|
this.itemLength = length
|
||||||
|
this.index = index
|
||||||
|
}
|
||||||
|
next() {
|
||||||
|
this.index += 1
|
||||||
|
console.log(this.index)
|
||||||
|
}
|
||||||
|
previous() {
|
||||||
|
this.index -= 1
|
||||||
|
console.log(this.index)
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user