From ff104a62058c47b6f6784cd0c41c9be0f93089fb Mon Sep 17 00:00:00 2001 From: Alexander Ebert Date: Thu, 1 Sep 2016 17:56:45 +0200 Subject: [PATCH] Cleanup DOM before saving --- .../node/HtmlInputNodeProcessor.class.php | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/wcfsetup/install/files/lib/system/html/input/node/HtmlInputNodeProcessor.class.php b/wcfsetup/install/files/lib/system/html/input/node/HtmlInputNodeProcessor.class.php index 2875f3a259..e129c53650 100644 --- a/wcfsetup/install/files/lib/system/html/input/node/HtmlInputNodeProcessor.class.php +++ b/wcfsetup/install/files/lib/system/html/input/node/HtmlInputNodeProcessor.class.php @@ -4,6 +4,7 @@ use wcf\system\bbcode\BBCodeHandler; use wcf\system\event\EventHandler; use wcf\system\html\node\AbstractHtmlNodeProcessor; use wcf\system\html\node\IHtmlNode; +use wcf\util\DOMUtil; use wcf\util\StringUtil; /** @@ -57,6 +58,8 @@ class HtmlInputNodeProcessor extends AbstractHtmlNodeProcessor { $this->processEmbeddedContent(); EventHandler::getInstance()->fireAction($this, 'afterProcess'); + + $this->cleanup(); } /** @@ -242,6 +245,48 @@ class HtmlInputNodeProcessor extends AbstractHtmlNodeProcessor { EventHandler::getInstance()->fireAction($this, 'parseEmbeddedContent'); } + /** + * Removes garbage left in the DOM. + */ + protected function cleanup() { + // remove empty

tags + $elements = []; + foreach ($this->getDocument()->getElementsByTagName('p') as $element) { + $elements[] = $element; + } + + /** @var \DOMElement $element */ + foreach ($elements as $element) { + if ($element->hasChildNodes()) { + if ($element->childNodes->length === 1) { + $textContent = StringUtil::trim($element->childNodes[0]->textContent); + if (empty($textContent)) { + DOMUtil::removeNode($element); + } + } + } + else { + DOMUtil::removeNode($element); + } + } + + // remove
at the end of block elements + // without a succeeding non-empty paragraph + $elements = []; + foreach ($this->getDocument()->getElementsByTagName('br') as $element) { + $elements[] = $element; + } + + $blocks = ['h1', 'h2', 'h3', 'p']; + foreach ($elements as $element) { + if (in_array($element->parentNode->nodeName, $blocks)) { + if ($element->previousSibling && !$element->nextSibling) { + DOMUtil::removeNode($element); + } + } + } + } + /** * Creates a new `` element contained in the same document * as the provided `$node`. -- 2.20.1