From b1778aa658bc87c4e91de2b29aed53e2a15b832c Mon Sep 17 00:00:00 2001 From: Simon Rozman Date: Tue, 6 Feb 2024 14:55:45 +0100 Subject: [PATCH] Fix editor referencing Pass editor data as a function argument rather than perform voodoo to get it. --- online-editor.js | 58 +++++++++++++++++++----------------------------- 1 file changed, 23 insertions(+), 35 deletions(-) diff --git a/online-editor.js b/online-editor.js index 28f5239..05c0abd 100644 --- a/online-editor.js +++ b/online-editor.js @@ -6,17 +6,18 @@ window.onload = () => { // Search and prepare all our editors found in the document. document.querySelectorAll('.bes-online-editor').forEach(edit => { let editor = { + el: edit, timer: null, children: [] } besEditors[edit.id] = editor - besProof(edit) + besProof(editor, edit) edit.addEventListener( 'beforeinput', - e => besHandleBeforeInput(edit.id, e), + e => besHandleBeforeInput(editor, e), false ) - edit.addEventListener('click', e => besHandleClick(e, edit)) + //edit.addEventListener('click', e => besHandleClick(editor, e)) }) } @@ -24,7 +25,7 @@ window.onresize = () => { Object.keys(besEditors).forEach(key => { let editor = besEditors[key] editor.children.forEach(child => { - besClearAllMistakes(child?.elements) + besClearAllMistakes(editor, child?.elements) child.matches.forEach(match => { const clientRect = besAddMistake(match.range, match.message) match.rects = clientRect @@ -34,7 +35,7 @@ window.onresize = () => { } // Recursively grammar-proofs one node. -async function besProof(el) { +async function besProof(editor, el) { switch (el.nodeType) { case Node.TEXT_NODE: return [{ text: el.textContent, el: el, markup: false }] @@ -42,13 +43,13 @@ async function besProof(el) { case Node.ELEMENT_NODE: if (besIsBlockElement(el)) { // Block elements are grammar-proofed independently. - if (besIsProofed(el)) { + if (besIsProofed(editor, el)) { return [{ text: '<' + el.tagName + '/>', el: el, markup: true }] } - besClearAllMistakes(el) + besClearAllMistakes(editor, el) let data = [] for (const el2 of el.childNodes) { - data = data.concat(await besProof(el2)) + data = data.concat(await besProof(editor, el2)) } if (data.some(x => !x.markup && !/^\s*$/.test(x.text))) { const requestData = { @@ -120,7 +121,7 @@ async function besProof(el) { }) }) - besMarkProofed(el, matches) + besMarkProofed(editor, el, matches) }) .catch(error => { // TODO: Make parsing issues non-fatal. But show an error sign somewhere in the UI. @@ -134,7 +135,7 @@ async function besProof(el) { // Surround inline element with dummy .... let data = [{ text: '<' + el.tagName + '>', el: el, markup: true }] for (const el2 of el.childNodes) { - data = data.concat(await besProof(el2)) + data = data.concat(await besProof(editor, el2)) } data.splice(data.length, 0, { text: '', @@ -149,12 +150,10 @@ async function besProof(el) { } // Marks section of text that is about to change as not-yet-grammar-proofed. -function besHandleBeforeInput(editorId, event) { - let editor = besEditors[editorId] +function besHandleBeforeInput(editor, event) { if (editor.timer) clearTimeout(editor.timer) - let edit = document.getElementById(editorId) editor.timer = setTimeout(function () { - besProof(edit) + besProof(editor, editor.el) }, 1000) // No need to invalidate elements after range.startContainer since they will @@ -162,23 +161,18 @@ function besHandleBeforeInput(editorId, event) { event .getTargetRanges() .forEach(range => - besClearProofed(besGetBlockParent(range.startContainer, edit)) + besClearProofed(editor, besGetBlockParent(editor, range.startContainer)) ) } // Test if given block element has already been grammar-proofed. -function besIsProofed(el) { - if (el.id.startsWith('ed')) return - const editorId = el.parentElement.id - const editor = besEditors[editorId] +function besIsProofed(editor, el) { let filteredChildren = editor?.children.filter(child => child.elements === el) return filteredChildren[0]?.isProofed } // Mark given block element as grammar-proofed. -function besMarkProofed(el, matches) { - const editorId = el.parentElement.id - const editor = besEditors[editorId] +function besMarkProofed(editor, el, matches) { let newChild = { isProofed: true, elements: el, @@ -194,18 +188,13 @@ function besMarkProofed(el, matches) { } // Mark given block element as not grammar-proofed. -function besClearProofed(el) { - const editorId = el.parentElement.id - const editor = besEditors[editorId] +function besClearProofed(editor, el) { let filteredChildren = editor.children.filter(child => child.elements === el) if (filteredChildren.length) filteredChildren[0].isProofed = false } // Remove all grammar mistakes markup for given block element. -function besClearAllMistakes(el) { - if (el?.id.startsWith('ed')) return - const editorId = el.parentElement.id - const editor = besEditors[editorId] +function besClearAllMistakes(editor, el) { let filteredChildren = editor?.children.filter(child => child.elements === el) if (!filteredChildren.length) return @@ -263,22 +252,21 @@ function besIsBlockElement(el) { } // Returns first block parent element -function besGetBlockParent(el, edit) { - for (; el && el !== edit; el = el.parentNode) { +function besGetBlockParent(editor, el) { + for (; el && el !== editor.el; el = el.parentNode) { if (el.nodeType === Node.ELEMENT_NODE && besIsBlockElement(el)) return el } return el } -function besHandleClick(e, editor) { +function besHandleClick(editor, e) { const targetEl = e.target const popup = document.querySelector('bes-popup-el') if (targetEl.tagName === 'DIV') { - const editorData = besEditors[editor.id] - const divIndex = editorData.children.findIndex( + const divIndex = editor.children.findIndex( child => child.elements === targetEl ) - const matches = editorData.children[divIndex]?.matches + const matches = editor.children[divIndex]?.matches if (!matches) { popup.hide() return