Insert newlines and whitespace after certain block elements
authorAlexander Ebert <ebert@woltlab.com>
Wed, 9 Aug 2023 16:26:10 +0000 (18:26 +0200)
committerAlexander Ebert <ebert@woltlab.com>
Wed, 9 Aug 2023 16:26:10 +0000 (18:26 +0200)
See https://www.woltlab.com/community/thread/301031-w%C3%B6rter-werden-falsch-gez%C3%A4hlt/

wcfsetup/install/files/lib/system/html/input/node/HtmlInputNodeProcessor.class.php

index d1ec405ce86cee120cb20b6504733368c1e76162..75c73b13405fb65f7963f8691e3bcd850538b0e8 100644 (file)
@@ -8,6 +8,7 @@ use wcf\system\html\node\AbstractHtmlNodeProcessor;
 use wcf\system\html\node\HtmlNodePlainLink;
 use wcf\system\html\node\HtmlNodeUnfurlLink;
 use wcf\system\html\node\IHtmlNode;
+use wcf\system\html\output\node\HtmlOutputNodeProcessor;
 use wcf\system\worker\AbstractWorker;
 use wcf\util\DOMUtil;
 use wcf\util\StringUtil;
@@ -631,9 +632,22 @@ class HtmlInputNodeProcessor extends AbstractHtmlNodeProcessor
     {
         // cloning the body allows custom event handlers to alter the contents
         // without making permanent changes to the document, avoids side-effects
-        $body = $this->getDocument()->getElementsByTagName('body')->item(0)->cloneNode(true);
+        $document = clone $this->getDocument();
 
-        $parameters = ['body' => $body];
+        // insert a trailing whitespace plus newline for certain elements, such as `<br>` or `<li>`
+        $tagNames = HtmlOutputNodeProcessor::$plainTextNewlineTags;
+        $tagNames[] = 'p';
+
+        $xpath = new \DOMXPath($document);
+        foreach ($tagNames as $tagName) {
+            foreach ($xpath->query("//{$tagName}") as $element) {
+                $newline = $document->createTextNode(" \n");
+                $element->parentNode->insertBefore($newline, $element->nextSibling);
+                DOMUtil::removeNode($element, true);
+            }
+        }
+
+        $parameters = ['body' => $document->getElementsByTagName('body')->item(0)];
         EventHandler::getInstance()->fireAction($this, 'getTextContent', $parameters);
 
         return StringUtil::trim($parameters['body']->textContent);