Proper handling of code bbcode
authorAlexander Ebert <ebert@woltlab.com>
Tue, 12 Jul 2016 10:16:23 +0000 (12:16 +0200)
committerAlexander Ebert <ebert@woltlab.com>
Tue, 12 Jul 2016 10:16:52 +0000 (12:16 +0200)
wcfsetup/install/files/lib/system/html/metacode/converter/CodeMetacodeConverter.class.php
wcfsetup/install/files/lib/util/DOMUtil.class.php

index 24fb747e3dea038959ce0d384e468951ba99d2d6..e0dd65f0f232d35eaad3db9da045edd749a18258 100644 (file)
@@ -1,5 +1,7 @@
 <?php
 namespace wcf\system\html\metacode\converter;
+use wcf\util\DOMUtil;
+use wcf\util\StringUtil;
 
 /**
  * Converts code bbcode into `<pre>`.
@@ -65,6 +67,41 @@ class CodeMetacodeConverter extends AbstractMetacodeConverter {
                
                $element->appendChild($fragment);
                
+               // convert code lines
+               $childNodes = DOMUtil::getChildNodes($element);
+               /** @var \DOMElement $node */
+               foreach ($childNodes as $node) {
+                       if ($node->nodeType === XML_ELEMENT_NODE && $node->nodeName === 'p') {
+                               DOMUtil::insertAfter($node->ownerDocument->createTextNode("\n\n"), $node);
+                               
+                               $brs = $node->getElementsByTagName('br');
+                               while ($brs->length) {
+                                       $br = $brs->item(0);
+                                       DOMUtil::insertBefore($br->ownerDocument->createTextNode("\n"), $br);
+                                       DOMUtil::removeNode($br);
+                               }
+                               
+                               DOMUtil::removeNode($node, true);
+                       }
+               }
+               
+               // clear any other elements contained within
+               $elements = $element->getElementsByTagName('*');
+               while ($elements->length) {
+                       /** @var \DOMElement $child */
+                       $child = $elements->item(0);
+                       if ($child->nodeName === 'a') {
+                               DOMUtil::insertBefore($child->ownerDocument->createTextNode($child->getAttribute('href')), $child);
+                               DOMUtil::removeNode($child);
+                               continue;
+                       }
+                       
+                       DOMUtil::removeNode($child, true);
+               }
+               
+               // trim code block
+               $element->textContent = StringUtil::trim($element->textContent);
+               
                return $element;
        }
        
index 36a94ae0fa3ffb49b4f95952d96c527153add98c..68ab736e7dd67709a7159b1c6b9dbb7d767438d5 100644 (file)
@@ -54,6 +54,21 @@ final class DOMUtil {
                return false;
        }
        
+       /**
+        * Returns a static list of child nodes of provided element.
+        * 
+        * @param       \DOMElement     $element        target element
+        * @return      \DOMNode[]      list of child nodes
+        */
+       public static function getChildNodes(\DOMElement $element) {
+               $nodes = [];
+               foreach ($element->childNodes as $node) {
+                       $nodes[] = $node;
+               }
+               
+               return $nodes;
+       }
+       
        /**
         * Returns the common ancestor of both nodes.
         *