Browse Source

Cleaning up

ns
Dustin Wilson 3 years ago
parent
commit
9177ed6074
  1. 105
      lib/DOM/Document.php
  2. 11
      lib/DOM/ElementMap.php
  3. 22
      lib/DOM/traits/Moonwalk.php
  4. 14
      lib/DOM/traits/MoonwalkShallow.php
  5. 4
      lib/DOM/traits/Walk.php
  6. 4
      lib/DOM/traits/WalkShallow.php

105
lib/DOM/Document.php

@ -20,7 +20,7 @@ class Document extends AbstractDocument {
protected $_body = null;
// List of elements that are treated as block elements for the purposes of
// output formatting when serializing
protected const BLOCK_ELEMENTS = [ 'address', 'article', 'aside', 'blockquote', 'base', 'body', 'details', 'dialog', 'dd', 'div', 'dl', 'dt', 'fieldset', 'figcaption', 'figure', 'footer', 'form', 'frame', 'frameset', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'header', 'hr', 'html', 'isindex', 'li', 'link', 'main', 'meta', 'nav', 'ol', 'p', 'pre', 'section', 'script', 'source', 'style', 'table', 'template', 'td', 'tfoot', 'th', 'thead', 'title', 'tr', 'ul' ];
protected const BLOCK_ELEMENTS = [ 'address', 'article', 'aside', 'blockquote', 'base', 'body', 'details', 'dialog', 'dd', 'div', 'dl', 'dt', 'fieldset', 'figcaption', 'figure', 'footer', 'form', 'frame', 'frameset', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'header', 'hr', 'html', 'isindex', 'li', 'link', 'main', 'meta', 'nav', 'ol', 'p', 'picture', 'pre', 'section', 'script', 'source', 'style', 'table', 'template', 'td', 'tfoot', 'th', 'thead', 'title', 'tr', 'ul' ];
// List of preformatted elements where content is ignored for the purposes of
// output formatting when serializing
protected const PREFORMATTED_ELEMENTS = [ 'iframe', 'listing', 'noembed', 'noframes', 'noscript', 'plaintext', 'pre', 'style', 'script', 'textarea', 'title', 'xmp' ];
@ -317,12 +317,6 @@ class Document extends AbstractDocument {
}
};
$blockElementOrForeignFilter = function($n) use ($currentNode) {
if (!$n->isSameNode($currentNode) && $n instanceof Element && ($n->namespaceURI !== null || in_array($n->nodeName, self::BLOCK_ELEMENTS))) {
return true;
}
};
$blockElementOrForeignSiblings = false;
$modify = false;
}
@ -370,36 +364,6 @@ class Document extends AbstractDocument {
}
}
/*if ($foreignElement === null && $foreign) {
if ($hasChildNodes) {
$foreignElement = $currentNode;
$children = $currentNode->parentNode->walkShallow($blockElementOrForeignFilter);
$blockChild = false;
foreach ($children as $child) {
if ($child->namespaceURI === null) {
$blockChild = true;
break;
}
}
if ($blockChild) {
$blockElementOrForeignSiblings = true;
$foreignElementWithBlockElementSiblings = true;
$modify = true;
}
}
}
elseif ($foreignElement !== null && $foreign && $foreignElementWithBlockElementSiblings) {
$modify = true;
}
elseif ($currentNode->parentNode !== null && in_array($tagName, self::BLOCK_ELEMENTS) && (($currentNode->previousElementSibling === null && $currentNode->nextElementSibling === null) || $currentNode->parentNode->walkShallow($blockElementOrForeignFilter)->current() !== null)) {
$blockElementOrForeignSiblings = true;
$modify = true;
}*/
if ($modify) {
$s .= "\n" . str_repeat(' ', $indent);
}
@ -514,7 +478,7 @@ class Document extends AbstractDocument {
// If a foreign element with a foreign element ancestor with block element
// siblings and has at least one element child or any element with a block
// element descendant...
if (($foreign && $foreignElementWithBlockElementSiblings && $currentNode->firstElementChild !== null) || ($hasChildNodes && $currentNode->walk($blockElementFilter)->current() !== null)) {
if (($foreign && $foreignElementWithBlockElementSiblings && $currentNode->firstElementChild !== null) || ($currentNode->walk($blockElementFilter)->current() !== null)) {
$s .= "\n" . str_repeat(' ', $indent);
}
}
@ -538,7 +502,7 @@ class Document extends AbstractDocument {
# noframes, or plaintext element, or if the parent of current node is a noscript
# element and scripting is enabled for the node, then append the value of
# current node’s data IDL attribute literally.
if ($currentNode->parentNode->namespaceURI === null && in_array($currentNode->parentNode->nodeName, [ 'style', 'script', 'xmp', 'iframe', 'noembed', 'noframes', 'noscript', 'plaintext' ])) {
if ($currentNode->parentNode->namespaceURI === null && in_array($currentNode->parentNode->nodeName, [ 'style', 'script', 'xmp', 'iframe', 'noembed', 'noframes', 'plaintext' ])) {
$s .= $text;
}
# Otherwise, append the value of current node’s data IDL attribute, escaped as
@ -546,24 +510,8 @@ class Document extends AbstractDocument {
else {
if ($formatOutput) {
if ($preformattedElement === null) {
if ($foreignElement !== null) {
$modify = true;
} elseif ($currentNode->parentNode instanceof Element && in_array($currentNode->parentNode->nodeName, self::BLOCK_ELEMENTS)) {
$children = $currentNode->parentNode->walkShallow($blockElementOrForeignFilter);
$blockChild = false;
foreach ($children as $child) {
if ($child->namespaceURI === null) {
$blockChild = true;
break;
}
}
if ($blockChild) {
$modify = true;
}
}
if ($modify) {
$text = preg_replace('/ +/', ' ', str_replace("\t", ' ', $text));
if ($foreignElementWithBlockElementSiblings || $currentNode->parentNode->walk($blockElementFilter)->current() !== null) {
// If the text node's data is made up of only whitespace characters continue
// onto the next node
if (strspn($text, Data::WHITESPACE) === strlen($text)) {
@ -574,7 +522,7 @@ class Document extends AbstractDocument {
// the next node.
// Normalization here means that newlines are removed and simple spaces and tabs
// are condensed a single space.
$text = preg_replace([ '/[\n\x0C\x0D]+/', '/[ \t]+/' ], [ '', ' ' ], $text);
$text = preg_replace('/[\n\x0C\x0D]+/', '', $text);
if ($text === '') {
continue;
}
@ -587,39 +535,22 @@ class Document extends AbstractDocument {
}
# If current node is a Comment
elseif ($currentNode instanceof Comment) {
if ($formatOutput) {
$children = $currentNode->parentNode->walkShallow($blockElementOrForeignFilter);
$blockChild = false;
foreach ($children as $child) {
if ($child->namespaceURI === null) {
$blockChild = true;
break;
}
}
$text = trim($currentNode->data);
if ($blockChild) {
$indention = str_repeat(' ', $indent);
$s .= "\n$indention<!--";
if (strpos($text, "\n") === false) {
$s .= " $text -->";
} else {
$s .= "\n$indention " . str_replace("\n", "\n$indention ", $text) . "\n$indention-->";
}
} else {
$s .= "<!-- $text -->";
}
} else {
# Append the literal string "<!--" (U+003C LESS-THAN SIGN, U+0021 EXCLAMATION
# MARK, U+002D HYPHEN-MINUS, U+002D HYPHEN-MINUS), followed by the value of
# current node’s data IDL attribute, followed by the literal string "-->"
# (U+002D HYPHEN-MINUS, U+002D HYPHEN-MINUS, U+003E GREATER-THAN SIGN).
$s .= "<!--{$currentNode->data}-->";
if ($formatOutput && $preformattedElement === null && $foreignElementWithBlockElementSiblings || $currentNode->parentNode->walk($blockElementFilter)->current() !== null) {
$s .= "\n" . str_repeat(' ', $indent);
}
# Append the literal string "<!--" (U+003C LESS-THAN SIGN, U+0021 EXCLAMATION
# MARK, U+002D HYPHEN-MINUS, U+002D HYPHEN-MINUS), followed by the value of
# current node’s data IDL attribute, followed by the literal string "-->"
# (U+002D HYPHEN-MINUS, U+002D HYPHEN-MINUS, U+003E GREATER-THAN SIGN).
$s .= "<!--{$currentNode->data}-->";
}
# If current node is a ProcessingInstruction
elseif ($currentNode instanceof ProcessingInstruction) {
if ($formatOutput && $preformattedElement === null && $foreignElementWithBlockElementSiblings || $currentNode->parentNode->walk($blockElementFilter)->current() !== null) {
$s .= "\n" . str_repeat(' ', $indent);
}
# Append the literal string "<?" (U+003C LESS-THAN SIGN, U+003F QUESTION MARK),
# followed by the value of current node’s target IDL attribute, followed by a
# single U+0020 SPACE character, followed by the value of current node’s data

11
lib/DOM/ElementMap.php

@ -1,7 +1,8 @@
<?php
/** @license MIT
* Copyright 2017 , Dustin Wilson, J. King et al.
* See LICENSE and AUTHORS files for details */
* Copyright 2017 Dustin Wilson, J. King et al.
* See LICENSE and AUTHORS files for details
*/
declare(strict_types=1);
namespace MensBeam\HTML;
@ -42,6 +43,12 @@ class ElementMap {
return false;
}
public static function getIterator(): \Traversable {
foreach (self::$_storage as $v) {
yield $v;
}
}
public static function has(Element $element) {
foreach (self::$_storage as $v) {
if ($v->isSameNode($element)) {

22
lib/DOM/traits/Moonwalk.php

@ -14,8 +14,26 @@ trait Moonwalk {
private function moonwalkGenerator(\DOMNode $node, ?\Closure $filter = null) {
do {
if ($filter === null || $filter($node)) {
yield $node;
while (true) {
if ($filter === null || $filter($node)) {
yield $node;
}
// If node is an instance of DocumentFragment then it might be the content
// fragment of a template element, so iterate through all template elements
// stored in the element map and see if node is the fragment of one of the
// templates; if it is change node to the template element and reprocess. Magic!
// Can walk backwards THROUGH templates!
if ($node instanceof DocumentFragment) {
foreach (ElementMap::getIterator() as $element) {
if ($element->ownerDocument->isSameNode($node->ownerDocument) && $element instanceof TemplateElement && $element->content->isSameNode($node)) {
$node = $element;
continue;
}
}
}
break;
}
} while ($node = $node->parentNode);
}

14
lib/DOM/traits/MoonwalkShallow.php

@ -14,13 +14,13 @@ trait MoonwalkShallow {
* @param ?\Closure $filter - An optional closure to use to filter
*/
public function moonwalkShallow(?\Closure $filter = null): \Generator {
if ($this->hasChildNodes()) {
$childNodesLength = $this->childNodes->length;
for ($childNodesLength = $this->childNodes->length, $i = $childNodesLength - 1; $i >= 0; $i--) {
$child = $this->childNodes[$i];
if ($filter === null || $filter($child)) {
yield $child;
}
$node = (!$this instanceof TemplateElement) ? $this : $this->content;
$childNodesLength = $node->childNodes->length;
for ($childNodesLength = $node->childNodes->length, $i = $childNodesLength - 1; $i >= 0; $i--) {
$child = $node->childNodes[$i];
if ($filter === null || $filter($child)) {
yield $child;
}
}
}

4
lib/DOM/traits/Walk.php

@ -17,6 +17,10 @@ trait Walk {
yield $node;
}
if ($node instanceof TemplateElement) {
$node = $node->content;
}
if ($node->hasChildNodes()) {
$children = $node->childNodes;
foreach ($children as $c) {

4
lib/DOM/traits/WalkShallow.php

@ -13,7 +13,9 @@ trait WalkShallow {
* @param ?\Closure $filter - An optional closure to use to filter
*/
public function walkShallow(?\Closure $filter = null): \Generator {
foreach ($this->childNodes as $child) {
$node = (!$this instanceof TemplateElement) ? $this : $this->content;
foreach ($node->childNodes as $child) {
if ($filter === null || $filter($child)) {
yield $child;
}

Loading…
Cancel
Save