Convert floating images in CKEditor into `<figure>`
authorAlexander Ebert <ebert@woltlab.com>
Wed, 10 May 2023 13:43:18 +0000 (15:43 +0200)
committerAlexander Ebert <ebert@woltlab.com>
Wed, 10 May 2023 13:43:18 +0000 (15:43 +0200)
See WoltLab/editor#51

ts/WoltLabSuite/Core/Component/Ckeditor/Normalizer.ts
wcfsetup/install/files/js/WoltLabSuite/Core/Component/Ckeditor/Normalizer.js

index 9b6447c6460496f13f3829e2e9bb7b0f3ba342fa..7b576552a42445c4184593fd4c66e06fcbc846d7 100644 (file)
@@ -123,6 +123,27 @@ function reduceSpacerParagraphs(paragraphs: HTMLParagraphElement[]): void {
   }
 }
 
+function convertFloatingImages(div: HTMLElement): void {
+  div.querySelectorAll("img").forEach((img) => {
+    if (img.classList.contains("messageFloatObjectRight")) {
+      const paragraph = img.closest("p");
+      if (paragraph === null) {
+        return;
+      }
+
+      const figure = document.createElement("figure");
+      figure.classList.add("image", "image-style-side");
+      figure.append(img);
+
+      paragraph.insertAdjacentElement("beforebegin", figure);
+
+      if (paragraph.innerHTML === "") {
+        paragraph.remove();
+      }
+    }
+  });
+}
+
 export function normalizeLegacyMessage(element: HTMLElement): void {
   if (!(element instanceof HTMLTextAreaElement)) {
     throw new TypeError("Expected the element to be a <textarea>.");
@@ -134,6 +155,7 @@ export function normalizeLegacyMessage(element: HTMLElement): void {
   normalizeBr(div);
   const paragraphs = getPossibleSpacerParagraphs(div);
   reduceSpacerParagraphs(paragraphs);
+  convertFloatingImages(div);
 
   element.value = div.innerHTML;
 }
index 46f0f41c68b1ae5eae90cdaaa5e1d8f956b3a505..1278f76178357c7d4fd239f02e07a39a4df21764 100644 (file)
@@ -107,6 +107,23 @@ define(["require", "exports", "tslib", "../../Dom/Util"], function (require, exp
             }
         }
     }
+    function convertFloatingImages(div) {
+        div.querySelectorAll("img").forEach((img) => {
+            if (img.classList.contains("messageFloatObjectRight")) {
+                const paragraph = img.closest("p");
+                if (paragraph === null) {
+                    return;
+                }
+                const figure = document.createElement("figure");
+                figure.classList.add("image", "image-style-side");
+                figure.append(img);
+                paragraph.insertAdjacentElement("beforebegin", figure);
+                if (paragraph.innerHTML === "") {
+                    paragraph.remove();
+                }
+            }
+        });
+    }
     function normalizeLegacyMessage(element) {
         if (!(element instanceof HTMLTextAreaElement)) {
             throw new TypeError("Expected the element to be a <textarea>.");
@@ -116,6 +133,7 @@ define(["require", "exports", "tslib", "../../Dom/Util"], function (require, exp
         normalizeBr(div);
         const paragraphs = getPossibleSpacerParagraphs(div);
         reduceSpacerParagraphs(paragraphs);
+        convertFloatingImages(div);
         element.value = div.innerHTML;
     }
     exports.normalizeLegacyMessage = normalizeLegacyMessage;