Implement functionality to replace text with suggestions inside popup.

It is not the cleanest solution because it requires passing editor object across multiple functions.
This commit is contained in:
Aljaž Grilc 2024-02-14 09:32:21 +01:00
parent a6130c39ce
commit 3b9d2dd73b

View File

@ -175,7 +175,11 @@ class BesEditor {
if (mutation.type === 'characterData') { if (mutation.type === 'characterData') {
this.clearProofed(this.getBlockParent(mutation.target)) this.clearProofed(this.getBlockParent(mutation.target))
} }
if (mutation.type === 'childList' && mutation.removedNodes.length) { if (
mutation.type === 'childList' &&
mutation.removedNodes.length &&
!mutation.addedNodes.length
) {
mutation.removedNodes.forEach(node => { mutation.removedNodes.forEach(node => {
// TODO: This is a temporary solution. We need to handle all cases such as <p></p>, <br>, etc. // TODO: This is a temporary solution. We need to handle all cases such as <p></p>, <br>, etc.
if (node.nodeName === 'DIV') { if (node.nodeName === 'DIV') {
@ -312,11 +316,12 @@ class BesEditor {
} }
if ( if (
BesEditor.renderPopup( BesEditor.renderPopup(
targetEl,
matches, matches,
popup, popup,
e.clientX, e.clientX,
e.clientY, e.clientY,
this.offsetTop this
) )
) )
return return
@ -329,17 +334,19 @@ class BesEditor {
this.offsetTop = editor.scrollTop this.offsetTop = editor.scrollTop
} }
static renderPopup(matches, popup, clientX, clientY, offsetTop) { static renderPopup(el, matches, popup, clientX, clientY, editor) {
for (let m of matches) { for (let m of matches) {
if (m.rects) { if (m.rects) {
for (let r of m.rects) { for (let r of m.rects) {
if (BesEditor.isPointInRect(clientX, clientY, r, offsetTop)) { if (BesEditor.isPointInRect(clientX, clientY, r, editor.offsetTop)) {
popup.changeText(m.match.message) popup.changeText(m.match.message)
m.match.replacements.forEach(replacement => { m.match.replacements.forEach(replacement => {
popup.appendReplacements( popup.appendReplacements(
el,
r,
m.match,
replacement.value, replacement.value,
m.match.offset, editor
m.match.length
) )
}) })
popup.show(clientX, clientY) popup.show(clientX, clientY)
@ -353,6 +360,35 @@ class BesEditor {
return false return false
} }
static replaceText(el, rect, match, replacement, editor) {
const text = el.textContent
const newText =
text.substring(0, match.offset) +
replacement +
text.substring(match.offset + match.length)
el.textContent = newText
BesEditor.clearSingleMistake(editor, el, rect)
}
// This function clears a single mistake
static clearSingleMistake(editor, el, rect) {
const childToDelete = editor.children.filter(
child => child.elements === el
)[0]
childToDelete.isProofed = false
childToDelete.matches = childToDelete.matches.filter(
match => !BesEditor.isPointInRect(rect.left, rect.top, match.rects[0])
)
// TODO: find a better way to remove elements from the DOM
Array.from(editor.scrollPanel.children)
.filter(child => {
const childRect = child.getBoundingClientRect()
return BesEditor.isPointInRect(childRect.left, childRect.top, rect)
})
.forEach(child => child.remove())
}
setCorrectionPanelSize(editor, correctionPanel, scrollPanel) { setCorrectionPanelSize(editor, correctionPanel, scrollPanel) {
const styles = window.getComputedStyle(editor) const styles = window.getComputedStyle(editor)
const totalWidth = const totalWidth =
@ -526,14 +562,15 @@ class BesPopupEl extends HTMLElement {
this.shadowRoot.querySelector('.popup-text').textContent = text this.shadowRoot.querySelector('.popup-text').textContent = text
} }
appendReplacements(replacement, offset, length) { appendReplacements(el, rect, match, replacement, editor) {
const replacementDiv = this.shadowRoot.querySelector('.bes-replacement-div') const replacementDiv = this.shadowRoot.querySelector('.bes-replacement-div')
const replacementBtn = document.createElement('button') const replacementBtn = document.createElement('button')
replacementBtn.classList.add('bes-replacement-btn') replacementBtn.classList.add('bes-replacement-btn')
replacementBtn.dataset.length = length
replacementBtn.dataset.offset = offset
replacementBtn.textContent = replacement replacementBtn.textContent = replacement
replacementBtn.classList.add('bes-replacement') replacementBtn.classList.add('bes-replacement')
replacementBtn.addEventListener('click', () => {
BesEditor.replaceText(el, rect, match, replacement, editor)
})
replacementDiv.appendChild(replacementBtn) replacementDiv.appendChild(replacementBtn)
} }
} }