Added proper support for bbcodes during output
authorAlexander Ebert <ebert@woltlab.com>
Sun, 15 May 2016 08:28:20 +0000 (10:28 +0200)
committerAlexander Ebert <ebert@woltlab.com>
Sun, 15 May 2016 08:28:26 +0000 (10:28 +0200)
wcfsetup/install/files/lib/system/bbcode/HtmlBBCodeParser.class.php
wcfsetup/install/files/lib/system/html/input/node/HtmlInputNodeWoltlabMetacode.class.php
wcfsetup/install/files/lib/system/html/input/node/HtmlInputNodeWoltlabMetacodeMarker.class.php
wcfsetup/install/files/lib/system/html/node/HtmlNodeProcessor.class.php
wcfsetup/install/files/lib/system/html/output/node/HtmlOutputNodeProcessor.class.php
wcfsetup/install/files/lib/system/html/output/node/HtmlOutputNodeWoltlabMetacode.class.php [new file with mode: 0644]

index f164b313946075983dc51970b76e78ad93336b9c..73048ecbd5780e644056a60c332ad43d4e354cfa 100644 (file)
@@ -140,6 +140,55 @@ class HtmlBBCodeParser extends BBCodeParser {
                if (isset($this->textArray[$i + 1])) $this->parsedText .= $this->textArray[$i + 1];
        }
        
+       /**
+        * Builds the bbcode output.
+        * 
+        * @param       string          $name           bbcode identifier
+        * @param       array           $attributes     list of attributes
+        * @return      string          parsed bbcode
+        */
+       public function getHtmlOutput($name, array $attributes) {
+               if (isset($this->bbcodes[$name])) {
+                       $openingTag = ['attributes' => $attributes, 'name' => $name];
+                       $closingTag = ['name' => $name];
+                       
+                       if ($this->bbcodes[$name]->getProcessor()) {
+                               /** @var IBBCode $processor */
+                               $processor = $this->bbcodes[$name]->getProcessor();
+                               return $processor->getParsedTag($openingTag, '<!-- META_CODE_INNER_CONTENT -->', $closingTag, $this);
+                       }
+                       else {
+                               return parent::buildOpeningTag($openingTag) . '<!-- META_CODE_INNER_CONTENT -->' . parent::buildClosingTag($closingTag);
+                       }
+               }
+               
+               // unknown bbcode, output plain tags
+               return $this->buildBBCodeTag($name, $attributes);
+       }
+       
+       /**
+        * Builds a plain bbcode string, used for unknown bbcodes.
+        * 
+        * @param       string          $name           bbcode identifier
+        * @param       array           $attributes     list of attributes
+        * @return      string
+        */
+       protected function buildBBCodeTag($name, $attributes) {
+               if (!empty($attributes)) {
+                       foreach ($attributes as &$attribute) {
+                               $attribute = "'" . addcslashes($attribute, "'") . "'";
+                       }
+                       unset($attribute);
+                       
+                       $attributes = '=' . implode(",", $attributes);
+               }
+               else {
+                       $attributes = '';
+               }
+               
+               return '[' . $name . $attributes . ']<!-- META_CODE_INNER_CONTENT -->[/' . $name . ']';
+       }
+       
        /**
         * Compiles tag fragments into the custom HTML element.
         * 
index bdc000f0b6049f31f276e3bd24bc2a9f5fb98892..7d699d04381b660bc7b8f89f233422858083e360 100644 (file)
@@ -41,7 +41,7 @@ class HtmlInputNodeWoltlabMetacode extends AbstractHtmlNode {
                        }
                        
                        // handle simple mapping types
-                       if (isset($name, $this->simpleMapping)) {
+                       if (isset($this->simpleMapping[$name])) {
                                $newElement = $element->ownerDocument->createElement($this->simpleMapping[$name]);
                                DOMUtil::replaceElement($element, $newElement);
                                
index e92c4b443234ed8527f98e0b8f3adc88beddaab0..05c5fc39c0b621daf8212585aed70dbff59443a2 100644 (file)
@@ -1,5 +1,6 @@
 <?php
 namespace wcf\system\html\input\node;
+use wcf\system\bbcode\HtmlBBCodeParser;
 use wcf\system\exception\SystemException;
 use wcf\system\html\node\AbstractHtmlNode;
 use wcf\system\html\node\HtmlNodeProcessor;
@@ -314,29 +315,8 @@ class HtmlInputNodeWoltlabMetacodeMarker extends AbstractHtmlNode {
                /** @var \DOMElement $end */
                $end = $pair['close'];
                
