Change upcast, that the function replace the elements and not get a fragment
authorCyperghost <olaf_schmitz_1@t-online.de>
Mon, 5 Feb 2024 12:53:44 +0000 (13:53 +0100)
committerCyperghost <olaf_schmitz_1@t-online.de>
Mon, 5 Feb 2024 12:53:44 +0000 (13:53 +0100)
wcfsetup/install/files/lib/system/html/metacode/upcast/AttachMetacodeUpcast.class.php
wcfsetup/install/files/lib/system/html/metacode/upcast/IMetacodeUpcast.class.php
wcfsetup/install/files/lib/system/html/metacode/upcast/WsmMetacodeUpcast.class.php
wcfsetup/install/files/lib/system/html/upcast/node/HtmlUpcastNodeWoltlabMetacode.class.php

index c6e45387c6b40a48d4a49c623f3632fcd48088a0..3354056404df7cf86ca152d8c34321ec2f112ba5 100644 (file)
@@ -4,6 +4,7 @@ namespace wcf\system\html\metacode\upcast;
 
 use wcf\data\attachment\Attachment;
 use wcf\system\cache\runtime\AttachmentRuntimeCache;
+use wcf\util\DOMUtil;
 use wcf\util\StringUtil;
 
 /**
@@ -15,7 +16,7 @@ use wcf\util\StringUtil;
 final class AttachMetacodeUpcast implements IMetacodeUpcast
 {
     #[\Override]
-    public function upcast(\DOMDocumentFragment $fragment, array $attributes): ?\DOMElement
+    public function upcast(\DOMElement $element, array $attributes): void
     {
         /**
          * @var string $alignment
@@ -25,45 +26,48 @@ final class AttachMetacodeUpcast implements IMetacodeUpcast
         $alignment = $attributes[1] ?? 'none';
         $width = $attributes[2] ?? 'auto';
         $attachment = AttachmentRuntimeCache::getInstance()->getObject($attachmentID);
+        $parentLink = $element->parentNode;
+        /** @var \DOMElement|null $parentLink */
+        if ($parentLink !== null && $parentLink->nodeName !== 'a') {
+            $parentLink = null;
+        }
 
-        $element = $fragment->ownerDocument->createElement('img');
+        $imgElement = $element->ownerDocument->createElement('img');
         if ($this->isThumbnailWidth($attachment, $width)) {
-            $element->setAttribute('src', StringUtil::decodeHTML($attachment->getThumbnailLink('thumbnail')));
+            $imgElement->setAttribute('src', StringUtil::decodeHTML($attachment->getThumbnailLink('thumbnail')));
         } else {
-            $element->setAttribute('src', StringUtil::decodeHTML($attachment->getLink()));
+            $imgElement->setAttribute('src', StringUtil::decodeHTML($attachment->getLink()));
         }
 
         if (\is_numeric($width) && $width > 0) {
-            $element->setAttribute('width', \intval($width));
-            $element->setAttribute('data-width', \intval($width) . 'px');
+            $imgElement->setAttribute('width', \intval($width));
+            $imgElement->setAttribute('data-width', \intval($width) . 'px');
         }
-        $element->setAttribute('data-attachment-id', $attachmentID);
+        $imgElement->setAttribute('data-attachment-id', $attachmentID);
+        $imgElement->setAttribute('class', 'image woltlabAttachment');
+        $imgElement->setAttribute('style', $this->getStyle($attachment, $width));
         if ($alignment === 'none') {
-            $element->setAttribute('class', 'image woltlabAttachment');
-            $element->setAttribute(
-                'style',
-                $this->getStyle($attachment, $width)
-            );
-            return $element;
+            return;
         }
-        $element->setAttribute('class', 'woltlabAttachment');
 
-        $figure = $fragment->ownerDocument->createElement('figure');
+        $figure = $element->ownerDocument->createElement('figure');
+        $figure->setAttribute('class', 'image');
         if ($alignment === 'left') {
-            $figure->setAttribute('class', 'image image-style-side-left');
+            $imgElement->setAttribute('class', $imgElement->getAttribute('style') . ' image-style-side-left');
         } elseif ($alignment === 'right') {
-            $figure->setAttribute('class', 'image image-style-side');
+            $imgElement->setAttribute('class', $imgElement->getAttribute('style') . ' image-style-side');
+        }
+        if ($parentLink !== null) {
+            DOMUtil::replaceElement($parentLink, $figure, false);
+            $figure->appendChild($parentLink);
+            foreach (DomUtil::getChildNodes($parentLink) as $child) {
+                $parentLink->removeChild($child);
+            }
+            $parentLink->appendChild($imgElement);
         } else {
-            $figure->setAttribute('class', 'image');
+            $figure->appendChild($imgElement);
+            DOMUtil::replaceElement($imgElement, $figure, false);
         }
-
-        $figure->setAttribute(
-            'style',
-            $this->getStyle($attachment, $width)
-        );
-
-        $figure->appendChild($element);
-        return $figure;
     }
 
     private function isThumbnailWidth(Attachment $attachment, string|bool|int $width): bool
index 604ce94b0b71c61c74e814b44b2c0bbd9143a41a..d48ba5d0f4f9479dfeb9795e4640b6b293eb5f21 100644 (file)
@@ -15,13 +15,10 @@ interface IMetacodeUpcast
     /**
      * Converts a known metacode into the HTML representation for use by CKEditor5.
      *
-     * The fragment must be inserted into your returned DOM element.
-     *
-     * @param \DOMDocumentFragment $fragment fragment containing all child nodes, must be appended to returned element
+     * @param \DOMElement $element
      * @param array $attributes list of attributes
-     * @return  null|\DOMElement     new DOM element
      */
