implement dismiss method instead of event
This commit is contained in:
Родитель
512550c597
Коммит
6807d7e6ba
|
@ -49,12 +49,6 @@
|
|||
}
|
||||
})
|
||||
|
||||
expander.addEventListener('keydown', event => {
|
||||
if (event.key === 'ArrowLeft' || event.key === 'ArrowRight') {
|
||||
expander.dispatchEvent(new CustomEvent('text-expander-dismiss', {cancelable: true}))
|
||||
}
|
||||
})
|
||||
|
||||
expander.addEventListener('text-expander-value', function(event) {
|
||||
const {key, item} = event.detail
|
||||
if (key === '#') event.detail.value = item.getAttribute('data-value') || item.textContent
|
||||
|
|
|
@ -50,7 +50,6 @@ class TextExpander {
|
|||
this.oncommit = this.onCommit.bind(this)
|
||||
this.onmousedown = this.onMousedown.bind(this)
|
||||
this.onblur = this.onBlur.bind(this)
|
||||
this.onDismiss = this.onDismiss.bind(this)
|
||||
this.interactingWithList = false
|
||||
input.addEventListener('paste', this.onpaste)
|
||||
input.addEventListener('input', this.oninput)
|
||||
|
@ -68,7 +67,7 @@ class TextExpander {
|
|||
activate(match: Match, menu: HTMLElement) {
|
||||
if (this.input !== document.activeElement) return
|
||||
|
||||
this.deactivate(this.lookBackIndex)
|
||||
this.deactivate()
|
||||
this.menu = menu
|
||||
|
||||
if (!menu.id) menu.id = `text-expander-${Math.floor(Math.random() * 100000).toString()}`
|
||||
|
@ -82,20 +81,19 @@ class TextExpander {
|
|||
this.combobox.start()
|
||||
menu.addEventListener('combobox-commit', this.oncommit)
|
||||
menu.addEventListener('mousedown', this.onmousedown)
|
||||
this.expander.addEventListener('text-expander-dismiss', this.onDismiss)
|
||||
|
||||
// Focus first menu item.
|
||||
this.combobox.navigate(1)
|
||||
}
|
||||
|
||||
deactivate(cursor: number) {
|
||||
deactivate(cursor?: number) {
|
||||
cursor = cursor || this.input.selectionEnd || this.lookBackIndex
|
||||
const menu = this.menu
|
||||
if (!menu || !this.combobox) return
|
||||
this.menu = null
|
||||
|
||||
menu.removeEventListener('combobox-commit', this.oncommit)
|
||||
menu.removeEventListener('mousedown', this.onmousedown)
|
||||
this.expander.removeEventListener('text-expander-dismiss', this.onDismiss)
|
||||
|
||||
this.combobox.destroy()
|
||||
this.combobox = null
|
||||
|
@ -104,10 +102,6 @@ class TextExpander {
|
|||
this.lookBackIndex = cursor
|
||||
}
|
||||
|
||||
onDismiss() {
|
||||
this.deactivate(this.input.selectionEnd || this.lookBackIndex)
|
||||
}
|
||||
|
||||
onCommit({target}: Event) {
|
||||
const item = target
|
||||
if (!(item instanceof HTMLElement)) return
|
||||
|
@ -144,7 +138,7 @@ class TextExpander {
|
|||
return
|
||||
}
|
||||
|
||||
this.deactivate(this.lookBackIndex)
|
||||
this.deactivate()
|
||||
}
|
||||
|
||||
onPaste() {
|
||||
|
@ -168,11 +162,11 @@ class TextExpander {
|
|||
if (menu) {
|
||||
this.activate(match, menu)
|
||||
} else {
|
||||
this.deactivate(this.lookBackIndex)
|
||||
this.deactivate()
|
||||
}
|
||||
} else {
|
||||
this.match = null
|
||||
this.deactivate(this.lookBackIndex)
|
||||
this.deactivate()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -244,4 +238,10 @@ export default class TextExpanderElement extends HTMLElement {
|
|||
state.destroy()
|
||||
states.delete(this)
|
||||
}
|
||||
|
||||
dismiss() {
|
||||
const state = states.get(this)
|
||||
if (!state) return
|
||||
state.deactivate()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,7 +48,7 @@ describe('text-expander element', function() {
|
|||
assert.equal(':', key)
|
||||
})
|
||||
|
||||
it('Escape triggers text-expander-dismiss', async function() {
|
||||
it('Escape dismisses the menu', async function() {
|
||||
const expander = document.querySelector('text-expander')
|
||||
const input = expander.querySelector('textarea')
|
||||
const menu = document.createElement('ul')
|
||||
|
@ -60,14 +60,13 @@ describe('text-expander element', function() {
|
|||
})
|
||||
|
||||
input.focus()
|
||||
// This is dependent on the implementation detail of text-expander-element
|
||||
// and it needs to await for all the Promises there to fullfil
|
||||
await await await triggerInput(input, ':')
|
||||
triggerInput(input, ':')
|
||||
await waitForAnimationFrame()
|
||||
assert.exists(expander.querySelector('ul'))
|
||||
|
||||
const resultDismiss = once(expander, 'text-expander-dismiss')
|
||||
input.dispatchEvent(new KeyboardEvent('keydown', {key: 'Escape'}))
|
||||
const eventDismiss = await resultDismiss
|
||||
assert.equal(eventDismiss.type, 'text-expander-dismiss')
|
||||
expander.dismiss()
|
||||
await waitForAnimationFrame()
|
||||
assert.isNull(expander.querySelector('ul'))
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -142,3 +141,9 @@ function triggerInput(input, value) {
|
|||
input.value = value
|
||||
return input.dispatchEvent(new InputEvent('input'))
|
||||
}
|
||||
|
||||
async function waitForAnimationFrame() {
|
||||
return new Promise(resolve => {
|
||||
window.requestAnimationFrame(resolve)
|
||||
})
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче