From 1e8edfdef7f105f843d10c0773a04fced0c42904 Mon Sep 17 00:00:00 2001 From: Alexander Ebert Date: Sun, 15 May 2016 10:28:20 +0200 Subject: [PATCH] Added proper support for bbcodes during output --- .../system/bbcode/HtmlBBCodeParser.class.php | 49 +++++++++++++++++++ .../HtmlInputNodeWoltlabMetacode.class.php | 2 +- ...mlInputNodeWoltlabMetacodeMarker.class.php | 26 ++-------- .../html/node/HtmlNodeProcessor.class.php | 19 +++++++ .../node/HtmlOutputNodeProcessor.class.php | 2 + .../HtmlOutputNodeWoltlabMetacode.class.php | 37 ++++++++++++++ 6 files changed, 111 insertions(+), 24 deletions(-) create mode 100644 wcfsetup/install/files/lib/system/html/output/node/HtmlOutputNodeWoltlabMetacode.class.php diff --git a/wcfsetup/install/files/lib/system/bbcode/HtmlBBCodeParser.class.php b/wcfsetup/install/files/lib/system/bbcode/HtmlBBCodeParser.class.php index f164b31394..73048ecbd5 100644 --- a/wcfsetup/install/files/lib/system/bbcode/HtmlBBCodeParser.class.php +++ b/wcfsetup/install/files/lib/system/bbcode/HtmlBBCodeParser.class.php @@ -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, '', $closingTag, $this); + } + else { + return parent::buildOpeningTag($openingTag) . '' . 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 . '][/' . $name . ']'; + } + /** * Compiles tag fragments into the custom HTML element. * diff --git a/wcfsetup/install/files/lib/system/html/input/node/HtmlInputNodeWoltlabMetacode.class.php b/wcfsetup/install/files/lib/system/html/input/node/HtmlInputNodeWoltlabMetacode.class.php index bdc000f0b6..7d699d0438 100644 --- a/wcfsetup/install/files/lib/system/html/input/node/HtmlInputNodeWoltlabMetacode.class.php +++ b/wcfsetup/install/files/lib/system/html/input/node/HtmlInputNodeWoltlabMetacode.class.php @@ -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); diff --git a/wcfsetup/install/files/lib/system/html/input/node/HtmlInputNodeWoltlabMetacodeMarker.class.php b/wcfsetup/install/files/lib/system/html/input/node/HtmlInputNodeWoltlabMetacodeMarker.class.php index e92c4b4432..05c5fc39c0 100644 --- a/wcfsetup/install/files/lib/system/html/input/node/HtmlInputNodeWoltlabMetacodeMarker.class.php +++ b/wcfsetup/install/files/lib/system/html/input/node/HtmlInputNodeWoltlabMetacodeMarker.class.php @@ -1,5 +1,6 @@ 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); diff --git a/wcfsetup/install/files/lib/system/html/node/HtmlNodeProcessor.class.php b/wcfsetup/install/files/lib/system/html/node/HtmlNodeProcessor.class.php index 0e37b2ad9e..3a0b1b137f 100644 --- a/wcfsetup/install/files/lib/system/html/node/HtmlNodeProcessor.class.php +++ b/wcfsetup/install/files/lib/system/html/node/HtmlNodeProcessor.class.php @@ -1,6 +1,7 @@ getTagName(); if (empty($tagName)) { diff --git a/wcfsetup/install/files/lib/system/html/output/node/HtmlOutputNodeProcessor.class.php b/wcfsetup/install/files/lib/system/html/output/node/HtmlOutputNodeProcessor.class.php index 65794ba25e..eb85e8e846 100644 --- a/wcfsetup/install/files/lib/system/html/output/node/HtmlOutputNodeProcessor.class.php +++ b/wcfsetup/install/files/lib/system/html/output/node/HtmlOutputNodeProcessor.class.php @@ -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 index 0000000000..bb13fc5afb --- /dev/null +++ b/wcfsetup/install/files/lib/system/html/output/node/HtmlOutputNodeWoltlabMetacode.class.php @@ -0,0 +1,37 @@ +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']); + } +} -- 2.20.1