Refactor correction panel creation to support scroll functionality

This feature is not fully tested, there are still some bugs left, i.e., after scroll event the popup is unavailable
This commit is contained in:
Aljaž Grilc 2024-02-09 10:38:31 +01:00
parent 40631798d1
commit 5d9d22bfef
2 changed files with 58 additions and 19 deletions

View File

@ -7,10 +7,15 @@ class BesEditor {
this.el = edit
this.timer = null
this.children = []
this.correctionPanel = this.createCorrectionPanel(edit)
const { correctionPanel, scrollPanel } = this.createCorrectionPanel(edit)
this.correctionPanel = correctionPanel
this.scrollPanel = scrollPanel
this.proof(edit)
edit.addEventListener('beforeinput', e => this.handleBeforeInput(e), false)
edit.addEventListener('click', e => this.handleClick(e))
edit.addEventListener('scroll', () =>
this.handleScrollEvent(this.el, this.scrollPanel)
)
}
// Register editor
@ -104,7 +109,7 @@ class BesEditor {
matches.push({
range: range,
rects: this.addMistakeMarkup(range, this.correctionPanel),
rects: this.addMistakeMarkup(range, this.scrollPanel),
match: match
})
})
@ -140,14 +145,17 @@ class BesEditor {
createCorrectionPanel(edit) {
const panelParent = document.createElement('div')
panelParent.classList.add('bes-correction-panel-parent')
const panel = document.createElement('div')
this.setCorrectionPanelSize(edit, panel)
panel.classList.add('bes-correction-panel')
const correctionPanel = document.createElement('div')
const scrollPanel = document.createElement('div')
this.setCorrectionPanelSize(edit, correctionPanel, scrollPanel)
correctionPanel.classList.add('bes-correction-panel')
scrollPanel.classList.add('bes-correction-panel-scroll')
panelParent.appendChild(panel)
correctionPanel.appendChild(scrollPanel)
panelParent.appendChild(correctionPanel)
edit.parentElement.insertBefore(panelParent, edit)
return panel
return { correctionPanel, scrollPanel }
}
// Marks section of text that is about to change as not-yet-grammar-proofed.
@ -203,7 +211,7 @@ class BesEditor {
// TODO: Remove elements that are found in editor object, that way we can avoid looping through all elements.
filteredChildren[0].matches.forEach(match => {
for (const rect of match.rects) {
for (let child of this.correctionPanel.children) {
for (let child of this.scrollPanel.children) {
let childRect = child.getBoundingClientRect()
const isWithinRect =
childRect.left >= rect.left &&
@ -219,21 +227,21 @@ class BesEditor {
}
// Adds grammar mistake markup
addMistakeMarkup(range, correctionPanel) {
addMistakeMarkup(range, scrollPanel) {
// TODO: Consider using range.getClientRects() instead of range.getBoundingClientRect()
const clientRects = range.getClientRects()
const correctionPanelRect = correctionPanel.getBoundingClientRect()
const scrollPanelRect = scrollPanel.getBoundingClientRect()
for (let i = 0, n = clientRects.length; i < n; ++i) {
const rect = clientRects[i]
const highlight = document.createElement('div')
highlight.classList.add('bes-typo-mistake')
const topPosition = rect.top - correctionPanelRect.top
const leftPosition = rect.left - correctionPanelRect.left
const topPosition = rect.top - scrollPanelRect.top
const leftPosition = rect.left - scrollPanelRect.left
highlight.style.left = `${leftPosition}px`
highlight.style.top = `${topPosition}px`
highlight.style.width = `${rect.width}px`
highlight.style.height = `${rect.height}px`
this.correctionPanel.appendChild(highlight)
this.scrollPanel.appendChild(highlight)
}
return clientRects
}
@ -281,6 +289,10 @@ class BesEditor {
}
}
handleScrollEvent(editor, scrollPanel) {
scrollPanel.style.top = -editor.scrollTop + 'px'
}
static renderPopup(matches, popup, clientX, clientY) {
for (let m of matches) {
if (m.rects) {
@ -305,7 +317,7 @@ class BesEditor {
return false
}
setCorrectionPanelSize(editor, correctionPanel) {
setCorrectionPanelSize(editor, correctionPanel, scrollPanel) {
const styles = window.getComputedStyle(editor)
const totalWidth =
parseFloat(styles.width) +
@ -321,6 +333,7 @@ class BesEditor {
parseFloat(styles.paddingBottom)
correctionPanel.style.width = totalWidth + 'px'
correctionPanel.style.height = totalHeight + 'px'
scrollPanel.style.height = editor.scrollHeight + 'px'
}
static isPointInRect(x, y, rect) {
@ -342,14 +355,15 @@ window.onload = () => {
window.onresize = () => {
besEditors.forEach(editor => {
editor.setCorrectionPanelSize(editor.el, editor.correctionPanel)
editor.setCorrectionPanelSize(
editor.el,
editor.correctionPanel,
editor.scrollPanel
)
editor.children.forEach(child => {
editor.clearMistakeMarkup(child.elements)
child.matches.forEach(match => {
match.rects = editor.addMistakeMarkup(
match.range,
editor.correctionPanel
)
match.rects = editor.addMistakeMarkup(match.range, editor.scrollPanel)
})
})
})

View File

@ -9,3 +9,28 @@
text-decoration-color: red;
cursor: text; */
}
.bes-correction-panel-scroll {
pointer-events: none !important;
box-shadow: initial !important;
box-sizing: initial !important;
cursor: initial !important;
display: block !important;
float: initial !important;
max-height: initial !important;
min-height: initial !important;
max-width: initial !important;
min-width: initial !important;
position: absolute !important;
height: initial !important;
width: initial !important;
animation: auto ease 0s 1 normal none running none !important;
background: transparent !important;
border-width: initial !important;
border-style: none !important;
border-color: initial !important;
border-image: initial !important;
margin: 0px !important;
outline: initial !important;
padding: 0px !important;
}