From f27e5de274599479de02a5f1ca5054942c6f0131 Mon Sep 17 00:00:00 2001 From: Alexander Ebert Date: Tue, 28 Jun 2016 10:23:40 +0200 Subject: [PATCH] Added proper support for simplified-html/plain --- com.woltlab.wcf/templates/spoilerMetaCode.tpl | 44 +++++++------ .../files/js/WoltLab/WCF/Ajax/Request.js | 16 ++--- .../node/AbstractHtmlNodeProcessor.class.php | 14 ++++- .../node/HtmlOutputNodeBlockquote.class.php | 3 +- .../output/node/HtmlOutputNodePre.class.php | 10 ++- .../node/HtmlOutputNodeProcessor.class.php | 62 +++++++++++++++++++ .../HtmlOutputNodeWoltlabMention.class.php | 2 +- .../HtmlOutputNodeWoltlabSpoiler.class.php | 17 ++--- .../install/files/lib/util/DOMUtil.class.php | 2 +- wcfsetup/install/lang/de.xml | 1 + wcfsetup/install/lang/en.xml | 1 + 11 files changed, 125 insertions(+), 47 deletions(-) diff --git a/com.woltlab.wcf/templates/spoilerMetaCode.tpl b/com.woltlab.wcf/templates/spoilerMetaCode.tpl index 74671a2941..cfe2a5e349 100644 --- a/com.woltlab.wcf/templates/spoilerMetaCode.tpl +++ b/com.woltlab.wcf/templates/spoilerMetaCode.tpl @@ -1,4 +1,3 @@ -
{if $buttonLabel}{$buttonLabel}{else}{lang}wcf.bbcode.spoiler.show{/lang}{/if} @@ -7,28 +6,27 @@
-
- -{if !$__wcfSpoilerBBCodeJavaScript|isset} - {assign var='__wcfSpoilerBBCodeJavaScript' value=true} - -{/if} - + + {/if} + diff --git a/wcfsetup/install/files/js/WoltLab/WCF/Ajax/Request.js b/wcfsetup/install/files/js/WoltLab/WCF/Ajax/Request.js index 627cac6d53..22f618fe4c 100644 --- a/wcfsetup/install/files/js/WoltLab/WCF/Ajax/Request.js +++ b/wcfsetup/install/files/js/WoltLab/WCF/Ajax/Request.js @@ -24,12 +24,12 @@ define(['Core', 'Language', 'Dom/ChangeListener', 'Dom/Util', 'Ui/Dialog', 'Wolt this._xhr = null; this._init(options); - }; + } AjaxRequest.prototype = { /** * Initializes the request options. * - * @param {object} options request options + * @param {Object} options request options */ _init: function(options) { this._options = Core.extend({ @@ -168,7 +168,7 @@ define(['Core', 'Language', 'Dom/ChangeListener', 'Dom/Util', 'Ui/Dialog', 'Wolt * Sets a specific option. * * @param {string} key option name - * @param {*} value option value + * @param {?} value option value */ setOption: function(key, value) { this._options[key] = value; @@ -191,7 +191,7 @@ define(['Core', 'Language', 'Dom/ChangeListener', 'Dom/Util', 'Ui/Dialog', 'Wolt /** * Sets request data while honoring pinned data from setup callback. * - * @param {object} data request data + * @param {Object} data request data */ setData: function(data) { if (this._data !== null && Core.getType(data) !== 'FormData') { @@ -205,7 +205,7 @@ define(['Core', 'Language', 'Dom/ChangeListener', 'Dom/Util', 'Ui/Dialog', 'Wolt * Handles a successful request. * * @param {XMLHttpRequest} xhr request object - * @param {object} options request options + * @param {Object} options request options */ _success: function(xhr, options) { if (!options.silent) { @@ -242,7 +242,7 @@ define(['Core', 'Language', 'Dom/ChangeListener', 'Dom/Util', 'Ui/Dialog', 'Wolt * a non-success status code or an entirely failed request. * * @param {XMLHttpRequest} xhr request object - * @param {object} options request options + * @param {Object} options request options */ _failure: function (xhr, options) { if (_ignoreAllErrors) { @@ -260,7 +260,7 @@ define(['Core', 'Language', 'Dom/ChangeListener', 'Dom/Util', 'Ui/Dialog', 'Wolt catch (e) {} var showError = true; - if (typeof options.failure === 'function') { + if (data !== null && typeof options.failure === 'function') { showError = options.failure(data, xhr.responseText, xhr, options.data); } @@ -296,7 +296,7 @@ define(['Core', 'Language', 'Dom/ChangeListener', 'Dom/Util', 'Ui/Dialog', 'Wolt /** * Finalizes a request. * - * @param {object} options request options + * @param {Object} options request options */ _finalize: function(options) { if (typeof options.finalize === 'function') { diff --git a/wcfsetup/install/files/lib/system/html/node/AbstractHtmlNodeProcessor.class.php b/wcfsetup/install/files/lib/system/html/node/AbstractHtmlNodeProcessor.class.php index 8c757d32ba..0d9be92cf2 100644 --- a/wcfsetup/install/files/lib/system/html/node/AbstractHtmlNodeProcessor.class.php +++ b/wcfsetup/install/files/lib/system/html/node/AbstractHtmlNodeProcessor.class.php @@ -2,6 +2,7 @@ namespace wcf\system\html\node; use wcf\system\exception\SystemException; use wcf\system\html\IHtmlProcessor; +use wcf\util\DOMUtil; use wcf\util\JSON; /** @@ -134,11 +135,20 @@ abstract class AbstractHtmlNodeProcessor implements IHtmlNodeProcessor { * Replaces an element with plain text. * * @param \DOMElement $element target element - * @param string $text text used to replace target element + * @param string $text text used to replace target + * @param boolean $isBlockElement true if element is a block element */ - public function replaceElementWithText(\DOMElement $element, $text) { + public function replaceElementWithText(\DOMElement $element, $text, $isBlockElement) { $textNode = $element->ownerDocument->createTextNode($text); $element->parentNode->insertBefore($textNode, $element); + + if ($isBlockElement) { + for ($i = 0; $i < 2; $i++) { + $br = $element->ownerDocument->createElement('br'); + $element->parentNode->insertBefore($br, $element); + } + } + $element->parentNode->removeChild($element); } 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 5ffc96d3a7..9e5e15497f 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 @@ -49,7 +49,8 @@ class HtmlOutputNodeBlockquote extends AbstractHtmlOutputNode { else { $htmlNodeProcessor->replaceElementWithText( $element, - WCF::getLanguage()->getDynamicVariable('wcf.bbcode.quote.simplified', ['cite' => $element->getAttribute('data-author')])."\n" + WCF::getLanguage()->getDynamicVariable('wcf.bbcode.quote.simplified', ['cite' => $element->getAttribute('data-author')]), + true ); } break; 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 95d4c94d37..3cca230328 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 @@ -50,8 +50,8 @@ class HtmlOutputNodePre extends AbstractHtmlOutputNode { $nodeIdentifier = StringUtil::getRandomID(); $htmlNodeProcessor->addNodeData($this, $nodeIdentifier, [ 'content' => $element->textContent, - 'file' => ($element->hasAttribute('data-file')) ? $element->getAttribute('data-file') : '', - 'highlighter' => ($element->hasAttribute('data-highlighter')) ? $element->getAttribute('data-highlighter') : '', + 'file' => $element->getAttribute('data-file'), + 'highlighter' => $element->getAttribute('data-highlighter'), 'line' => ($element->hasAttribute('data-line')) ? $element->getAttribute('data-line') : 1 ]); @@ -60,7 +60,11 @@ class HtmlOutputNodePre extends AbstractHtmlOutputNode { case 'text/simplified-html': case 'text/plain': - return WCF::getLanguage()->getDynamicVariable('wcf.bbcode.code.simplified', ['lines' => substr_count($element->nodeValue, "\n") + 1]); + $htmlNodeProcessor->replaceElementWithText( + $element, + WCF::getLanguage()->getDynamicVariable('wcf.bbcode.code.simplified', ['lines' => substr_count($element->nodeValue, "\n") + 1]), + true + ); break; } } 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 cf0adb66cc..175ea2884f 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 @@ -2,6 +2,8 @@ namespace wcf\system\html\output\node; use wcf\system\html\node\AbstractHtmlNodeProcessor; use wcf\system\html\node\IHtmlNode; +use wcf\util\DOMUtil; +use wcf\util\StringUtil; /** * Processes a HTML string and renders the final output for display. @@ -41,6 +43,66 @@ class HtmlOutputNodeProcessor extends AbstractHtmlNodeProcessor { // dynamic node handlers $this->invokeNodeHandlers('wcf\system\html\output\node\HtmlOutputNode', ['woltlab-metacode']); + + if ($this->outputType !== 'text/html') { + // convert `

...

` into `...

` + $paragraphs = $this->getDocument()->getElementsByTagName('p'); + while ($paragraphs->length) { + $paragraph = $paragraphs->item(0); + + for ($i = 0; $i < 2; $i++) { + $br = $this->getDocument()->createElement('br'); + $paragraph->appendChild($br); + } + + DOMUtil::removeNode($paragraph, true); + } + + if ($this->outputType === 'text/plain') { + // remove all `\n` first + $nodes = []; + /** @var \DOMText $node */ + foreach ($this->getXPath()->query('//text()') as $node) { + if (strpos($node->textContent, "\n") !== false) { + $nodes[] = $node; + } + } + foreach ($nodes as $node) { + $textNode = $this->getDocument()->createTextNode(preg_replace('~\r?\n~', '', $node->textContent)); + $node->parentNode->insertBefore($textNode, $node); + $node->parentNode->removeChild($node); + } + + // convert `
` into `\n` + $brs = $this->getDocument()->getElementsByTagName('br'); + while ($brs->length) { + $br = $brs->item(0); + + $newline = $this->getDocument()->createTextNode("\n"); + $br->parentNode->insertBefore($newline, $br); + DOMUtil::removeNode($br); + } + + // remove all other elements + $elements = $this->getDocument()->getElementsByTagName('*'); + while ($elements->length) { + DOMUtil::removeNode($elements->item(0), true); + } + } + } + } + + /** + * @inheritDoc + */ + public function getHtml() { + $html = parent::getHtml(); + + if ($this->outputType === 'text/plain') { + $html = StringUtil::trim($html); + } + + return $html; } /** 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 3ae4183a50..d580e7ae05 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 @@ -59,7 +59,7 @@ class HtmlOutputNodeWoltlabMention extends AbstractHtmlOutputNode { else if ($this->outputType === 'text/plain') { /** @var \DOMElement $element */ foreach ($elements as $element) { - $htmlNodeProcessor->replaceElementWithText($element, '@' . $element->getAttribute('data-username')); + $htmlNodeProcessor->replaceElementWithText($element, '@' . $element->getAttribute('data-username'), false); } } } 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 2305900c0a..3e75dfaba2 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 @@ -24,19 +24,20 @@ class HtmlOutputNodeWoltlabSpoiler extends AbstractHtmlOutputNode { * @inheritDoc */ public function process(array $elements, AbstractHtmlNodeProcessor $htmlNodeProcessor) { - if ($this->outputType === 'text/html' || $this->outputType === 'text/simplified-html') { - /** @var \DOMElement $element */ - foreach ($elements as $element) { + /** @var \DOMElement $element */ + foreach ($elements as $element) { + if ($this->outputType === 'text/html') { $nodeIdentifier = StringUtil::getRandomID(); $htmlNodeProcessor->addNodeData($this, $nodeIdentifier, ['label' => $element->getAttribute('data-label')]); $htmlNodeProcessor->renameTag($element, 'wcfNode-' . $nodeIdentifier); } - } - else if ($this->outputType === 'text/plain') { - /** @var \DOMElement $element */ - foreach ($elements as $element) { - DOMUtil::removeNode($element); + else if ($this->outputType === 'text/simplified-html' || $this->outputType === 'text/plain') { + $htmlNodeProcessor->replaceElementWithText( + $element, + WCF::getLanguage()->getDynamicVariable('wcf.bbcode.spoiler.simplified', ['label' => $element->getAttribute('data-label')]), + true + ); } } } diff --git a/wcfsetup/install/files/lib/util/DOMUtil.class.php b/wcfsetup/install/files/lib/util/DOMUtil.class.php index c255353bad..c844c248f8 100644 --- a/wcfsetup/install/files/lib/util/DOMUtil.class.php +++ b/wcfsetup/install/files/lib/util/DOMUtil.class.php @@ -181,7 +181,7 @@ final class DOMUtil { * * @param \DOMElement $element start element * @param string $tagName tag name to match - * @return boolean true if there is at least one parent with the provided tag name + * @return boolean */ public static function hasParent(\DOMElement $element, $tagName) { while ($element = $element->parentNode) { diff --git a/wcfsetup/install/lang/de.xml b/wcfsetup/install/lang/de.xml index abcc640084..3444537bfc 100644 --- a/wcfsetup/install/lang/de.xml +++ b/wcfsetup/install/lang/de.xml @@ -1882,6 +1882,7 @@ Erlaubte Dateiendungen: {', '|implode:$attachmentHandler->getFormattedAllowedExt + diff --git a/wcfsetup/install/lang/en.xml b/wcfsetup/install/lang/en.xml index a5a1634239..3676669a74 100644 --- a/wcfsetup/install/lang/en.xml +++ b/wcfsetup/install/lang/en.xml @@ -1863,6 +1863,7 @@ Allowed extensions: {', '|implode:$attachmentHandler->getFormattedAllowedExtensi + -- 2.20.1