Merge pull request #19 from iulia-b/main

Introduce dismiss event for text-expander-element
This commit is contained in:
Keith Cirkel 2020-11-25 16:00:52 +01:00 коммит произвёл GitHub
Родитель 760da4af27 91eec2b936
Коммит 013352b711
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
3 изменённых файлов: 62 добавлений и 19 удалений

Просмотреть файл

@ -21,10 +21,10 @@ export default function query(
const keyIndex = text.lastIndexOf(key, cursor - 1)
if (keyIndex === -1) return
if (multiWord) {
// Stop matching at the lookBackIndex
if (keyIndex < lookBackIndex) return
// Stop matching at the lookBackIndex
if (keyIndex < lookBackIndex) return
if (multiWord) {
// Space immediately after activation key
const charAfterKey = text[keyIndex + 1]
if (charAfterKey === ' ') return

Просмотреть файл

@ -64,7 +64,13 @@ class TextExpander {
this.input.removeEventListener('blur', this.onblur)
}
activate(match: Match, menu: HTMLElement) {
dismissMenu() {
if (this.deactivate()) {
this.lookBackIndex = this.input.selectionEnd || this.lookBackIndex
}
}
private activate(match: Match, menu: HTMLElement) {
if (this.input !== document.activeElement) return
this.deactivate()
@ -86,19 +92,22 @@ class TextExpander {
this.combobox.navigate(1)
}
deactivate() {
private deactivate() {
const menu = this.menu
if (!menu || !this.combobox) return
if (!menu || !this.combobox) return false
this.menu = null
menu.removeEventListener('combobox-commit', this.oncommit)
menu.removeEventListener('mousedown', this.onmousedown)
this.combobox.destroy()
this.combobox = null
menu.remove()
return true
}
onCommit({target}: Event) {
private onCommit({target}: Event) {
const item = target
if (!(item instanceof HTMLElement)) return
if (!this.combobox) return
@ -118,17 +127,17 @@ class TextExpander {
this.input.value = beginning + value + remaining
const cursor = beginning.length + value.length
this.deactivate()
this.input.focus()
const cursor = beginning.length + value.length
this.input.selectionStart = cursor
this.input.selectionEnd = cursor
this.lookBackIndex = cursor
}
onBlur() {
private onBlur() {
if (this.interactingWithList) {
this.interactingWithList = false
return
@ -137,7 +146,7 @@ class TextExpander {
this.deactivate()
}
onPaste() {
private onPaste() {
this.justPasted = true
}
@ -193,19 +202,20 @@ class TextExpander {
return fragments[0]
}
onMousedown() {
private onMousedown() {
this.interactingWithList = true
}
onKeydown(event: KeyboardEvent) {
if (event.key === 'Escape' && (this.menu || this.combobox)) {
this.deactivate()
event.stopImmediatePropagation()
event.preventDefault()
private onKeydown(event: KeyboardEvent) {
if (event.key === 'Escape') {
if (this.deactivate()) {
this.lookBackIndex = this.input.selectionEnd || this.lookBackIndex
event.stopImmediatePropagation()
event.preventDefault()
}
}
}
}
export default class TextExpanderElement extends HTMLElement {
get keys(): Key[] {
const keysAttr = this.getAttribute('keys')
@ -226,9 +236,15 @@ export default class TextExpanderElement extends HTMLElement {
}
disconnectedCallback() {
const state = states.get(this)
const state: TextExpander = states.get(this)
if (!state) return
state.destroy()
states.delete(this)
}
dismiss() {
const state: TextExpander = states.get(this)
if (!state) return
state.dismissMenu()
}
}

Просмотреть файл

@ -47,6 +47,27 @@ describe('text-expander element', function() {
const {key} = event.detail
assert.equal(':', key)
})
it('dismisses the menu when dismiss() is called', async function() {
const expander = document.querySelector('text-expander')
const input = expander.querySelector('textarea')
const menu = document.createElement('ul')
menu.appendChild(document.createElement('li'))
expander.addEventListener('text-expander-change', event => {
const {provide} = event.detail
provide(Promise.resolve({matched: true, fragment: menu}))
})
input.focus()
triggerInput(input, ':')
await waitForAnimationFrame()
assert.exists(expander.querySelector('ul'))
expander.dismiss()
await waitForAnimationFrame()
assert.isNull(expander.querySelector('ul'))
})
})
describe('multi-word scenarios', function() {
@ -120,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)
})
}