-    public function upcast(\DOMDocumentFragment $fragment, array $attributes): ?\DOMElement;
+    public function upcast(\DOMElement $element, array $attributes): void;
 
     /**
      * Returns true if the given attributes are valid for this upcast.
index cf427a28b4d7f729e620f58297861bcb0818ea74..d027b8e53f0654891f7a72ad32d868020d8e8865 100644 (file)
@@ -4,6 +4,7 @@ namespace wcf\system\html\metacode\upcast;
 
 use wcf\data\media\Media;
 use wcf\system\cache\runtime\MediaRuntimeCache;
+use wcf\util\DOMUtil;
 use wcf\util\StringUtil;
 
 /**
@@ -15,7 +16,7 @@ use wcf\util\StringUtil;
 final class WsmMetacodeUpcast implements IMetacodeUpcast
 {
     #[\Override]
-    public function upcast(\DOMDocumentFragment $fragment, array $attributes): ?\DOMElement
+    public function upcast(\DOMElement $element, array $attributes): void
     {
         /**
          * @var string $alignment
@@ -27,27 +28,33 @@ final class WsmMetacodeUpcast implements IMetacodeUpcast
         $alignment = $attributes[2] ?? 'none';
         $width = $attributes[3] ?? 'auto';
         $media = MediaRuntimeCache::getInstance()->getObject($mediaID);
+        $parentLink = $element->parentNode;
+        /** @var \DOMElement|null $parentLink */
+        if ($parentLink !== null && $parentLink->nodeName !== 'a') {
+            $parentLink = null;
+        }
 
-        $element = $fragment->ownerDocument->createElement('img');
+        $imgElement = $element->ownerDocument->createElement('img');
         if ($thumbnail === 'original') {
-            $element->setAttribute('src', StringUtil::decodeHTML($media->getLink()));
+            $imgElement->setAttribute('src', StringUtil::decodeHTML($media->getLink()));
         } else {
-            $element->setAttribute('src', StringUtil::decodeHTML($media->getThumbnailLink($thumbnail)));
+            $imgElement->setAttribute('src', StringUtil::decodeHTML($media->getThumbnailLink($thumbnail)));
         }
         if ($width !== 'auto') {
-            $element->setAttribute('width', \intval($width));
-            $element->setAttribute('data-width', \intval($width) . 'px');
+            $imgElement->setAttribute('width', \intval($width));
+            $imgElement->setAttribute('data-width', \intval($width) . 'px');
         }
-        $element->setAttribute('data-media-id', $mediaID);
-        $element->setAttribute('data-media-size', StringUtil::decodeHTML($thumbnail));
+        $imgElement->setAttribute('data-media-id', $mediaID);
+        $imgElement->setAttribute('data-media-size', StringUtil::decodeHTML($thumbnail));
+        $imgElement->setAttribute('style', $this->getStyle($media, $width, $thumbnail));
         if ($alignment === 'none') {
-            $element->setAttribute('class', 'image woltlabSuiteMedia');
-            $element->setAttribute('style', $this->getStyle($media, $width, $thumbnail));
-            return $element;
+            $imgElement->setAttribute('class', 'image woltlabSuiteMedia');
+            DOMUtil::replaceElement($element, $imgElement);
+            return;
         }
-        $element->setAttribute('class', 'woltlabSuiteMedia');
+        $imgElement->setAttribute('class', 'woltlabSuiteMedia');
 
-        $figure = $fragment->ownerDocument->createElement('figure');
+        $figure = $element->ownerDocument->createElement('figure');
         if ($alignment === 'left') {
             $figure->setAttribute('class', 'image image-style-side-left');
         } elseif ($alignment === 'right') {
@@ -55,9 +62,17 @@ final class WsmMetacodeUpcast implements IMetacodeUpcast
         } else {
             $figure->setAttribute('class', 'image');
         }
-        $figure->setAttribute('style', $this->getStyle($media, $width, $thumbnail));
-        $figure->appendChild($element);
-        return $figure;
+        if ($parentLink !== null) {
+            DOMUtil::replaceElement($parentLink, $figure, false);
+            $figure->appendChild($parentLink);
+            foreach (DomUtil::getChildNodes($parentLink) as $child) {
+                $parentLink->removeChild($child);
+            }
+            $parentLink->appendChild($imgElement);
+        } else {
+            $figure->appendChild($imgElement);
+            DOMUtil::replaceElement($element, $figure, false);
+        }
     }
 
     #[\Override]
index 2329f8f5194018c8aa99dc9d1cd60d36297a44a4..62e1d1a2358fdfb9881983583e256d057216cbdb 100644 (file)
@@ -65,18 +65,7 @@ final class HtmlUpcastNodeWoltlabMetacode extends AbstractHtmlUpcastNode
 
         foreach ($nodes as [$element, $name, $upcast, $attributes]) {
             if ($upcast->hasValidAttributes($attributes)) {
-                $fragment = DOMUtil::childNodesToFragment($element);
-                if (!$fragment->hasChildNodes()) {
-                    $fragment->appendChild($fragment->ownerDocument->createTextNode(''));
-                }
-
-                $newElement = $upcast->upcast($fragment, $attributes);
-                if (!($newElement instanceof \DOMElement)) {
-                    throw new \UnexpectedValueException("Expected a valid DOMElement as return value.");
-                }
-
-                DOMUtil::replaceElement($element, $newElement);
-                unset($fragment);
+                $upcast->upcast($element, $attributes);
             } else {
                 // Replace this with a text node
                 $bbcode = BBCodeCache::getInstance()->getBBCodeByTag($name);