Upgrade to 3.6.0

This commit is contained in:
Bastian Allgeier
2021-11-16 14:53:37 +01:00
parent 7388fa4d24
commit 92b7a330fa
318 changed files with 20017 additions and 6878 deletions

View File

@@ -2,70 +2,173 @@
namespace Kirby\Parsley;
use DOMNode;
use DOMNodeList;
use Kirby\Toolkit\Html;
/**
* Represents an inline element
* in an HTML document
*
* @since 3.5.0
*
* @package Kirby Parsley
* @author Bastian Allgeier <bastian@getkirby.com>,
* @link https://getkirby.com
* @copyright Bastian Allgeier GmbH
* @license https://getkirby.com/license
*/
class Inline
{
/**
* @var string
*/
protected $html = '';
/**
* @var array
*/
protected $marks = [];
public function __construct($node, array $marks = [])
/**
* @param \DOMNode $node
* @param array $marks
*/
public function __construct(DOMNode $node, array $marks = [])
{
$this->createMarkRules($marks);
$this->html = trim($this->parseNode($node));
$this->html = trim(static::parseNode($node, $this->marks));
}
public function createMarkRules($marks)
/**
* Loads all mark rules
*
* @param array $marks
* @return array
*/
protected function createMarkRules(array $marks)
{
foreach ($marks as $mark) {
$this->marks[$mark['tag']] = $mark;
}
return $this->marks;
}
public function parseChildren($children): string
/**
* Get all allowed attributes for a DOMNode
* as clean array
*
* @param DOMNode $node
* @param array $marks
* @return array
*/
public static function parseAttrs(DOMNode $node, array $marks = []): array
{
if (!$children) {
return '';
$attrs = [];
$mark = $marks[$node->tagName];
$defaults = $mark['defaults'] ?? [];
foreach ($mark['attrs'] ?? [] as $attr) {
if ($node->hasAttribute($attr)) {
$attrs[$attr] = $node->getAttribute($attr);
} else {
$attrs[$attr] = $defaults[$attr] ?? null;
}
}
return $attrs;
}
/**
* Parses all children and creates clean HTML
* for each of them.
*
* @param \DOMNodeList $children
* @param array $marks
* @return string
*/
public static function parseChildren(DOMNodeList $children, array $marks): string
{
$html = '';
foreach ($children as $child) {
$html .= $this->parseNode($child);
$html .= static::parseNode($child, $marks);
}
return $html;
}
public function parseNode($node)
/**
* Go through all child elements and create
* clean inner HTML for them
*
* @param DOMNode $node
* @return string|null
*/
public static function parseInnerHtml(DOMNode $node, array $marks = []): ?string
{
$html = static::parseChildren($node->childNodes, $marks);
// trim the inner HTML for paragraphs
if ($node->tagName === 'p') {
$html = trim($html);
}
// return null for empty inner HTML
if ($html === '') {
return null;
}
return $html;
}
/**
* Converts the given node to clean HTML
*
* @param \DOMNode $node
* @param array $marks
* @return string|null
*/
public static function parseNode(DOMNode $node, array $marks = []): ?string
{
if (is_a($node, 'DOMText') === true) {
return $node->textContent;
return Html::encode($node->textContent);
}
// ignore comments
if (is_a($node, 'DOMComment') === true) {
return '';
}
// known marks
if (array_key_exists($node->tagName, $this->marks) === true) {
$mark = $this->marks[$node->tagName];
$attrs = [];
$defaults = $mark['defaults'] ?? [];
foreach ($mark['attrs'] ?? [] as $attr) {
if ($node->hasAttribute($attr)) {
$attrs[$attr] = $node->getAttribute($attr);
} else {
$attrs[$attr] = $defaults[$attr] ?? null;
}
}
return '<' . $node->tagName . attr($attrs, ' ') . '>' . $this->parseChildren($node->childNodes) . '</' . $node->tagName . '>';
return null;
}
// unknown marks
return $this->parseChildren($node->childNodes);
if (array_key_exists($node->tagName, $marks) === false) {
return static::parseChildren($node->childNodes, $marks);
}
// collect all allowed attributes
$attrs = static::parseAttrs($node, $marks);
// close self-closing elements
if (Html::isVoid($node->tagName) === true) {
return '<' . $node->tagName . attr($attrs, ' ') . ' />';
}
$innerHtml = static::parseInnerHtml($node, $marks);
// skip empty paragraphs
if ($innerHtml === null && $node->tagName === 'p') {
return null;
}
// create the outer html for the element
return '<' . $node->tagName . attr($attrs, ' ') . '>' . $innerHtml . '</' . $node->tagName . '>';
}
public function innerHtml()
/**
* Returns the HTML contents of the element
*
* @return string
*/
public function innerHtml(): string
{
return $this->html;
}