Implement text replacement feature in textarea elements

This commit is contained in:
Aljaž Grilc 2024-03-19 14:03:57 +01:00
parent dbecc61ec3
commit 385e38c06d

View File

@ -18,6 +18,7 @@ class BesService {
this.scrollPanel = scrollPanel
this.statusIcon = statusIcon
this.offsetTop = null
this.textAreaService = null
this.originalSpellcheck = hostElement.spellcheck
this.abortController = new AbortController()
hostElement.spellcheck = false
@ -37,12 +38,13 @@ class BesService {
* @param {Element} hostElement DOM element to register grammar checking service for
* @returns {BesService} Grammar checking service instance
*/
static register(hostElement) {
static register(hostElement, textAreaService) {
let service = new BesService(hostElement)
service.proof(hostElement)
if (service.statusIcon.classList.contains('bes-status-loading')) {
service.updateStatusIcon('bes-status-success')
}
if (textAreaService) service.textAreaService = textAreaService
return service
}
@ -530,7 +532,7 @@ class BesService {
if (m.rects) {
for (let r of m.rects) {
if (BesService.isPointInRect(clientX, clientY, r)) {
popup.changeText(m.match.message)
popup.changeMessage(m.match.message)
m.match.replacements.forEach(replacement => {
popup.appendReplacements(
el,
@ -556,6 +558,9 @@ class BesService {
this.abortController.abort()
match.range.deleteContents()
match.range.insertNode(document.createTextNode(replacement))
if (this.textAreaService) {
this.textAreaService.handleReplacement(this.hostElement)
}
this.clearMistakeMarkup(el)
// In my opinion, this approach provides the most straightforward solution for repositioning mistakes after a change.
// It maintains reasonable performance as it only checks the block element that has been modified,
@ -677,7 +682,7 @@ class BesTAService {
this.textAreaEl = textAreaEl
this.textAreaEl.spellcheck = false
this.cloneDiv = this.createCloneDiv(textAreaEl)
this.service = BesService.register(this.cloneDiv)
this.service = BesService.register(this.cloneDiv, this)
this.textAreaEl.addEventListener('input', () => this.handleInput())
this.textAreaEl.addEventListener('click', e => {
//TODO: Consider adding some kind of proofing?
@ -731,6 +736,11 @@ class BesTAService {
this.cloneDiv.dispatchEvent(customEvent)
}
// TODO: think of a way to reposition the cursor after the replacement
handleReplacement(el) {
this.textAreaEl.value = el.outerText
}
/**
* Registers grammar checking service
*
@ -867,7 +877,7 @@ class BesPopupEl extends HTMLElement {
}
}
changeText(text) {
changeMessage(text) {
this.clear()
this.shadowRoot.querySelector('.popup-text').textContent = text
}