diff --git a/service.js b/service.js index 573042d..aa83ddb 100644 --- a/service.js +++ b/service.js @@ -699,51 +699,55 @@ 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 - const viewElement = - this.ckEditorInstance.editing.mapper.toViewElement(parentElement) - 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) - } + 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(element) + const domElement = + this.ckEditorInstance.editing.view.domConverter.mapViewToDom(viewElement) + return domElement + } + /** * Registers grammar checking service * @@ -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) {