Cleanups and improvements

This commit is contained in:
Simon Rozman 2024-02-19 16:14:03 +01:00
parent dc4418038d
commit 9522ace2ce

View File

@ -14,10 +14,10 @@ class BesEditor {
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)
edit.addEventListener('scroll', e =>
this.handleScrollEvent(edit, this.scrollPanel)
)
this.observeDeletions(this.el)
//this.observeDeletions(this.el)
}
// Register editor
@ -162,8 +162,18 @@ class BesEditor {
}
// Marks section of text that is about to change as not-yet-grammar-proofed.
handleBeforeInput() {
handleBeforeInput(event) {
if (this.timer) clearTimeout(this.timer)
let blockElements = new Set()
event.getTargetRanges().forEach(range => {
BesEditor.getNodesInRange(range).forEach(el =>
blockElements.add(this.getBlockParent(el))
)
})
blockElements.forEach(block => {
this.clearProofed(block)
this.clearMistakeMarkup(block)
})
let editor = this
this.timer = setTimeout(function () {
editor.proof(editor.el)
@ -230,31 +240,35 @@ class BesEditor {
// Mark given block element as not grammar-proofed.
clearProofed(el) {
let filteredChildren = this.children.filter(child => child.elements === el)
if (filteredChildren.length) filteredChildren[0].isProofed = false
this.children
.filter(child => child.elements === el)
.forEach(child => {
child.isProofed = false
})
}
// Remove all grammar mistakes markup for given block element.
clearMistakeMarkup(el) {
let filteredChildren = this.children.filter(child => child.elements === el)
if (!filteredChildren.length) return
// 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.scrollPanel.children) {
let childRect = child.getBoundingClientRect()
const isWithinRect =
childRect.left >= rect.left &&
childRect.right <= rect.right &&
childRect.top >= rect.top &&
childRect.bottom <= rect.bottom + 20
if (isWithinRect) {
child.remove()
this.children
.filter(child => child.elements === el)
.forEach(child => {
// TODO: Remove elements that are found in editor object, that way we can avoid looping through all elements.
child.matches.forEach(match => {
for (const rect of match.rects) {
for (let child of this.scrollPanel.children) {
let childRect = child.getBoundingClientRect()
const isWithinRect =
childRect.left >= rect.left &&
childRect.right <= rect.right &&
childRect.top >= rect.top &&
childRect.bottom <= rect.bottom + 20
if (isWithinRect) {
child.remove()
}
}
}
}
}
})
})
})
}
// Adds grammar mistake markup
@ -302,6 +316,59 @@ class BesEditor {
return el
}
static getNextNode(node) {
if (node.firstChild) return node.firstChild
while (node) {
if (node.nextSibling) return node.nextSibling
node = node.parentNode
}
}
static getParents(node) {
let parents = []
do {
parents.push(node)
node = node.parentNode
} while (node)
return parents.reverse()
}
static getNodesInRange(range) {
var start = range.startContainer
var end = range.endContainer
let startAncestors = BesEditor.getParents(start)
let endAncestors = BesEditor.getParents(end)
let commonAncestor = null
for (
let i = 0;
i < startAncestors.length &&
i < endAncestors.length &&
startAncestors[i] === endAncestors[i];
++i
) {
commonAncestor = startAncestors[i]
}
var nodes = []
var node
// walk parent nodes from start to common ancestor
for (node = start.parentNode; node; node = node.parentNode) {
nodes.push(node)
if (node == commonAncestor) break
}
nodes.reverse()
// walk children and siblings from start until end is found
for (node = start; node; node = BesEditor.getNextNode(node)) {
nodes.push(node)
if (node == end) break
}
return nodes
}
// TODO: Improve this function to support copied rich html content from news sites, etc.
handleClick(e) {
const targetEl = e.target