Refactor CKEditor event handling
This commit is contained in:
parent
970b43b8d6
commit
c54366e95f
129
service.js
129
service.js
@ -699,49 +699,53 @@ class BesCKService extends BesService {
|
||||
super(hostElement)
|
||||
this.ckEditorInstance = ckEditorInstance
|
||||
this.disableCKEditorSpellcheck(this.ckEditorInstance)
|
||||
hostElement.addEventListener(
|
||||
'beforeinput',
|
||||
e => this.handleBeforeCKInput(e),
|
||||
false
|
||||
)
|
||||
this.ckEditorInstance.model.document.on('change:data', () => {
|
||||
const differ = this.ckEditorInstance.model.document.differ
|
||||
const changes = Array.from(differ.getChanges())
|
||||
for (const entry of changes) {
|
||||
if (entry.type === 'attribute') {
|
||||
const parentElement = entry.range.start.parent
|
||||
let element =
|
||||
entry.type === 'attribute'
|
||||
? entry.range.start.parent
|
||||
: entry._element || entry.position.parent
|
||||
const domElement = this.getDomElement(element)
|
||||
const child = this.children.find(child => child.element === domElement)
|
||||
this.clearMistakeMarkup(domElement)
|
||||
if (entry.type === 'attribute') child.isProofed = false
|
||||
else if (entry.type === 'remove') this.removeChildFromChildren(child)
|
||||
let service = besServices.find(e => e.hostElement === hostElement)
|
||||
if (!service) return
|
||||
service.clearMistakeMarkup(domElement)
|
||||
service.removeChild(domElement)
|
||||
if (service.timer) clearTimeout(service.timer)
|
||||
service.abortController.abort()
|
||||
service.timer = setTimeout(function () {
|
||||
service.abortController = new AbortController()
|
||||
service.proof(hostElement)
|
||||
window.dispatchEvent(new Event('resize'))
|
||||
}, 1000)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
removeChildFromChildren(child) {
|
||||
let index = this.children.indexOf(child)
|
||||
if (index !== -1) {
|
||||
this.children.splice(index, 1)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function converts a CKEditor element to a DOM element.
|
||||
*
|
||||
* @param {CKEditor} element
|
||||
* @returns domElement
|
||||
*/
|
||||
getDomElement(element) {
|
||||
const viewElement =
|
||||
this.ckEditorInstance.editing.mapper.toViewElement(parentElement)
|
||||
this.ckEditorInstance.editing.mapper.toViewElement(element)
|
||||
const domElement =
|
||||
this.ckEditorInstance.editing.view.domConverter.mapViewToDom(
|
||||
viewElement
|
||||
)
|
||||
const child = this.children.find(
|
||||
child => child.element === domElement
|
||||
)
|
||||
if (child) {
|
||||
child.matches.forEach(match => {
|
||||
console.log(match)
|
||||
match.highlights.forEach(highlight => {
|
||||
highlight.remove()
|
||||
delete match.highlights
|
||||
})
|
||||
})
|
||||
delete child.matches
|
||||
child.isProofed = false
|
||||
}
|
||||
setTimeout(() => {
|
||||
this.proof(domElement)
|
||||
window.dispatchEvent(new Event('resize'))
|
||||
}, 500)
|
||||
} else {
|
||||
setTimeout(() => {
|
||||
this.proof(hostElement)
|
||||
window.dispatchEvent(new Event('resize'))
|
||||
}, 500)
|
||||
}
|
||||
}
|
||||
})
|
||||
this.ckEditorInstance.editing.view.domConverter.mapViewToDom(viewElement)
|
||||
return domElement
|
||||
}
|
||||
|
||||
/**
|
||||
@ -757,55 +761,6 @@ class BesCKService extends BesService {
|
||||
return service
|
||||
}
|
||||
|
||||
handleBeforeCKInput(event) {
|
||||
const hostElement = event.target
|
||||
let service = besServices.find(e => e.hostElement === hostElement)
|
||||
if (!service) return
|
||||
if (service.timer) clearTimeout(service.timer)
|
||||
service.abortController.abort()
|
||||
let blockElements = new Set()
|
||||
event.getTargetRanges().forEach(range => {
|
||||
BesService.getNodesInRange(range).forEach(el => {
|
||||
if (el === hostElement || hostElement?.contains(el)) {
|
||||
blockElements.add(service.getBlockParent(el))
|
||||
}
|
||||
})
|
||||
})
|
||||
blockElements.forEach(block => {
|
||||
service.clearMistakeMarkup(block)
|
||||
service.removeChild(block)
|
||||
})
|
||||
// Not a nice way to do it, but it works for now the repositionMistakes function is called before the DOM updates are finished.
|
||||
// If users will experience performance issues, we can consider debouncing this function.
|
||||
// The lagginess becomes noticeable if the text is long and has many grammar mistakes.
|
||||
setTimeout(() => {
|
||||
service.repositionMistakes()
|
||||
window.dispatchEvent(new Event('resize'))
|
||||
}, 100)
|
||||
service.timer = setTimeout(function () {
|
||||
service.abortController = new AbortController()
|
||||
service.proof(hostElement)
|
||||
}, 1000)
|
||||
}
|
||||
|
||||
clearAllMistakes(el) {
|
||||
while (el.firstChild) {
|
||||
el.removeChild(el.firstChild)
|
||||
}
|
||||
}
|
||||
|
||||
clearChildren() {
|
||||
this.children = []
|
||||
}
|
||||
|
||||
proofCKEditor() {
|
||||
this.clearAllMistakes(this.scrollPanel)
|
||||
this.clearChildren()
|
||||
setTimeout(() => {
|
||||
this.proof(this.hostElement)
|
||||
}, 500)
|
||||
}
|
||||
|
||||
/**
|
||||
* This function disables the CKEditor spellcheck.
|
||||
*
|
||||
@ -882,7 +837,7 @@ class BesCKService extends BesService {
|
||||
// It maintains reasonable performance as it only checks the block element that has been modified,
|
||||
// rather than re-evaluating the entire document or a larger set of elements.
|
||||
this.abortController = new AbortController()
|
||||
this.proofCKEditor()
|
||||
this.proof(this.hostElement)
|
||||
}
|
||||
|
||||
setStatusDivPosition(hostElement, statusDiv) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user