-               $attributes = '';
-               if (!empty($pair['attributes'])) {
-                       $pair['attributes'] = base64_decode($pair['attributes'], true);
-                       if ($pair['attributes'] !== false) {
-                               try {
-                                       $pair['attributes'] = JSON::decode($pair['attributes']);
-                               }
-                               catch (SystemException $e) {
-                                       $pair['attributes'] = [];
-                               }
-                               
-                               if (!empty($pair['attributes'])) {
-                                       foreach ($pair['attributes'] as &$attribute) {
-                                               $attribute = "'" . addcslashes($attribute, "'") . "'";
-                                       }
-                                       unset($attribute);
-                                       
-                                       $attributes = '=' . implode(",", $attributes);
-                               }
-                       }
-               }
-               
-               $textNode = $start->ownerDocument->createTextNode('[' . $pair['name'] . $attributes . ']');
+               $attributes = (isset($pair['attributes'])) ? $pair['attributes'] : '';
+               $textNode = $start->ownerDocument->createTextNode(HtmlBBCodeParser::getInstance()->buildBBCodeTag($pair['name'], $attributes));
                DOMUtil::insertBefore($textNode, $start);
                DOMUtil::removeNode($start);
                
index 0e37b2ad9efc380f9cc683487f219a6aa518f32b..3a0b1b137f7f7d2cb8b844d99954e084ea3f6329 100644 (file)
@@ -1,6 +1,7 @@
 <?php
 namespace wcf\system\html\node;
 use wcf\system\exception\SystemException;
+use wcf\util\JSON;
 
 /**
  * TOOD documentation
@@ -84,6 +85,24 @@ class HtmlNodeProcessor {
                ];
        }
        
+       public function parseAttributes($attributes) {
+               if (empty($attributes)) {
+                       return [];
+               }
+               
+               $parsedAttributes = base64_decode($attributes, true);
+               if ($parsedAttributes !== false) {
+                       try {
+                               $parsedAttributes = JSON::decode($parsedAttributes);
+                       }
+                       catch (SystemException $e) {
+                               $parsedAttributes = [];
+                       }
+               }
+               
+               return $parsedAttributes;
+       }
+       
        protected function invokeHtmlNode(IHtmlNode $htmlNode) {
                $tagName = $htmlNode->getTagName();
                if (empty($tagName)) {
index 65794ba25e9eb6a74d11af56ff92030068f1be00..eb85e8e84619890d8eff1f5c9284dce6ca1fcb0c 100644 (file)
@@ -8,6 +8,8 @@ use wcf\system\html\node\HtmlNodeProcessor;
  */
 class HtmlOutputNodeProcessor extends HtmlNodeProcessor {
        public function process() {
+               $this->invokeHtmlNode(new HtmlOutputNodeWoltlabMetacode());
+               
                // TODO: this should be dynamic to some extent
                $this->invokeHtmlNode(new HtmlOutputNodeBlockquote());
                $this->invokeHtmlNode(new HtmlOutputNodeWoltlabMention());
diff --git a/wcfsetup/install/files/lib/system/html/output/node/HtmlOutputNodeWoltlabMetacode.class.php b/wcfsetup/install/files/lib/system/html/output/node/HtmlOutputNodeWoltlabMetacode.class.php
new file mode 100644 (file)
index 0000000..bb13fc5
--- /dev/null
@@ -0,0 +1,37 @@
+<?php
+namespace wcf\system\html\output\node;
+use wcf\system\bbcode\HtmlBBCodeParser;
+use wcf\system\html\node\AbstractHtmlNode;
+use wcf\system\html\node\HtmlNodeProcessor;
+use wcf\util\StringUtil;
+
+/**
+ * TOOD documentation
+ * @since      2.2
+ */
+class HtmlOutputNodeWoltlabMetacode extends AbstractHtmlNode {
+       protected $tagName = 'woltlab-metacode';
+       
+       /**
+        * @inheritDoc
+        */
+       public function process(array $elements, HtmlNodeProcessor $htmlNodeProcessor) {
+               /** @var \DOMElement $element */
+               foreach ($elements as $element) {
+                       $name = $element->getAttribute('data-name');
+                       $attributes = $element->getAttribute('data-attributes');
+                       
+                       $nodeIdentifier = StringUtil::getRandomID();
+                       $htmlNodeProcessor->addNodeData($this, $nodeIdentifier, [
+                               'name' => $name,
+                               'attributes' => $htmlNodeProcessor->parseAttributes($attributes)
+                       ]);
+                       
+                       $htmlNodeProcessor->renameTag($element, 'wcfNode-' . $nodeIdentifier);
+               }
+       }
+       
+       public function replaceTag(array $data) {
+               return HtmlBBCodeParser::getInstance()->getHtmlOutput($data['name'], $data['attributes']);
+       }
+}