From 679aa1b6d12309f095901dfcd0dcbc1ecbd6c82e Mon Sep 17 00:00:00 2001 From: Cyperghost Date: Wed, 17 Jan 2024 13:29:50 +0100 Subject: [PATCH] Detect links in one line alone --- .../node/HtmlInputNodeProcessor.class.php | 35 +++++++++++++++++++ .../html/node/HtmlNodePlainLink.class.php | 12 ++++--- .../html/node/HtmlNodeUnfurlLink.class.php | 3 ++ 3 files changed, 45 insertions(+), 5 deletions(-) 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 75c73b1340..014b8c7c27 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 @@ -819,6 +819,30 @@ class HtmlInputNodeProcessor extends AbstractHtmlNodeProcessor $this->plainLinks[] = $plainLink->setIsStandalone($parent); continue; } + } elseif ($parent->nodeName === 'p') { + $nextSibling = $this->getNoneEmptyNode($link, 'nextSibling'); + $previousSibling = $this->getNoneEmptyNode($link, 'previousSibling'); + + //Check whether the link is at the beginning or end of the paragraph + //and whether the next or previous sibling is a line break. + //

https://example.com
…

+ //

…
https://example.com

+ if ( + ($nextSibling === null && $previousSibling !== null && $previousSibling->nodeName === 'br') || + ($previousSibling === null && $nextSibling !== null && $nextSibling->nodeName === 'br') + ) { + $this->plainLinks[] = $plainLink->setIsStandalone(); + continue; + } + //If not, the previous and next sibling may be a line break. + //

…
https://example.com
…

+ if ( + $previousSibling !== null && $previousSibling->nodeName === 'br' && + $nextSibling !== null && $nextSibling->nodeName === 'br' + ) { + $this->plainLinks[] = $plainLink->setIsStandalone(); + continue; + } } $this->plainLinks[] = $plainLink->setIsInline(); @@ -835,4 +859,15 @@ class HtmlInputNodeProcessor extends AbstractHtmlNodeProcessor } } } + + private function getNoneEmptyNode(?\DOMNode $element, string $property): ?\DOMNode + { + while ($element = $element->{$property}) { + if (!DOMUtil::isEmpty($element)) { + return $element; + } + } + + return null; + } } diff --git a/wcfsetup/install/files/lib/system/html/node/HtmlNodePlainLink.class.php b/wcfsetup/install/files/lib/system/html/node/HtmlNodePlainLink.class.php index 7b75ccf938..a7dca6b8df 100644 --- a/wcfsetup/install/files/lib/system/html/node/HtmlNodePlainLink.class.php +++ b/wcfsetup/install/files/lib/system/html/node/HtmlNodePlainLink.class.php @@ -77,10 +77,10 @@ class HtmlNodePlainLink /** * Marks the link as standalone, which means that it is the only content in a line. * - * @param \DOMElement $topLevelParent + * @param \DOMElement|null $topLevelParent * @return $this */ - public function setIsStandalone(\DOMElement $topLevelParent) + public function setIsStandalone(?\DOMElement $topLevelParent = null) { $this->standalone = true; $this->topLevelParent = $topLevelParent; @@ -171,9 +171,11 @@ class HtmlNodePlainLink throw new \LogicException('Cannot inject a block bbcode in an inline context.'); } - // Replace the top level parent with the link itself, which will be replaced with the bbcode afterwards. - $this->topLevelParent->parentNode->insertBefore($this->link, $this->topLevelParent); - DOMUtil::removeNode($this->topLevelParent); + if ($this->topLevelParent !== null) { + // Replace the top level parent with the link itself, which will be replaced with the bbcode afterwards. + $this->topLevelParent->parentNode->insertBefore($this->link, $this->topLevelParent); + DOMUtil::removeNode($this->topLevelParent); + } } DOMUtil::replaceElement($this->link, $metacodeElement, false); diff --git a/wcfsetup/install/files/lib/system/html/node/HtmlNodeUnfurlLink.class.php b/wcfsetup/install/files/lib/system/html/node/HtmlNodeUnfurlLink.class.php index ba65283fdb..1c71ed2c46 100644 --- a/wcfsetup/install/files/lib/system/html/node/HtmlNodeUnfurlLink.class.php +++ b/wcfsetup/install/files/lib/system/html/node/HtmlNodeUnfurlLink.class.php @@ -57,6 +57,9 @@ class HtmlNodeUnfurlLink extends HtmlNodePlainLink private static function removeStyling(HtmlNodePlainLink $element): void { + if ($element->topLevelParent == null) { + return; + } foreach ($element->topLevelParent->childNodes as $child) { DOMUtil::removeNode($child); } -- 2.20.1