HTMLTemplateElements are now properly created when importing nodes
This commit is contained in:
parent
477930fa4c
commit
e22e23da0c
5 changed files with 54 additions and 20 deletions
|
@ -27,7 +27,7 @@ class DOMException extends \Exception {
|
|||
7 => 'Modification not allowed here',
|
||||
8 => 'Not found error',
|
||||
12 => 'Syntax error',
|
||||
100 => 'Argument #%s (\$%s) must be of type %s, %s given',
|
||||
100 => 'Argument #%s ($%s) must be of type %s, %s given',
|
||||
101 => 'Failed to set the "outerHTML" property; the element does not have a parent node'
|
||||
];
|
||||
|
||||
|
|
|
@ -124,7 +124,11 @@ class Document extends AbstractDocument {
|
|||
public function __construct($source = null, ?string $encoding = null, int $quirksMode = 0) {
|
||||
// Because we cannot have union types until php 8... :)
|
||||
if ($source !== null && !$source instanceof \DOMDocument && !is_string($source)) {
|
||||
throw new DOMException(DOMException::ARGUMENT_TYPE_ERROR, 1, 'source', '\DOMDocument|string|null', gettype($source));
|
||||
$type = gettype($source);
|
||||
if ($type === 'object') {
|
||||
$type = get_class($source);
|
||||
}
|
||||
throw new DOMException(DOMException::ARGUMENT_TYPE_ERROR, 1, 'source', '\DOMDocument|string|null', $type);
|
||||
}
|
||||
|
||||
parent::__construct();
|
||||
|
@ -214,9 +218,13 @@ class Document extends AbstractDocument {
|
|||
public function importNode(\DOMNode $node, bool $deep = false) {
|
||||
$node = parent::importNode($node, $deep);
|
||||
|
||||
/*if ($node instanceof \DOMElement) {
|
||||
$node = $this->convertTemplate($node);
|
||||
}*/
|
||||
if ($node instanceof \DOMElement || $node instanceof \DOMDocumentFragment) {
|
||||
if ($node instanceof \DOMElement && !$node instanceof HTMLTemplateElement && $node->namespaceURI === null && $node->nodeName === 'template') {
|
||||
$node = $this->convertTemplate($node);
|
||||
} else {
|
||||
$this->replaceTemplates($node);
|
||||
}
|
||||
}
|
||||
|
||||
return $node;
|
||||
}
|
||||
|
@ -233,13 +241,17 @@ class Document extends AbstractDocument {
|
|||
|
||||
public function loadDOM(\DOMDocument $source, ?string $encoding = null, int $quirksMode = 0) {
|
||||
if (!$source instanceof \DOMDocument) {
|
||||
throw new DOMException(DOMException::ARGUMENT_TYPE_ERROR, 1, 'source', '\DOMDocument', gettype($source));
|
||||
$type = gettype($source);
|
||||
if ($type === 'object') {
|
||||
$type = get_class($source);
|
||||
}
|
||||
throw new DOMException(DOMException::ARGUMENT_TYPE_ERROR, 1, 'source', '\DOMDocument', $type);
|
||||
}
|
||||
|
||||
$this->_documentEncoding = $encoding;
|
||||
$this->_quirksMode = $quirksMode;
|
||||
|
||||
// If there are already existing child nodes then remove them before loading the
|
||||
// If there are already-existing child nodes then remove them before loading the
|
||||
// DOM.
|
||||
while ($this->hasChildNodes()) {
|
||||
$this->removeChild($this->firstChild);
|
||||
|
@ -253,13 +265,16 @@ class Document extends AbstractDocument {
|
|||
}
|
||||
}
|
||||
|
||||
$this->replaceTemplates();
|
||||
return true;
|
||||
}
|
||||
|
||||
public function loadHTML($source, $options = null, ?string $encoding = null): bool {
|
||||
if (!is_string($source)) {
|
||||
throw new DOMException(DOMException::ARGUMENT_TYPE_ERROR, 1, 'source', 'string', gettype($source));
|
||||
$type = gettype($source);
|
||||
if ($type === 'object') {
|
||||
$type = get_class($source);
|
||||
}
|
||||
throw new DOMException(DOMException::ARGUMENT_TYPE_ERROR, 1, 'source', 'string', $type);
|
||||
}
|
||||
|
||||
$source = Parser::parse($source, $encoding, null);
|
||||
|
@ -788,13 +803,16 @@ class Document extends AbstractDocument {
|
|||
while ($element->hasChildNodes()) {
|
||||
$child = $element->firstChild;
|
||||
|
||||
if ($child instanceof Element && !$child instanceof HTMLTemplateElement && $child->namespaceURI === null && $child->nodeName === 'template') {
|
||||
$newChild = $this->convertTemplate($child);
|
||||
$child->parentNode->removeChild($child);
|
||||
$child = $newChild;
|
||||
if ($child instanceof Element) {
|
||||
if (!$child instanceof HTMLTemplateElement && $child->namespaceURI === null && $child->nodeName === 'template') {
|
||||
$newChild = $this->convertTemplate($child);
|
||||
$child->parentNode->removeChild($child);
|
||||
$child = $newChild;
|
||||
}
|
||||
|
||||
$this->replaceTemplates($child);
|
||||
}
|
||||
|
||||
$this->replaceTemplates($child);
|
||||
$template->content->appendChild($child);
|
||||
}
|
||||
|
||||
|
@ -807,7 +825,17 @@ class Document extends AbstractDocument {
|
|||
private function replaceTemplates(?\DOMNode $node = null) {
|
||||
if ($node === null) {
|
||||
$node = $this;
|
||||
} elseif ($node instanceof HTMLTemplateElement) {
|
||||
}
|
||||
|
||||
if (!$node instanceof \DOMDocument && !$node instanceof \DOMElement && !$node instanceof \DOMDocumentFragment) {
|
||||
$type = gettype($node);
|
||||
if ($type === 'object') {
|
||||
$type = get_class($node);
|
||||
}
|
||||
throw new DOMException(DOMException::ARGUMENT_TYPE_ERROR, 1, 'node', '\DOMDocument|\DOMDocumentFragment|\DOMElement|null', $type);
|
||||
}
|
||||
|
||||
if ($node instanceof HTMLTemplateElement) {
|
||||
$node = $node->content;
|
||||
}
|
||||
|
||||
|
|
|
@ -52,7 +52,8 @@ class Element extends \DOMElement {
|
|||
|
||||
# 2. Let fragment be the result of invoking the fragment parsing algorithm with
|
||||
# the new value as markup, and with context element.
|
||||
$fragment = Parser::parseFragment($value, $this->ownerDocument, 'UTF-8', $this);
|
||||
$fragment = Parser::parseFragment($value, null, 'UTF-8', $this);
|
||||
$fragment = $this->ownerDocument->importNode($fragment);
|
||||
|
||||
# 3. If the context object is a template element, then let context object be the
|
||||
# template's template contents (a DocumentFragment).
|
||||
|
@ -169,7 +170,8 @@ class Element extends \DOMElement {
|
|||
|
||||
# 5. Let fragment be the result of invoking the fragment parsing algorithm with
|
||||
# the new value as markup, and parent as the context element.
|
||||
$fragment = Parser::parseFragment($value, $this->ownerDocument, 'UTF-8', $parent);
|
||||
$fragment = Parser::parseFragment($value, null, 'UTF-8', $parent);
|
||||
$fragment = $this->ownerDocument->importNode($fragment);
|
||||
|
||||
# 6. Replace the context object with fragment within the context object's
|
||||
# parent.
|
||||
|
|
|
@ -225,7 +225,11 @@ if (version_compare(\PHP_VERSION, '8.0', '>=')) {
|
|||
foreach ($nodes as $n) {
|
||||
// Can't do union types until PHP 8... OTL
|
||||
if (!$n instanceof \DOMNode && !is_string($n)) {
|
||||
throw new DOMException(DOMException::ARGUMENT_TYPE_ERROR, 1, 'nodes', '\DOMNode|string', gettype($n));
|
||||
$type = gettype($n);
|
||||
if ($type === 'object') {
|
||||
$type = get_class($n);
|
||||
}
|
||||
throw new DOMException(DOMException::ARGUMENT_TYPE_ERROR, 1, 'nodes', '[\DOMNode|string]', $n);
|
||||
}
|
||||
|
||||
$nn = (!is_string($n)) ? $n : $this->ownerDocument->createTextNode($n);
|
||||
|
|
|
@ -7,9 +7,9 @@ declare(strict_types=1);
|
|||
namespace MensBeam\HTML\DOM\TestCase;
|
||||
|
||||
use MensBeam\HTML\DOM\Document;
|
||||
use MensBeam\HTML\DOM\Parser;
|
||||
use MensBeam\HTML\Parser;
|
||||
|
||||
/**
|
||||
/**
|
||||
* @covers \MensBeam\HTML\DOM\Document
|
||||
* @covers \MensBeam\HTML\DOM\DocumentFragment
|
||||
* @covers \MensBeam\HTML\DOM\Element
|
||||
|
|
Loading…
Reference in a new issue