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