From 126538b703bcb78d79f1af810481125c65b62e3d Mon Sep 17 00:00:00 2001
From: Jan-Hendrik Willms <tleilax+studip@gmail.com>
Date: Fri, 16 Feb 2024 13:48:46 +0000
Subject: [PATCH] use dataset for id storage not element attributes and
 optimize textarea replacement, fixes #3698

Closes #3698

Merge request studip/studip!2567
---
 .../assets/javascripts/bootstrap/wysiwyg.js   |  7 ++--
 resources/assets/javascripts/lib/wysiwyg.js   | 32 ++++---------------
 2 files changed, 12 insertions(+), 27 deletions(-)

diff --git a/resources/assets/javascripts/bootstrap/wysiwyg.js b/resources/assets/javascripts/bootstrap/wysiwyg.js
index 92479d2be88..fb158bb641c 100644
--- a/resources/assets/javascripts/bootstrap/wysiwyg.js
+++ b/resources/assets/javascripts/bootstrap/wysiwyg.js
@@ -20,7 +20,10 @@ STUDIP.domReady(() => {
     // hidden, the editor does not function properly; therefore attach to
     // visible textareas only
     function replaceVisibleTextareas() {
-        const textareas = document.querySelectorAll('textarea.wysiwyg');
-        textareas.forEach(STUDIP.wysiwyg.replace);
+        const textareas = document.querySelectorAll('textarea.wysiwyg:not(.has-editor)');
+        textareas.forEach(node => {
+            STUDIP.wysiwyg.replace(node);
+            node.classList.add('has-editor');
+        });
     }
 });
diff --git a/resources/assets/javascripts/lib/wysiwyg.js b/resources/assets/javascripts/lib/wysiwyg.js
index 806abaf16ca..f9acb81e01e 100644
--- a/resources/assets/javascripts/lib/wysiwyg.js
+++ b/resources/assets/javascripts/lib/wysiwyg.js
@@ -59,44 +59,26 @@ async function replaceTextarea(textarea) {
     return editor;
 }
 
-function destroyTextarea(textarea) {
-    if (!hasEditor(textarea)) {
-        throw new Error('Trying to destroy a non-existing editor instance.');
-    }
-
-    const editor = getEditor(textarea);
-    editor.destroy(true);
-    unsetEditor(textarea);
-}
-
-// create an unused id
-function createNewId(prefix) {
-    var i = 0;
-    while ($('#' + prefix + i).length > 0) {
-        i++;
-    }
-    return prefix + i;
-}
-
 const instances = new Map();
+let internalIdCounter = 0;
 
 function getEditor(textarea) {
-    return textarea?.id !== '' ? instances.get(textarea.id) : null;
+    return textarea.dataset.editorId !== undefined ? instances.get(textarea.dataset.editorId) : null;
 }
 
 function hasEditor(textarea) {
-    return textarea.id !== '' && instances.has(textarea.id);
+    return textarea.dataset.editorId !== undefined && instances.has(textarea.dataset.editorId);
 }
 
 function setEditor(textarea, editor) {
-    if (textarea.id === '') {
-        textarea.id = createNewId('wysiwyg');
+    if (textarea.dataset.editorId === undefined) {
+        textarea.dataset.editorId = String(internalIdCounter++);
     }
-    instances.set(textarea.id, editor);
+    instances.set(textarea.dataset.editorId, editor);
 }
 
 function unsetEditor(textarea) {
-    instances.delete(textarea.id);
+    instances.delete(textarea.dataset.editorId);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-- 
GitLab