From: Alexander Ebert Date: Fri, 24 Jun 2016 13:32:54 +0000 (+0200) Subject: Cleanup and added missing documentation X-Git-Tag: 3.0.0_Beta_1~1358 X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=4ccf59756be62240fc1e6e9d14bc5ea54f021041;p=GitHub%2FWoltLab%2FWCF.git Cleanup and added missing documentation --- diff --git a/wcfsetup/install/files/lib/system/html/input/HtmlInputProcessor.class.php b/wcfsetup/install/files/lib/system/html/input/HtmlInputProcessor.class.php index 433f0a0b87..0a2ba2e48f 100644 --- a/wcfsetup/install/files/lib/system/html/input/HtmlInputProcessor.class.php +++ b/wcfsetup/install/files/lib/system/html/input/HtmlInputProcessor.class.php @@ -5,14 +5,22 @@ use wcf\system\html\input\filter\IHtmlInputFilter; use wcf\system\html\input\filter\MessageHtmlInputFilter; use wcf\system\html\input\node\HtmlInputNodeProcessor; use wcf\system\html\input\node\IHtmlInputNodeProcessor; -use wcf\system\html\node\IHtmlNodeProcessor; use wcf\util\StringUtil; /** - * TOOD documentation - * @since 3.0 + * Reads a HTML string, applies filters and parses all nodes including bbcodes. + * + * @author Alexander Ebert + * @copyright 2001-2016 WoltLab GmbH + * @license GNU Lesser General Public License + * @package WoltLabSuite\Core\System\Html\Input + * @since 3.0 */ class HtmlInputProcessor { + /** + * list of embedded content grouped by type + * @var array + */ protected $embeddedContent = []; /** @@ -25,6 +33,12 @@ class HtmlInputProcessor { */ protected $htmlInputNodeProcessor; + /** + * Processes input HTML by applying filters and parsing all nodes + * including bbcodes. + * + * @param string $html html string + */ public function process($html) { // enforce consistent newlines $html = StringUtil::unifyNewlines($html); @@ -45,14 +59,28 @@ class HtmlInputProcessor { // TODO } + /** + * Returns the parsed HTML ready to store. + * + * @return string parsed html + */ public function getHtml() { return $this->getHtmlInputNodeProcessor()->getHtml(); } + /** + * Returns the all embedded content data. + * + * @return array + */ + public function getEmbeddedContent() { + return $this->embeddedContent; + } + /** * @return IHtmlInputFilter */ - public function getHtmlInputFilter() { + protected function getHtmlInputFilter() { if ($this->htmlInputFilter === null) { $this->htmlInputFilter = new MessageHtmlInputFilter(); } @@ -60,26 +88,14 @@ class HtmlInputProcessor { return $this->htmlInputFilter; } - public function setHtmlInputFilter(IHtmlInputFilter $htmlInputFilter) { - $this->htmlInputFilter = $htmlInputFilter; - } - /** * @return IHtmlInputNodeProcessor */ - public function getHtmlInputNodeProcessor() { + protected function getHtmlInputNodeProcessor() { if ($this->htmlInputNodeProcessor === null) { $this->htmlInputNodeProcessor = new HtmlInputNodeProcessor(); } return $this->htmlInputNodeProcessor; } - - public function setHtmlInputNodeProcessor(IHtmlNodeProcessor $htmlInputNodeProcessor) { - $this->htmlInputNodeProcessor = $htmlInputNodeProcessor; - } - - public function getEmbeddedContent() { - return $this->embeddedContent; - } } diff --git a/wcfsetup/install/files/lib/system/html/input/filter/IHtmlInputFilter.class.php b/wcfsetup/install/files/lib/system/html/input/filter/IHtmlInputFilter.class.php index 6cf21c4966..461dcc5b89 100644 --- a/wcfsetup/install/files/lib/system/html/input/filter/IHtmlInputFilter.class.php +++ b/wcfsetup/install/files/lib/system/html/input/filter/IHtmlInputFilter.class.php @@ -2,8 +2,13 @@ namespace wcf\system\html\input\filter; /** - * TOOD documentation - * @since 3.0 + * Default interface for html input filters. + * + * @author Alexander Ebert + * @copyright 2001-2016 WoltLab GmbH + * @license GNU Lesser General Public License + * @package WoltLabSuite\Core\System\Html\Input\Filter + * @since 3.0 */ interface IHtmlInputFilter { /** diff --git a/wcfsetup/install/files/lib/system/html/input/filter/MessageHtmlInputFilter.class.php b/wcfsetup/install/files/lib/system/html/input/filter/MessageHtmlInputFilter.class.php index 4b7596e4d0..35adbfe6fb 100644 --- a/wcfsetup/install/files/lib/system/html/input/filter/MessageHtmlInputFilter.class.php +++ b/wcfsetup/install/files/lib/system/html/input/filter/MessageHtmlInputFilter.class.php @@ -1,9 +1,15 @@ + * @package WoltLabSuite\Core\System\Html\Input\Filter + * @since 3.0 */ class MessageHtmlInputFilter implements IHtmlInputFilter { /** @@ -11,6 +17,12 @@ class MessageHtmlInputFilter implements IHtmlInputFilter { */ protected static $purifier; + /** + * Applies HTMLPurifier's filter on provided HTML. + * + * @param string $html unsafe HTML + * @return string sanitized HTML + */ public function apply($html) { return $this->getPurifier()->purify($html); } @@ -28,8 +40,12 @@ class MessageHtmlInputFilter implements IHtmlInputFilter { return self::$purifier; } + /** + * Sets required configuration data for HTML filter. + * + * @param \HTMLPurifier_Config $config HTMLPurifier configuration + */ protected function setAttributeDefinitions(\HTMLPurifier_Config $config) { - // TODO: move this into own PHP classes $definition = $config->getHTMLDefinition(true); // quotes @@ -73,5 +89,11 @@ class MessageHtmlInputFilter implements IHtmlInputFilter { // add data-attachment-id="" for $definition->addAttribute('img', 'data-attachment-id', 'Number'); + + $parameters = [ + 'config' => $config, + 'definition' => $definition + ]; + EventHandler::getInstance()->fireAction($this, 'setAttributeDefinitions', $parameters); } } diff --git a/wcfsetup/install/files/lib/system/html/input/node/HtmlInputNodeImg.class.php b/wcfsetup/install/files/lib/system/html/input/node/HtmlInputNodeImg.class.php index 49d9bf1ebe..12e9b64c0f 100644 --- a/wcfsetup/install/files/lib/system/html/input/node/HtmlInputNodeImg.class.php +++ b/wcfsetup/install/files/lib/system/html/input/node/HtmlInputNodeImg.class.php @@ -1,22 +1,33 @@ ` to handle embedded attachments. + * + * @author Alexander Ebert + * @copyright 2001-2016 WoltLab GmbH + * @license GNU Lesser General Public License + * @package WoltLabSuite\Core\System\Html\Input\Node + * @since 3.0 */ class HtmlInputNodeImg extends AbstractHtmlNode { + /** + * @inheritDoc + */ protected $tagName = 'img'; - public function process(array $elements, HtmlNodeProcessor $htmlNodeProcessor) { + /** + * @inheritDoc + */ + public function process(array $elements, AbstractHtmlNodeProcessor $htmlNodeProcessor) { /** @var \DOMElement $element */ foreach ($elements as $element) { $class = $element->getAttribute('class'); - if ($class !== 'woltlabAttachment') { + if (!preg_match('~\bwoltlabAttachment\b~', $class)) { continue; } @@ -25,17 +36,20 @@ class HtmlInputNodeImg extends AbstractHtmlNode { continue; } - // TODO: add alignment detection - $alignment = 'none'; + $float = 'none'; $thumbnail = false; if (strpos($element->getAttribute('src'), 'thumbnail=1') !== false) { $thumbnail = true; } + if (preg_match('~\bmessageFloatObject(?PLeft|Right)\b~', $class, $matches)) { + $float = ($matches['float'] === 'Left') ? 'left' : 'right'; + } + $attributes = [ $attachmentID, - $alignment, + $float, $thumbnail ]; 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 e88dc7e633..0d2c8e5e96 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 @@ -1,22 +1,27 @@ + * @package WoltLabSuite\Core\System\Html\Input\Node + * @since 3.0 */ -class HtmlInputNodeProcessor extends HtmlNodeProcessor implements IHtmlInputNodeProcessor { +class HtmlInputNodeProcessor extends AbstractHtmlNodeProcessor { + /** + * list of embedded content grouped by type + * @var array + */ protected $embeddedContent = []; - // TODO: this should include other tags - protected $emptyTags = ['em', 'strong', 'u']; - - // TODO: this should include other tags - protected $mergeTags = ['em', 'strong', 'u']; - + /** + * @inheritDoc + */ public function process() { EventHandler::getInstance()->fireAction($this, 'beforeProcess'); @@ -29,6 +34,9 @@ class HtmlInputNodeProcessor extends HtmlNodeProcessor implements IHtmlInputNode $this->invokeHtmlNode(new HtmlInputNodeWoltlabMetacode()); $this->invokeHtmlNode(new HtmlInputNodeImg()); + // dynamic node handlers + $this->invokeNodeHandlers('wcf\system\html\input\node\HtmlInputNode', ['img', 'woltlab-metacode']); + // detect mentions, urls, emails and smileys $textParser = new HtmlInputNodeTextParser($this); $textParser->parse(); @@ -36,19 +44,24 @@ class HtmlInputNodeProcessor extends HtmlNodeProcessor implements IHtmlInputNode // extract embedded content $this->parseEmbeddedContent(); - // remove empty elements and join identical siblings if appropriate - $this->cleanup(); - EventHandler::getInstance()->fireAction($this, 'afterProcess'); } /** - * @inheritDoc + * Returns the embedded content grouped by type. + * + * @return array */ public function getEmbeddedContent() { return $this->embeddedContent; } + /** + * Add embedded content for provided type. + * + * @param string $type type name + * @param array $data embedded content + */ public function addEmbeddedContent($type, array $data) { if (isset($this->embeddedContent[$type])) { $this->embeddedContent[$type] = array_merge($this->embeddedContent[$type], $data); @@ -58,6 +71,9 @@ class HtmlInputNodeProcessor extends HtmlNodeProcessor implements IHtmlInputNode } } + /** + * Parses embedded content containedin metacode elements. + */ protected function parseEmbeddedContent() { // handle `woltlab-metacode` $elements = $this->getDocument()->getElementsByTagName('woltlab-metacode'); @@ -77,47 +93,6 @@ class HtmlInputNodeProcessor extends HtmlNodeProcessor implements IHtmlInputNode EventHandler::getInstance()->fireAction($this, 'parseEmbeddedContent'); } - protected function cleanup() { - // remove emtpy elements - foreach ($this->emptyTags as $emptyTag) { - $elements = []; - foreach ($this->getDocument()->getElementsByTagName($emptyTag) as $element) { - $elements[] = $element; - } - - /** @var \DOMElement $element */ - foreach ($elements as $element) { - if (DOMUtil::isEmpty($element)) { - DOMUtil::removeNode($element); - } - } - } - - // find identical siblings - foreach ($this->mergeTags as $mergeTag) { - $elements = []; - foreach ($this->getDocument()->getElementsByTagName($mergeTag) as $element) { - $elements[] = $element; - } - - /** @var \DOMElement $element */ - foreach ($elements as $element) { - $sibling = $element->nextSibling; - if ($sibling === null) { - continue; - } - - if ($sibling->nodeName === $mergeTag) { - while ($sibling->hasChildNodes()) { - $element->appendChild($sibling->childNodes[0]); - } - - DOMUtil::removeNode($sibling); - } - } - } - } - /** * Creates a new `` element contained in the same document * as the provided `$node`. diff --git a/wcfsetup/install/files/lib/system/html/input/node/HtmlInputNodeTextParser.class.php b/wcfsetup/install/files/lib/system/html/input/node/HtmlInputNodeTextParser.class.php index 1488adcb6b..ebdf26e868 100644 --- a/wcfsetup/install/files/lib/system/html/input/node/HtmlInputNodeTextParser.class.php +++ b/wcfsetup/install/files/lib/system/html/input/node/HtmlInputNodeTextParser.class.php @@ -9,10 +9,19 @@ use wcf\system\WCF; use wcf\util\StringUtil; /** - * TOOD documentation + * Parses all text nodes searching for links, media, mentions or smilies. + * + * @author Alexander Ebert + * @copyright 2001-2016 WoltLab GmbH + * @license GNU Lesser General Public License + * @package WoltLabSuite\Core\System\Html\Input\Node * @since 3.0 */ class HtmlInputNodeTextParser { + /** + * list of markers per element that will face a replacement + * @var \DOMElement[][] + */ protected $elementStack = []; /** @@ -20,8 +29,16 @@ class HtmlInputNodeTextParser { */ protected $htmlInputNodeProcessor; + /** + * list of text nodes that will face a replacement + * @var \DOMText[] + */ protected $nodeStack = []; + /** + * list of smilies by smiley code + * @var string[] + */ protected $smilies = []; /** @@ -35,6 +52,10 @@ class HtmlInputNodeTextParser { */ protected static $illegalChars = '[^\x0-\x2C\x2E\x2F\x3A-\x40\x5B-\x60\x7B-\x7F]+'; + /** + * regex for user mentions + * @var string + */ protected static $userRegex = "~ \\B # any non-word character, whitespace, string start is fine @ @@ -47,6 +68,11 @@ class HtmlInputNodeTextParser { ) ~x"; + /** + * HtmlInputNodeTextParser constructor. + * + * @param HtmlInputNodeProcessor $htmlInputNodeProcessor + */ public function __construct(HtmlInputNodeProcessor $htmlInputNodeProcessor) { $this->htmlInputNodeProcessor = $htmlInputNodeProcessor; $this->sourceBBCodes = HtmlBBCodeParser::getInstance()->getSourceBBCodes(); @@ -83,6 +109,9 @@ class HtmlInputNodeTextParser { } } + /** + * Parses all text nodes searching for possible replacements. + */ public function parse() { // get all text nodes $nodes = []; @@ -114,7 +143,7 @@ class HtmlInputNodeTextParser { $users = []; if (!empty($usernames)) { - $users = $this->findUsernames($usernames); + $users = $this->lookupUsernames($usernames); } for ($i = 0, $length = count($nodes); $i < $length; $i++) { @@ -141,6 +170,13 @@ class HtmlInputNodeTextParser { } } + /** + * Detects mentions in text nodes. + * + * @param \DOMText $text text node + * @param string $value node value + * @param string[] $usernames list of already found usernames + */ protected function detectMention(\DOMText $text, $value, array &$usernames) { if (mb_strpos($value, '@') === false) { return; @@ -159,7 +195,13 @@ class HtmlInputNodeTextParser { } } - protected function findUsernames(array $usernames) { + /** + * Matches the found usernames agains the user table. + * + * @param string[] $usernames list of found usernames + * @return string[] list of valid usernames + */ + protected function lookupUsernames(array $usernames) { $exactValues = []; $likeValues = []; foreach ($usernames as $username) { @@ -214,6 +256,14 @@ class HtmlInputNodeTextParser { return $users; } + /** + * Parses text nodes and searches for mentions. + * + * @param \DOMText $text text node + * @param string $value node value + * @param string[] $users list of usernames by user id + * @return string modified node value with replacement placeholders + */ protected function parseMention(\DOMText $text, $value, array $users) { if (mb_strpos($value, '@') === false) { return $value; @@ -249,6 +299,13 @@ class HtmlInputNodeTextParser { return $value; } + /** + * Parses regular links and media links contained in text nodes. + * + * @param \DOMText $text text node + * @param string $value node value + * @return string modified node value with replacement placeholders + */ protected function parseURL(\DOMText $text, $value) { static $urlPattern = ''; if ($urlPattern === '') { @@ -288,6 +345,13 @@ class HtmlInputNodeTextParser { }, $value); } + /** + * Parses text nodes and replaces email addresses. + * + * @param \DOMText $text text node + * @param string $value node value + * @return string modified node value with replacement placeholders + */ protected function parseEmail(\DOMText $text, $value) { if (mb_strpos($this->text, '@') === false) { return $value; @@ -314,6 +378,13 @@ class HtmlInputNodeTextParser { }, $value); } + /** + * Parses text nodes and replaces smilies. + * + * @param \DOMText $text text node + * @param string $value node value + * @return string modified node value with replacement placeholders + */ protected function parseSmiley(\DOMText $text, $value) { static $smileyPattern = null; if ($smileyPattern === null) { @@ -343,6 +414,12 @@ class HtmlInputNodeTextParser { }, $value); } + /** + * Replaces all found occurences of special text with their new value. + * + * @param \DOMText $text text node + * @param \DOMElement[] $elements elements to be inserted + */ protected function replaceMatches(\DOMText $text, array $elements) { $nodes = [$text]; @@ -373,12 +450,19 @@ class HtmlInputNodeTextParser { } } + /** + * Returns true if text node is inside a code element, suppresing any + * auto-detection of content. + * + * @param \DOMText $text text node + * @return boolean true if text node is inside a code element + */ protected function hasCodeParent(\DOMText $text) { $parent = $text; /** @var \DOMElement $parent */ while ($parent = $parent->parentNode) { $nodeName = $parent->nodeName; - if ($nodeName === 'code' || $nodeName === 'kbd') { + if ($nodeName === 'code' || $nodeName === 'kbd' || $nodeName === 'pre') { return true; } else if ($nodeName === 'woltlab-metacode' && in_array($parent->getAttribute('data-name'), $this->sourceBBCodes)) { @@ -389,6 +473,13 @@ class HtmlInputNodeTextParser { return false; } + /** + * Returns true if text node is inside a link, preventing the link content + * being recognized as a link again. + * + * @param \DOMText $text text node + * @return boolean true if text node is inside a link + */ protected function hasLinkParent(\DOMText $text) { $parent = $text; /** @var \DOMElement $parent */ @@ -402,6 +493,17 @@ class HtmlInputNodeTextParser { return false; } + /** + * Uses string markers to replace the matched text. This process prevents multiple + * detections being applied to the same target and enables us to delay replacement. + * + * Immediately replacing matches would potentially cause a lot of DOM modifications + * and moving of nodes especially if there are multiple matches per text node. + * + * @param \DOMText $text text node + * @param \DOMElement $element element queued for insertion + * @return string replacement marker + */ public function addReplacement(\DOMText $text, \DOMElement $element) { $index = array_search($text, $this->nodeStack, true); if ($index === false) { @@ -417,16 +519,22 @@ class HtmlInputNodeTextParser { return $marker; } + /** + * Returns a random string marker for replacement. + * + * @return string random string marker + */ public function getNewMarker() { return '@@@' . StringUtil::getUUID() . '@@@'; } /** - * Returns the username for the given regular expression match. - * - * @param string $match - * @return string - * @since 3.0 + * Returns the username for the given regular expression match and takes care + * of any quotes outside the username and certain special characters, such as + * colons, that have been incorrectly matched. + * + * @param string $match matched username + * @return string sanitized username */ public function getUsername($match) { // remove escaped single quotation mark diff --git a/wcfsetup/install/files/lib/system/html/input/node/HtmlInputNodeWoltlabMention.class.php b/wcfsetup/install/files/lib/system/html/input/node/HtmlInputNodeWoltlabMention.class.php index 67f99aa3d2..253add68da 100644 --- a/wcfsetup/install/files/lib/system/html/input/node/HtmlInputNodeWoltlabMention.class.php +++ b/wcfsetup/install/files/lib/system/html/input/node/HtmlInputNodeWoltlabMention.class.php @@ -1,16 +1,29 @@ `. + * + * @author Alexander Ebert + * @copyright 2001-2016 WoltLab GmbH + * @license GNU Lesser General Public License + * @package WoltLabSuite\Core\System\Html\Input\Node + * @since 3.0 */ class HtmlInputNodeWoltlabMention extends AbstractHtmlNode { + /** + * @inheritDoc + */ protected $tagName = 'woltlab-mention'; - public function process(array $elements, HtmlNodeProcessor $htmlNodeProcessor) { + /** + * @inheritDoc + */ + public function process(array $elements, AbstractHtmlNodeProcessor $htmlNodeProcessor) { + // TODO + $userIds = []; /** @var \DOMElement $mention */ @@ -25,8 +38,4 @@ class HtmlInputNodeWoltlabMention extends AbstractHtmlNode { } } - - public function replaceTag(array $data) { - return null; - } } 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 161680b29a..23acfc8681 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 @@ -2,12 +2,17 @@ namespace wcf\system\html\input\node; use wcf\system\html\metacode\converter\IMetacodeConverter; use wcf\system\html\node\AbstractHtmlNode; -use wcf\system\html\node\HtmlNodeProcessor; +use wcf\system\html\node\AbstractHtmlNodeProcessor; use wcf\util\DOMUtil; /** - * TOOD documentation - * @since 3.0 + * Proccesses `` and converts them if appropriate. + * + * @author Alexander Ebert + * @copyright 2001-2016 WoltLab GmbH + * @license GNU Lesser General Public License + * @package WoltLabSuite\Core\System\Html\Input\Node + * @since 3.0 */ class HtmlInputNodeWoltlabMetacode extends AbstractHtmlNode { /** @@ -23,9 +28,15 @@ class HtmlInputNodeWoltlabMetacode extends AbstractHtmlNode { 'u' => 'u' ]; + /** + * @inheritDoc + */ protected $tagName = 'woltlab-metacode'; - public function process(array $elements, HtmlNodeProcessor $htmlNodeProcessor) { + /** + * @inheritDoc + */ + public function process(array $elements, AbstractHtmlNodeProcessor $htmlNodeProcessor) { /** @var IMetacodeConverter[] $converters */ $converters = []; @@ -78,11 +89,10 @@ class HtmlInputNodeWoltlabMetacode extends AbstractHtmlNode { } } + /** + * @inheritDoc + */ public function replaceTag(array $data) { return $data['parsedTag']; } - - protected function getPlaceholderElement() { - return new \DOMElement('woltlab-placeholder'); - } } 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 7e87f925ba..8a90cb92f8 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 @@ -2,7 +2,7 @@ namespace wcf\system\html\input\node; use wcf\system\bbcode\HtmlBBCodeParser; use wcf\system\html\node\AbstractHtmlNode; -use wcf\system\html\node\HtmlNodeProcessor; +use wcf\system\html\node\AbstractHtmlNodeProcessor; use wcf\util\DOMUtil; /** @@ -44,7 +44,7 @@ class HtmlInputNodeWoltlabMetacodeMarker extends AbstractHtmlNode { /** * @inheritDoc */ - public function process(array $elements, HtmlNodeProcessor $htmlNodeProcessor) { + public function process(array $elements, AbstractHtmlNodeProcessor $htmlNodeProcessor) { // collect pairs $pairs = $this->buildPairs($elements); @@ -72,7 +72,7 @@ class HtmlInputNodeWoltlabMetacodeMarker extends AbstractHtmlNode { while ($parent = $parent->parentNode) { $nodeName = $parent->nodeName; - if ($nodeName === 'code' || $nodeName === 'kbd') { + if ($nodeName === 'code' || $nodeName === 'kbd' || $nodeName === 'pre') { return true; } else if ($nodeName === 'woltlab-metacode') { diff --git a/wcfsetup/install/files/lib/system/html/input/node/IHtmlInputNode.class.php b/wcfsetup/install/files/lib/system/html/input/node/IHtmlInputNode.class.php index 14a293deb7..33d2a709ce 100644 --- a/wcfsetup/install/files/lib/system/html/input/node/IHtmlInputNode.class.php +++ b/wcfsetup/install/files/lib/system/html/input/node/IHtmlInputNode.class.php @@ -3,7 +3,12 @@ namespace wcf\system\html\input\node; use wcf\system\html\node\IHtmlNode; /** - * TOOD documentation - * @since 3.0 + * Default interface for html input nodes. + * + * @author Alexander Ebert + * @copyright 2001-2016 WoltLab GmbH + * @license GNU Lesser General Public License + * @package WoltLabSuite\Core\System\Html\Input\Node + * @since 3.0 */ interface IHtmlInputNode extends IHtmlNode {} diff --git a/wcfsetup/install/files/lib/system/html/input/node/IHtmlInputNodeProcessor.class.php b/wcfsetup/install/files/lib/system/html/input/node/IHtmlInputNodeProcessor.class.php deleted file mode 100644 index 2c2f6aaba0..0000000000 --- a/wcfsetup/install/files/lib/system/html/input/node/IHtmlInputNodeProcessor.class.php +++ /dev/null @@ -1,12 +0,0 @@ - + * @package WoltLabSuite\Core\System\Html\Metacode\Converter + * @since 3.0 */ abstract class AbstractMetacodeConverter implements IMetacodeConverter { /** diff --git a/wcfsetup/install/files/lib/system/html/metacode/converter/CodeMetacodeConverter.class.php b/wcfsetup/install/files/lib/system/html/metacode/converter/CodeMetacodeConverter.class.php index 462253b64a..07e9c5060f 100644 --- a/wcfsetup/install/files/lib/system/html/metacode/converter/CodeMetacodeConverter.class.php +++ b/wcfsetup/install/files/lib/system/html/metacode/converter/CodeMetacodeConverter.class.php @@ -2,8 +2,13 @@ namespace wcf\system\html\metacode\converter; /** - * TOOD documentation - * @since 3.0 + * Converts code bbcode into `
`.
+ * 
+ * @author      Alexander Ebert
+ * @copyright   2001-2016 WoltLab GmbH
+ * @license     GNU Lesser General Public License 
+ * @package     WoltLabSuite\Core\System\Html\Metacode\Converter
+ * @since       3.0
  */
 class CodeMetacodeConverter extends AbstractMetacodeConverter {
 	/**
diff --git a/wcfsetup/install/files/lib/system/html/metacode/converter/ColorMetacodeConverter.class.php b/wcfsetup/install/files/lib/system/html/metacode/converter/ColorMetacodeConverter.class.php
index d6d61fea9b..1225d2b866 100644
--- a/wcfsetup/install/files/lib/system/html/metacode/converter/ColorMetacodeConverter.class.php
+++ b/wcfsetup/install/files/lib/system/html/metacode/converter/ColorMetacodeConverter.class.php
@@ -2,8 +2,13 @@
 namespace wcf\system\html\metacode\converter;
 
 /**
- * TOOD documentation
- * @since	3.0
+ * Converts color bbcode into ``.
+ * 
+ * @author      Alexander Ebert
+ * @copyright   2001-2016 WoltLab GmbH
+ * @license     GNU Lesser General Public License 
+ * @package     WoltLabSuite\Core\System\Html\Metacode\Converter
+ * @since       3.0
  */
 class ColorMetacodeConverter extends AbstractMetacodeConverter {
 	/**
diff --git a/wcfsetup/install/files/lib/system/html/metacode/converter/IMetacodeConverter.class.php b/wcfsetup/install/files/lib/system/html/metacode/converter/IMetacodeConverter.class.php
index d832f40cf6..499b47405f 100644
--- a/wcfsetup/install/files/lib/system/html/metacode/converter/IMetacodeConverter.class.php
+++ b/wcfsetup/install/files/lib/system/html/metacode/converter/IMetacodeConverter.class.php
@@ -2,8 +2,13 @@
 namespace wcf\system\html\metacode\converter;
 
 /**
- * TOOD documentation
- * @since	3.0
+ * Default interface for metacode converters.
+ * 
+ * @author      Alexander Ebert
+ * @copyright   2001-2016 WoltLab GmbH
+ * @license     GNU Lesser General Public License 
+ * @package     WoltLabSuite\Core\System\Html\Metacode\Converter
+ * @since       3.0
  */
 interface IMetacodeConverter {
 	/**
diff --git a/wcfsetup/install/files/lib/system/html/metacode/converter/QuoteMetacodeConverter.class.php b/wcfsetup/install/files/lib/system/html/metacode/converter/QuoteMetacodeConverter.class.php
index 7318cc7b84..0766b7b904 100644
--- a/wcfsetup/install/files/lib/system/html/metacode/converter/QuoteMetacodeConverter.class.php
+++ b/wcfsetup/install/files/lib/system/html/metacode/converter/QuoteMetacodeConverter.class.php
@@ -2,8 +2,13 @@
 namespace wcf\system\html\metacode\converter;
 
 /**
- * TOOD documentation
- * @since	3.0
+ * Converts quote bbcode into `
`. + * + * @author Alexander Ebert + * @copyright 2001-2016 WoltLab GmbH + * @license GNU Lesser General Public License + * @package WoltLabSuite\Core\System\Html\Metacode\Converter + * @since 3.0 */ class QuoteMetacodeConverter extends AbstractMetacodeConverter { /** @@ -11,7 +16,6 @@ class QuoteMetacodeConverter extends AbstractMetacodeConverter { */ public function convert(\DOMDocumentFragment $fragment, array $attributes) { $element = $fragment->ownerDocument->createElement('blockquote'); - $element->setAttribute('class', 'quoteBox'); $element->setAttribute('data-quote-title', (isset($attributes[0])) ? $attributes[0] : ''); $element->setAttribute('data-quote-url', (isset($attributes[1])) ? $attributes[1] : ''); $element->appendChild($fragment); diff --git a/wcfsetup/install/files/lib/system/html/metacode/converter/SizeMetacodeConverter.class.php b/wcfsetup/install/files/lib/system/html/metacode/converter/SizeMetacodeConverter.class.php index a9aa98744a..87fe4e9085 100644 --- a/wcfsetup/install/files/lib/system/html/metacode/converter/SizeMetacodeConverter.class.php +++ b/wcfsetup/install/files/lib/system/html/metacode/converter/SizeMetacodeConverter.class.php @@ -2,8 +2,13 @@ namespace wcf\system\html\metacode\converter; /** - * TOOD documentation - * @since 3.0 + * Converts size bbcode into ``. + * + * @author Alexander Ebert + * @copyright 2001-2016 WoltLab GmbH + * @license GNU Lesser General Public License + * @package WoltLabSuite\Core\System\Html\Metacode\Converter + * @since 3.0 */ class SizeMetacodeConverter extends AbstractMetacodeConverter { protected $sizes = [8, 10, 12, 14, 18, 24, 36]; diff --git a/wcfsetup/install/files/lib/system/html/metacode/converter/SpoilerMetacodeConverter.class.php b/wcfsetup/install/files/lib/system/html/metacode/converter/SpoilerMetacodeConverter.class.php index 89ab85c062..941b371d0b 100644 --- a/wcfsetup/install/files/lib/system/html/metacode/converter/SpoilerMetacodeConverter.class.php +++ b/wcfsetup/install/files/lib/system/html/metacode/converter/SpoilerMetacodeConverter.class.php @@ -3,8 +3,13 @@ namespace wcf\system\html\metacode\converter; use wcf\util\StringUtil; /** - * TOOD documentation - * @since 3.0 + * Converts spoiler bbcode into ``. + * + * @author Alexander Ebert + * @copyright 2001-2016 WoltLab GmbH + * @license GNU Lesser General Public License + * @package WoltLabSuite\Core\System\Html\Metacode\Converter + * @since 3.0 */ class SpoilerMetacodeConverter extends AbstractMetacodeConverter { /** diff --git a/wcfsetup/install/files/lib/system/html/node/AbstractHtmlNode.class.php b/wcfsetup/install/files/lib/system/html/node/AbstractHtmlNode.class.php index d2a37fbf61..cf8100d49d 100644 --- a/wcfsetup/install/files/lib/system/html/node/AbstractHtmlNode.class.php +++ b/wcfsetup/install/files/lib/system/html/node/AbstractHtmlNode.class.php @@ -2,18 +2,37 @@ namespace wcf\system\html\node; /** - * TOOD documentation - * @since 3.0 + * Default implementation for html nodes. + * + * @author Alexander Ebert + * @copyright 2001-2016 WoltLab GmbH + * @license GNU Lesser General Public License + * @package WoltLabSuite\Core\System\Html\Node + * @since 3.0 */ abstract class AbstractHtmlNode implements IHtmlNode { + /** + * tag name used to identify elements consumed by this node + * @var string + */ protected $tagName = ''; + /** + * placeholder for inner content when performing direct html replacement + * @var string + */ const PLACEHOLDER = ''; + /** + * @inheritDoc + */ public function getTagName() { return $this->tagName; } + /** + * @inheritDoc + */ public function replaceTag(array $data) { throw new \BadMethodCallException("Method replaceTag() is not supported by ".get_class($this)); } diff --git a/wcfsetup/install/files/lib/system/html/node/AbstractHtmlNodeProcessor.class.php b/wcfsetup/install/files/lib/system/html/node/AbstractHtmlNodeProcessor.class.php new file mode 100644 index 0000000000..fc4610fd39 --- /dev/null +++ b/wcfsetup/install/files/lib/system/html/node/AbstractHtmlNodeProcessor.class.php @@ -0,0 +1,223 @@ + + * @package WoltLabSuite\Core\System\Html\Node + * @since 3.0 + */ +abstract class AbstractHtmlNodeProcessor implements IHtmlNodeProcessor { + /** + * active DOM document + * @var \DOMDocument + */ + protected $document; + + /** + * storage for node replacements + * @var array + */ + protected $nodeData = []; + + /** + * XPath instance + * @var \DOMXPath + */ + protected $xpath; + + /** + * @inheritDOc + */ + public function load($html) { + $this->document = new \DOMDocument('1.0', 'UTF-8'); + $this->xpath = null; + + // Ignore all errors when loading the HTML string, because DOMDocument does not + // provide a proper way to add custom HTML elements (even though explicitly allowed + // in HTML5) and the input HTML has already been sanitized by HTMLPurifier. + // + // We're also injecting a bogus meta tag that magically enables DOMDocument + // to handle UTF-8 properly. This avoids encoding non-ASCII characters as it + // would conflict with already existing entities when reverting them. + @$this->document->loadHTML('' . $html); + + $this->nodeData = []; + } + + /** + * @inheritDoc + */ + public function getHtml() { + $html = $this->document->saveHTML($this->document->getElementsByTagName('body')->item(0)); + + // remove nuisance added by PHP + $html = preg_replace('~^~', '', $html); + $html = preg_replace('~$~', '', $html); + + /** @var IHtmlNode $obj */ + foreach ($this->nodeData as $data) { + $obj = $data['object']; + $string = $obj->replaceTag($data['data']); + $html = preg_replace_callback('~(?P[\s\S]*)~', function($matches) use ($string) { + $string = str_replace('', $matches['content'], $string); + + return $string; + }, $html); + + } + + return $html; + } + + /** + * @inheritDoc + */ + public function getDocument() { + return $this->document; + } + + /** + * Returns a XPath instance for the current DOM document. + * + * @return \DOMXPath XPath instance + */ + public function getXPath() { + if ($this->xpath === null) { + $this->xpath = new \DOMXPath($this->getDocument()); + } + + return $this->xpath; + } + + /** + * Renames a tag by creating a new element, moving all child nodes and + * eventually removing the original element. + * + * @param \DOMElement $element old element + * @param string $tagName tag name for the new element + * @return \DOMElement newly created element + */ + public function renameTag(\DOMElement $element, $tagName) { + $newElement = $this->document->createElement($tagName); + $element->parentNode->insertBefore($newElement, $element); + while ($element->hasChildNodes()) { + $newElement->appendChild($element->firstChild); + } + + $element->parentNode->removeChild($element); + + return $newElement; + } + + /** + * Removes an element but preserves child nodes by moving them into + * its original position. + * + * @param \DOMElement $element element to be removed + */ + public function unwrapContent(\DOMElement $element) { + while ($element->hasChildNodes()) { + $element->parentNode->insertBefore($element->firstChild, $element); + } + + $element->parentNode->removeChild($element); + } + + /** + * Adds node replacement data. + * + * @param IHtmlNode $htmlNode node processor instance + * @param string $nodeIdentifier replacement node identifier + * @param array $data replacement data + */ + public function addNodeData(IHtmlNode $htmlNode, $nodeIdentifier, array $data) { + $this->nodeData[] = [ + 'data' => $data, + 'identifier' => $nodeIdentifier, + 'object' => $htmlNode + ]; + } + + /** + * Parses an attribute string. + * + * @param string $attributes base64 and JSON encoded attributes + * @return array parsed attributes + */ + public function parseAttributes($attributes) { + if (empty($attributes)) { + return []; + } + + $parsedAttributes = base64_decode($attributes, true); + if ($parsedAttributes !== false) { + try { + $parsedAttributes = JSON::decode($parsedAttributes); + } + catch (SystemException $e) { + /* parse errors can occur if user provided malicious content - ignore them */ + $parsedAttributes = []; + } + } + + return $parsedAttributes; + } + + /** + * Invokes a html node processor. + * + * @param IHtmlNode $htmlNode html node processor + */ + protected function invokeHtmlNode(IHtmlNode $htmlNode) { + $tagName = $htmlNode->getTagName(); + if (empty($tagName)) { + throw new \UnexpectedValueException("Missing tag name for " . get_class($htmlNode)); + } + + $elements = []; + foreach ($this->getDocument()->getElementsByTagName($tagName) as $element) { + $elements[] = $element; + } + + if (!empty($elements)) { + $htmlNode->process($elements, $this); + } + } + + /** + * Invokes possible html node processors based on found element tag names. + * + * @param string $classNamePattern full namespace pattern for class guessing + * @param string[] $skipTags list of tag names that should be ignored + */ + protected function invokeNodeHandlers($classNamePattern, array $skipTags = []) { + $skipTags = array_merge($skipTags, ['html', 'head', 'title', 'meta', 'body', 'link']); + + $tags = []; + /** @var \DOMElement $tag */ + foreach ($this->getDocument()->getElementsByTagName('*') as $tag) { + $tagName = $tag->nodeName; + if (!isset($tags[$tagName])) $tags[$tagName] = $tagName; + } + + foreach ($tags as $tagName) { + if (in_array($tagName, $skipTags)) { + continue; + } + + $tagName = preg_replace_callback('/-([a-z])/', function($matches) { + return ucfirst($matches[1]); + }, $tagName); + $className = $classNamePattern . ucfirst($tagName); + if (class_exists($className)) { + $this->invokeHtmlNode(new $className); + } + } + } +} diff --git a/wcfsetup/install/files/lib/system/html/node/HtmlNodeProcessor.class.php b/wcfsetup/install/files/lib/system/html/node/HtmlNodeProcessor.class.php deleted file mode 100644 index 0c0e4f6668..0000000000 --- a/wcfsetup/install/files/lib/system/html/node/HtmlNodeProcessor.class.php +++ /dev/null @@ -1,135 +0,0 @@ -document = new \DOMDocument('1.0', 'UTF-8'); - $this->xpath = null; - - // ignore all errors when loading the HTML string, because DOMDocument does not - // provide a proper way to add custom HTML elements (even though explicitly allowed - // in HTML5) and the input HTML has already been sanitized by HTMLPurifier - // - // we're also injecting a bogus meta tag that magically enables DOMDocument - // to handle UTF-8 properly, this avoids encoding non-ASCII characters as it - // would conflict with already existing entities when reverting them - @$this->document->loadHTML('' . $html); - - $this->nodeData = []; - } - - public function getHtml() { - $html = $this->document->saveHTML($this->document->getElementsByTagName('body')->item(0)); - - // remove nuisance added by PHP - $html = preg_replace('~^~', '', $html); - $html = preg_replace('~$~', '', $html); - - /** @var IHtmlNode $obj */ - foreach ($this->nodeData as $data) { - $obj = $data['object']; - $string = $obj->replaceTag($data['data']); - $html = preg_replace_callback('~(?P[\s\S]*)~', function($matches) use ($string) { - $string = str_replace('', $matches['content'], $string); - - return $string; - }, $html); - - } - - return $html; - } - - public function getDocument() { - return $this->document; - } - - public function getXPath() { - if ($this->xpath === null) { - $this->xpath = new \DOMXPath($this->getDocument()); - } - - return $this->xpath; - } - - public function renameTag(\DOMElement $element, $tagName) { - $newElement = $this->document->createElement($tagName); - $element->parentNode->insertBefore($newElement, $element); - while ($element->hasChildNodes()) { - $newElement->appendChild($element->firstChild); - } - - $element->parentNode->removeChild($element); - - return $newElement; - } - - public function unwrapContent(\DOMElement $element) { - while ($element->hasChildNodes()) { - $element->parentNode->insertBefore($element->firstChild, $element); - } - - $element->parentNode->removeChild($element); - } - - public function addNodeData(IHtmlNode $htmlNode, $nodeIdentifier, array $data) { - $this->nodeData[] = [ - 'data' => $data, - 'identifier' => $nodeIdentifier, - 'object' => $htmlNode - ]; - } - - public function parseAttributes($attributes) { - if (empty($attributes)) { - return []; - } - - $parsedAttributes = base64_decode($attributes, true); - if ($parsedAttributes !== false) { - try { - $parsedAttributes = JSON::decode($parsedAttributes); - } - catch (SystemException $e) { - /* parse errors can occur if user provided malicious content - ignore them */ - $parsedAttributes = []; - } - } - - return $parsedAttributes; - } - - protected function invokeHtmlNode(IHtmlNode $htmlNode) { - $tagName = $htmlNode->getTagName(); - if (empty($tagName)) { - throw new \UnexpectedValueException("Missing tag name for " . get_class($htmlNode)); - } - - $elements = []; - foreach ($this->getDocument()->getElementsByTagName($tagName) as $element) { - $elements[] = $element; - } - - if (!empty($elements)) { - $htmlNode->process($elements, $this); - } - } -} diff --git a/wcfsetup/install/files/lib/system/html/node/IHtmlNode.class.php b/wcfsetup/install/files/lib/system/html/node/IHtmlNode.class.php index 8f81002650..2f71694cf1 100644 --- a/wcfsetup/install/files/lib/system/html/node/IHtmlNode.class.php +++ b/wcfsetup/install/files/lib/system/html/node/IHtmlNode.class.php @@ -2,18 +2,34 @@ namespace wcf\system\html\node; /** - * TOOD documentation - * @since 3.0 + * Default interface for html nodes. + * + * @author Alexander Ebert + * @copyright 2001-2016 WoltLab GmbH + * @license GNU Lesser General Public License + * @package WoltLabSuite\Core\System\Html\Node + * @since 3.0 */ interface IHtmlNode { + /** + * Returns the tag name of elements consumed by this node. + * + * @return string tag name of consumed elements + */ public function getTagName(); /** - * @param \DOMElement[] $elements - * @param HtmlNodeProcessor $htmlNodeProcessor - * @return mixed + * Processes the provided elements and marks them for replacement if applicable. + * + * @param \DOMElement[] $elements static list of matched elements, does not change when removing elements + * @param AbstractHtmlNodeProcessor $htmlNodeProcessor node processor instance */ - public function process(array $elements, HtmlNodeProcessor $htmlNodeProcessor); + public function process(array $elements, AbstractHtmlNodeProcessor $htmlNodeProcessor); + /** + * Replaces a placeholder tag with the provided data. + * + * @param array $data replacement data + */ public function replaceTag(array $data); } diff --git a/wcfsetup/install/files/lib/system/html/node/IHtmlNodeProcessor.class.php b/wcfsetup/install/files/lib/system/html/node/IHtmlNodeProcessor.class.php index 0d428a0a35..133b4b2fad 100644 --- a/wcfsetup/install/files/lib/system/html/node/IHtmlNodeProcessor.class.php +++ b/wcfsetup/install/files/lib/system/html/node/IHtmlNodeProcessor.class.php @@ -2,15 +2,38 @@ namespace wcf\system\html\node; /** - * @since 3.0 + * Default interface for html node processors. + * + * @author Alexander Ebert + * @copyright 2001-2016 WoltLab GmbH + * @license GNU Lesser General Public License + * @package WoltLabSuite\Core\System\Html\Node + * @since 3.0 */ interface IHtmlNodeProcessor { /** - * @return \DOMDocument + * Returns the currently loaded DOM document. + * + * @return \DOMDocument active DOM document */ public function getDocument(); + /** + * Returns the final HTML for storage or display. + * + * @return string parsed HTML + */ public function getHtml(); + /** + * Loads a HTML string for processing. + * + * @param string $html HTML string + */ public function load($html); + + /** + * Processes the HTML and transforms it depending on the output type. + */ + public function process(); } diff --git a/wcfsetup/install/files/lib/system/html/output/node/HtmlOutputNodeBlockquote.class.php b/wcfsetup/install/files/lib/system/html/output/node/HtmlOutputNodeBlockquote.class.php index 83a7744f03..d1fdea2009 100644 --- a/wcfsetup/install/files/lib/system/html/output/node/HtmlOutputNodeBlockquote.class.php +++ b/wcfsetup/install/files/lib/system/html/output/node/HtmlOutputNodeBlockquote.class.php @@ -2,23 +2,31 @@ namespace wcf\system\html\output\node; use wcf\system\application\ApplicationHandler; use wcf\system\html\node\AbstractHtmlNode; -use wcf\system\html\node\HtmlNodeProcessor; +use wcf\system\html\node\AbstractHtmlNodeProcessor; use wcf\system\message\embedded\object\MessageEmbeddedObjectManager; use wcf\system\request\RouteHandler; use wcf\system\WCF; use wcf\util\StringUtil; /** - * TOOD documentation - * @since 3.0 + * Processes quotes. + * + * @author Alexander Ebert + * @copyright 2001-2016 WoltLab GmbH + * @license GNU Lesser General Public License + * @package WoltLabSuite\Core\System\Html\Output\Node + * @since 3.0 */ class HtmlOutputNodeBlockquote extends AbstractHtmlNode { + /** + * @inheritDoc + */ protected $tagName = 'blockquote'; /** * @inheritDoc */ - public function process(array $elements, HtmlNodeProcessor $htmlNodeProcessor) { + public function process(array $elements, AbstractHtmlNodeProcessor $htmlNodeProcessor) { /** @var \DOMElement $element */ foreach ($elements as $element) { $nodeIdentifier = StringUtil::getRandomID(); @@ -31,6 +39,9 @@ class HtmlOutputNodeBlockquote extends AbstractHtmlNode { } } + /** + * @inheritDoc + */ public function replaceTag(array $data) { $externalQuoteLink = (!empty($data['url'])) ? !ApplicationHandler::getInstance()->isInternalURL($data['url']) : false; if (!$externalQuoteLink) { diff --git a/wcfsetup/install/files/lib/system/html/output/node/HtmlOutputNodePre.class.php b/wcfsetup/install/files/lib/system/html/output/node/HtmlOutputNodePre.class.php index 25f74548ce..79184f5bb9 100644 --- a/wcfsetup/install/files/lib/system/html/output/node/HtmlOutputNodePre.class.php +++ b/wcfsetup/install/files/lib/system/html/output/node/HtmlOutputNodePre.class.php @@ -14,16 +14,24 @@ use wcf\system\bbcode\highlighter\SqlHighlighter; use wcf\system\bbcode\highlighter\TexHighlighter; use wcf\system\bbcode\highlighter\XmlHighlighter; use wcf\system\html\node\AbstractHtmlNode; -use wcf\system\html\node\HtmlNodeProcessor; +use wcf\system\html\node\AbstractHtmlNodeProcessor; use wcf\system\Regex; use wcf\system\WCF; use wcf\util\StringUtil; /** - * TOOD documentation - * @since 3.0 + * Processes code listings. + * + * @author Alexander Ebert + * @copyright 2001-2016 WoltLab GmbH + * @license GNU Lesser General Public License + * @package WoltLabSuite\Core\System\Html\Output\Node + * @since 3.0 */ class HtmlOutputNodePre extends AbstractHtmlNode { + /** + * @inheritDoc + */ protected $tagName = 'pre'; /** @@ -35,7 +43,7 @@ class HtmlOutputNodePre extends AbstractHtmlNode { /** * @inheritDoc */ - public function process(array $elements, HtmlNodeProcessor $htmlNodeProcessor) { + public function process(array $elements, AbstractHtmlNodeProcessor $htmlNodeProcessor) { /** @var \DOMElement $element */ foreach ($elements as $element) { $nodeIdentifier = StringUtil::getRandomID(); @@ -50,6 +58,9 @@ class HtmlOutputNodePre extends AbstractHtmlNode { } } + /** + * @inheritDoc + */ public function replaceTag(array $data) { $content = preg_replace('/^\s*\n/', '', $data['content']); $content = preg_replace('/\n\s*$/', '', $content); 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 8648ffdac5..015203c176 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 @@ -1,21 +1,24 @@ + * @package WoltLabSuite\Core\System\Html\Output\Node + * @since 3.0 */ -class HtmlOutputNodeProcessor extends HtmlNodeProcessor { +class HtmlOutputNodeProcessor extends AbstractHtmlNodeProcessor { + /** + * @inheritDoc + */ public function process() { $this->invokeHtmlNode(new HtmlOutputNodeWoltlabMetacode()); - // TODO: this should be dynamic to some extent - $this->invokeHtmlNode(new HtmlOutputNodeBlockquote()); - $this->invokeHtmlNode(new HtmlOutputNodeWoltlabMention()); - $this->invokeHtmlNode(new HtmlOutputNodeWoltlabColor()); - $this->invokeHtmlNode(new HtmlOutputNodeWoltlabSize()); - $this->invokeHtmlNode(new HtmlOutputNodeWoltlabSpoiler()); - $this->invokeHtmlNode(new HtmlOutputNodePre()); + // dynamic node handlers + $this->invokeNodeHandlers('wcf\system\html\output\node\HtmlOutputNode', ['woltlab-metacode']); } } diff --git a/wcfsetup/install/files/lib/system/html/output/node/HtmlOutputNodeWoltlabColor.class.php b/wcfsetup/install/files/lib/system/html/output/node/HtmlOutputNodeWoltlabColor.class.php index 9b45a1febb..f6829e093d 100644 --- a/wcfsetup/install/files/lib/system/html/output/node/HtmlOutputNodeWoltlabColor.class.php +++ b/wcfsetup/install/files/lib/system/html/output/node/HtmlOutputNodeWoltlabColor.class.php @@ -1,20 +1,28 @@ + * @package WoltLabSuite\Core\System\Html\Output\Node + * @since 3.0 */ class HtmlOutputNodeWoltlabColor extends AbstractHtmlNode { + /** + * @inheritDoc + */ protected $tagName = 'woltlab-color'; /** * @inheritDoc */ - public function process(array $elements, HtmlNodeProcessor $htmlNodeProcessor) { + public function process(array $elements, AbstractHtmlNodeProcessor $htmlNodeProcessor) { /** @var \DOMElement $element */ foreach ($elements as $element) { // parse color @@ -29,6 +37,9 @@ class HtmlOutputNodeWoltlabColor extends AbstractHtmlNode { } } + /** + * @inheritDoc + */ public function replaceTag(array $data) { return '' . self::PLACEHOLDER . ''; } diff --git a/wcfsetup/install/files/lib/system/html/output/node/HtmlOutputNodeWoltlabMention.class.php b/wcfsetup/install/files/lib/system/html/output/node/HtmlOutputNodeWoltlabMention.class.php index 7ecc86b4db..e2821b253e 100644 --- a/wcfsetup/install/files/lib/system/html/output/node/HtmlOutputNodeWoltlabMention.class.php +++ b/wcfsetup/install/files/lib/system/html/output/node/HtmlOutputNodeWoltlabMention.class.php @@ -3,16 +3,24 @@ namespace wcf\system\html\output\node; use wcf\data\user\UserProfile; use wcf\system\cache\runtime\UserProfileRuntimeCache; use wcf\system\html\node\AbstractHtmlNode; -use wcf\system\html\node\HtmlNodeProcessor; +use wcf\system\html\node\AbstractHtmlNodeProcessor; use wcf\system\WCF; use wcf\util\DOMUtil; use wcf\util\StringUtil; /** - * TOOD documentation - * @since 3.0 + * Processes user mentions. + * + * @author Alexander Ebert + * @copyright 2001-2016 WoltLab GmbH + * @license GNU Lesser General Public License + * @package WoltLabSuite\Core\System\Html\Output\Node + * @since 3.0 */ class HtmlOutputNodeWoltlabMention extends AbstractHtmlNode { + /** + * @inheritDoc + */ protected $tagName = 'woltlab-mention'; /** @@ -23,10 +31,11 @@ class HtmlOutputNodeWoltlabMention extends AbstractHtmlNode { /** * @inheritDoc */ - public function process(array $elements, HtmlNodeProcessor $htmlNodeProcessor) { + public function process(array $elements, AbstractHtmlNodeProcessor $htmlNodeProcessor) { $this->userProfiles = []; $userIds = []; + /** @var \DOMElement $element */ foreach ($elements as $element) { $userId = ($element->hasAttribute('data-user-id')) ? intval($element->getAttribute('data-user-id')) : 0; $username = ($element->hasAttribute('data-username')) ? StringUtil::trim($element->getAttribute('data-username')) : ''; @@ -51,6 +60,9 @@ class HtmlOutputNodeWoltlabMention extends AbstractHtmlNode { } } + /** + * @inheritDoc + */ public function replaceTag(array $data) { WCF::getTPL()->assign([ 'username' => $data['username'], 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 index b2cfffe8c4..98a2df63e1 100644 --- a/wcfsetup/install/files/lib/system/html/output/node/HtmlOutputNodeWoltlabMetacode.class.php +++ b/wcfsetup/install/files/lib/system/html/output/node/HtmlOutputNodeWoltlabMetacode.class.php @@ -2,20 +2,28 @@ 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\system\html\node\AbstractHtmlNodeProcessor; use wcf\util\StringUtil; /** - * TOOD documentation - * @since 3.0 + * Processes bbcodes represented by ``. + * + * @author Alexander Ebert + * @copyright 2001-2016 WoltLab GmbH + * @license GNU Lesser General Public License + * @package WoltLabSuite\Core\System\Html\Output\Node + * @since 3.0 */ class HtmlOutputNodeWoltlabMetacode extends AbstractHtmlNode { + /** + * @inheritDoc + */ protected $tagName = 'woltlab-metacode'; /** * @inheritDoc */ - public function process(array $elements, HtmlNodeProcessor $htmlNodeProcessor) { + public function process(array $elements, AbstractHtmlNodeProcessor $htmlNodeProcessor) { /** @var \DOMElement $element */ foreach ($elements as $element) { $name = $element->getAttribute('data-name'); @@ -31,6 +39,9 @@ class HtmlOutputNodeWoltlabMetacode extends AbstractHtmlNode { } } + /** + * @inheritDoc + */ public function replaceTag(array $data) { return HtmlBBCodeParser::getInstance()->getHtmlOutput($data['name'], $data['attributes']); } diff --git a/wcfsetup/install/files/lib/system/html/output/node/HtmlOutputNodeWoltlabSize.class.php b/wcfsetup/install/files/lib/system/html/output/node/HtmlOutputNodeWoltlabSize.class.php index 168475c358..094d96f7a5 100644 --- a/wcfsetup/install/files/lib/system/html/output/node/HtmlOutputNodeWoltlabSize.class.php +++ b/wcfsetup/install/files/lib/system/html/output/node/HtmlOutputNodeWoltlabSize.class.php @@ -1,20 +1,28 @@ + * @package WoltLabSuite\Core\System\Html\Output\Node + * @since 3.0 */ class HtmlOutputNodeWoltlabSize extends AbstractHtmlNode { + /** + * @inheritDoc + */ protected $tagName = 'woltlab-size'; /** * @inheritDoc */ - public function process(array $elements, HtmlNodeProcessor $htmlNodeProcessor) { + public function process(array $elements, AbstractHtmlNodeProcessor $htmlNodeProcessor) { /** @var \DOMElement $element */ foreach ($elements as $element) { // parse color @@ -29,6 +37,9 @@ class HtmlOutputNodeWoltlabSize extends AbstractHtmlNode { } } + /** + * @inheritDoc + */ public function replaceTag(array $data) { return '' . self::PLACEHOLDER . ''; } diff --git a/wcfsetup/install/files/lib/system/html/output/node/HtmlOutputNodeWoltlabSpoiler.class.php b/wcfsetup/install/files/lib/system/html/output/node/HtmlOutputNodeWoltlabSpoiler.class.php index 921099da7e..982172626c 100644 --- a/wcfsetup/install/files/lib/system/html/output/node/HtmlOutputNodeWoltlabSpoiler.class.php +++ b/wcfsetup/install/files/lib/system/html/output/node/HtmlOutputNodeWoltlabSpoiler.class.php @@ -1,23 +1,29 @@ + * @package WoltLabSuite\Core\System\Html\Output\Node + * @since 3.0 */ class HtmlOutputNodeWoltlabSpoiler extends AbstractHtmlNode { + /** + * @inheritDoc + */ protected $tagName = 'woltlab-spoiler'; /** * @inheritDoc */ - public function process(array $elements, HtmlNodeProcessor $htmlNodeProcessor) { + public function process(array $elements, AbstractHtmlNodeProcessor $htmlNodeProcessor) { /** @var \DOMElement $element */ foreach ($elements as $element) { $nodeIdentifier = StringUtil::getRandomID(); @@ -29,6 +35,9 @@ class HtmlOutputNodeWoltlabSpoiler extends AbstractHtmlNode { } } + /** + * @inheritDoc + */ public function replaceTag(array $data) { WCF::getTPL()->assign([ 'buttonLabel' => $data['label'] diff --git a/wcfsetup/install/files/lib/system/html/output/node/IHtmlOutputNode.class.php b/wcfsetup/install/files/lib/system/html/output/node/IHtmlOutputNode.class.php index e8e34f64ab..1dd8700bdd 100644 --- a/wcfsetup/install/files/lib/system/html/output/node/IHtmlOutputNode.class.php +++ b/wcfsetup/install/files/lib/system/html/output/node/IHtmlOutputNode.class.php @@ -3,7 +3,12 @@ namespace wcf\system\html\output\node; use wcf\system\html\node\IHtmlNode; /** - * TOOD documentation - * @since 3.0 + * Default interface for html output nodes. + * + * @author Alexander Ebert + * @copyright 2001-2016 WoltLab GmbH + * @license GNU Lesser General Public License + * @package WoltLabSuite\Core\System\Html\Output\Node + * @since 3.0 */ interface IHtmlOutputNode extends IHtmlNode {}