diff --git a/lib/Parser/Serializer.php b/lib/Parser/Serializer.php index af69f4a..78103b5 100644 --- a/lib/Parser/Serializer.php +++ b/lib/Parser/Serializer.php @@ -131,66 +131,68 @@ abstract class Serializer { if ($reformatWhitespace) { $modify = false; - $preformattedContent = $preformattedContent ?: static::isPreformattedContent($node); - // If the node is an HTML element... - if ($htmlElement) { - // If the element's parent is to be treated as block then we need to modify - // whitespace. - if (!$first && self::treatAsBlock($node->parentNode)) { - $modify = true; + $preformattedContent = $preformattedContent ?: static::isPreformattedContent($node); + if (!$preformattedContent || in_array($node->tagName, self::PREFORMATTED_ELEMENTS)) { + // If the node is an HTML element... + if ($htmlElement) { + // If the element's parent is to be treated as block then we need to modify + // whitespace. + if (!$first && self::treatAsBlock($node->parentNode)) { + $modify = true; + } } - } - // If the node is not an HTML element... - elseif ($foreignAsBlock) { - $modify = true; - } else { - // If the parent node is null then we need to modify whitespace; this means that - // it is the element itself that is being serialized. Foreign content without - // any context is printed as "block" content. - // If a foreign element with an html element parent and the foreign element - // should be treated as block then we also need to modify whitespace. - if ($node->parentNode === null) { + // If the node is not an HTML element... + elseif ($foreignAsBlock) { $modify = true; - $foreignAsBlock = true; - } elseif (($node->parentNode->namespaceURI ?? Parser::HTML_NAMESPACE) === Parser::HTML_NAMESPACE) { - if (self::treatAsBlock($node->parentNode)) { + } else { + // If the parent node is null then we need to modify whitespace; this means that + // it is the element itself that is being serialized. Foreign content without + // any context is printed as "block" content. + // If a foreign element with an html element parent and the foreign element + // should be treated as block then we also need to modify whitespace. + if ($node->parentNode === null) { + $modify = true; + $foreignAsBlock = true; + } elseif (($node->parentNode->namespaceURI ?? Parser::HTML_NAMESPACE) === Parser::HTML_NAMESPACE) { + if (self::treatAsBlock($node->parentNode)) { + $modify = true; + $foreignAsBlock = true; + } + } + // Otherwise, if the node's parent is not an HTML element then moonwalk up + // the tree until the root foreign node is found, and if it is to be treated + // as block then we need to modify whitespace. This should only match when + // printing non-root foreign elements themselves while also being appended to + // the document. + // TODO: Figure out how to make this not fire on every single "inline" svg + // element. + elseif (static::treatForeignRootAsBlock($node->parentNode)) { $modify = true; $foreignAsBlock = true; } } - // Otherwise, if the node's parent is not an HTML element then moonwalk up - // the tree until the root foreign node is found, and if it is to be treated - // as block then we need to modify whitespace. This should only match when - // printing non-root foreign elements themselves while also being appended to - // the document. - // TODO: Figure out how to make this not fire on every single "inline" svg - // element. - elseif (static::treatForeignRootAsBlock($node->parentNode)) { - $modify = true; - $foreignAsBlock = true; - } - } - // Only modify here before printing the open tag if it's not the first element - // printed. Above whether to modify is still partially calculated because if - // printing just foreign nodes the foreignAsBlock flag needs to be set for any - // descendants. - if (!$first && $modify) { - // If the previous non text or non document type node sibling doesn't have the - // same name as the current node and neither are h1-h6 elements then add an - // additional newline. This causes like elements to be grouped together. - $n = $node; - while ($n = $n->previousSibling) { - if (!$n instanceof \DOMText) { - if ((!$n instanceof \DOMElement && !$n instanceof \DOMDocumentType) || ($n instanceof \DOMElement && $n->tagName !== $tagName && count(array_intersect([ $n->tagName, $tagName ], self::H_ELEMENTS)) !== 2)) { - $s .= "\n"; + // Only modify here before printing the open tag if it's not the first element + // printed. Above whether to modify is still partially calculated because if + // printing just foreign nodes the foreignAsBlock flag needs to be set for any + // descendants. + if (!$first && $modify) { + // If the previous non text or non document type node sibling doesn't have the + // same name as the current node and neither are h1-h6 elements then add an + // additional newline. This causes like elements to be grouped together. + $n = $node; + while ($n = $n->previousSibling) { + if (!$n instanceof \DOMText) { + if ((!$n instanceof \DOMElement && !$n instanceof \DOMDocumentType) || ($n instanceof \DOMElement && $n->tagName !== $tagName && count(array_intersect([ $n->tagName, $tagName ], self::H_ELEMENTS)) !== 2)) { + $s .= "\n"; + } + break; } - break; } - } - $s .= "\n" . str_repeat($indentChar, $indentionLevel * $indentStep); + $s .= "\n" . str_repeat($indentChar, $indentionLevel * $indentStep); + } } // Disable whitespace reformatting when the content is preformatted.