From 4eeb45b816b02550f6af70a4b31eea969ee23c8c Mon Sep 17 00:00:00 2001 From: Dustin Wilson Date: Fri, 1 Oct 2021 07:29:50 -0500 Subject: [PATCH] Added support for html namespace, 1 test fails now --- lib/Document.php | 10 +- tests/cases/TestDocument.php | 174 +++++++++++++++++++++-------------- 2 files changed, 110 insertions(+), 74 deletions(-) diff --git a/lib/Document.php b/lib/Document.php index 581c568..d44dd4a 100644 --- a/lib/Document.php +++ b/lib/Document.php @@ -284,7 +284,7 @@ class Document extends AbstractDocument { // DEVIATION: There is no scripting in this implementation. try { - if (strtolower($qualifiedName) !== 'template' || $namespaceURI !== null) { + if (strtolower($qualifiedName) !== 'template' || ($namespaceURI !== null && $namespaceURI !== Parser::HTML_NAMESPACE)) { $e = parent::createElementNS($namespaceURI, $qualifiedName); } else { $e = new HTMLTemplateElement($this, $qualifiedName); @@ -314,7 +314,7 @@ class Document extends AbstractDocument { $node = parent::importNode($node, $deep); if ($node instanceof \DOMElement || $node instanceof \DOMDocumentFragment) { - if ($node instanceof \DOMElement && !$node instanceof HTMLTemplateElement && $node->namespaceURI === null && strtolower($node->nodeName) === 'template') { + if ($node instanceof \DOMElement && !$node instanceof HTMLTemplateElement && ($node->namespaceURI === null || $node->namespaceURI === Parser::HTML_NAMESPACE) && strtolower($node->nodeName) === 'template') { $node = $this->convertTemplate($node); } else { $this->replaceTemplates($node); @@ -943,7 +943,7 @@ class Document extends AbstractDocument { private function convertTemplate(\DOMElement $element): \DOMElement { - if ($element->namespaceURI === null && strtolower($element->nodeName) === 'template') { + if (($element->namespaceURI === null || $element->namespaceURI === Parser::HTML_NAMESPACE) && strtolower($element->nodeName) === 'template') { $template = $this->createElement($element->nodeName); while ($element->attributes->length > 0) { @@ -953,7 +953,7 @@ class Document extends AbstractDocument { $child = $element->firstChild; if ($child instanceof Element) { - if (!$child instanceof HTMLTemplateElement && $child->namespaceURI === null && strtolower($child->nodeName) === 'template') { + if (!$child instanceof HTMLTemplateElement && ($child->namespaceURI === null || $child->namespaceURI === Parser::HTML_NAMESPACE) && strtolower($child->nodeName) === 'template') { $newChild = $this->convertTemplate($child); $child->parentNode->removeChild($child); $child = $newChild; @@ -989,7 +989,7 @@ class Document extends AbstractDocument { } $templates = $node->walk(function($n) { - if ($n instanceof Element && !$n instanceof HTMLTemplateElement && $n->namespaceURI === null && strtolower($n->nodeName) === 'template') { + if ($n instanceof Element && !$n instanceof HTMLTemplateElement && ($n->namespaceURI === null || $n->namespaceURI === Parser::HTML_NAMESPACE) && strtolower($n->nodeName) === 'template') { return true; } }); diff --git a/tests/cases/TestDocument.php b/tests/cases/TestDocument.php index 66ba451..f6d9068 100644 --- a/tests/cases/TestDocument.php +++ b/tests/cases/TestDocument.php @@ -19,88 +19,124 @@ use MensBeam\HTML\Parser; class TestDocument extends \PHPUnit\Framework\TestCase { public function provideAttributeNodes(): iterable { return [ - [null, 'test', 'test', ''], - [null, 'test:test', 'testU00003Atest', ''], - [null, 'test', 'test', ''], - [null, 'TEST:TEST', 'testU00003Atest', ''], - ['fake_ns', 'test', 'test', ''], - ['fake_ns', 'test:test', 'test', 'test'], - ['fake_ns', 'TEST:TEST', 'TEST', 'TEST'] + [ 'test', 'test' ], + [ 'TEST', 'test' ], + [ 'test:test', 'testU00003Atest' ], + [ 'TEST:TEST', 'testU00003Atest' ] ]; } /** * @dataProvider provideAttributeNodes * @covers \MensBeam\HTML\DOM\Document::createAttribute + */ + public function testAttributeNodeCreation(string $nameIn, string $local): void { + $d = new Document(); + $d->appendChild($d->createElement('html')); + $a = $d->createAttribute($nameIn); + $this->assertSame($local, $a->localName); + } + + + public function provideAttributeNodesNS(): iterable { + return [ + [ 'fake_ns', 'test', 'test', '' ], + [ 'fake_ns', 'test:test', 'test', 'test' ], + [ 'fake_ns', 'TEST:TEST', 'TEST', 'TEST' ] + ]; + } + + /** + * @dataProvider provideAttributeNodesNS * @covers \MensBeam\HTML\DOM\Document::createAttributeNS */ - public function testAttributeNodeCreation(?string $nsIn, string $nameIn, string $local, string $prefix): void { + public function testAttributeNodeNSCreation(?string $nsIn, string $nameIn, string $local, string $prefix): void { $d = new Document(); $d->appendChild($d->createElement('html')); - $a = ($nsIn === null) ? $d->createAttribute($nameIn) : $d->createAttributeNS($nsIn, $nameIn); + $a = $d->createAttributeNS($nsIn, $nameIn); $this->assertSame($local, $a->localName); $this->assertSame($nsIn, $a->namespaceURI); $this->assertSame($prefix, $a->prefix); } - /** - * @covers \MensBeam\HTML\DOM\Document::__construct - * @covers \MensBeam\HTML\DOM\Document::loadDOM - * @covers \MensBeam\HTML\DOM\Document::loadHTML - */ - public function testDocumentCreation(): void { - // Test null source - $d = new Document(); - $this->assertSame('MensBeam\HTML\DOM\Document', $d::class); - $this->assertSame(null, $d->firstChild); - - // Test string source - $d = new Document('Ook!'); - $this->assertSame(Parser::QUIRKS_MODE, $d->quirksMode); - - // Test DOM source - $d = new \DOMDocument(); - $d->appendChild($d->createElement('html')); - $d = new Document($d); - $this->assertSame('MensBeam\HTML\DOM\Element', $d->firstChild::class); - $this->assertSame('html', $d->firstChild->nodeName); - } - - - public function provideElements(): iterable { - return [ - // HTML element - [ '', null, 'div', 'div', Element::class ], - // HTML element and having to normalize local name - [ '', null, 'DIV', 'div', Element::class ], - // HTML element with a null namespace - [ null, null, 'div', 'div', Element::class ], - // Template element - [ '', null, 'template', 'template', HTMLTemplateElement::class ], - // Template element and having to normalize local name - [ '', null, 'TEMPLATE', 'template', HTMLTemplateElement::class ], - // Template element with a null namespace - [ null, null, 'template', 'template', HTMLTemplateElement::class ], - // Template element with a null namespace and uppercase name - [ null, null, 'TEMPLATE', 'TEMPLATE', HTMLTemplateElement::class ], - // SVG element with SVG namespace - [ Parser::SVG_NAMESPACE, Parser::SVG_NAMESPACE, 'svg', 'svg', Element::class ], - // SVG element with SVG namespace and having to normalize local name - [ Parser::SVG_NAMESPACE, Parser::SVG_NAMESPACE, 'SVG', 'SVG', Element::class ] - ]; - } - - /** - * @dataProvider provideElements - * @covers \MensBeam\HTML\DOM\Document::createElement - * @covers \MensBeam\HTML\DOM\Document::createElementNS - */ - public function testElementCreation(?string $nsIn, ?string $nsOut, string $localIn, string $localOut, string $class): void { - $d = new Document; - $n = ($nsIn !== '') ? $d->createElementNS($nsIn, $localIn) : $d->createElement($localIn); - $this->assertInstanceOf($class, $n); - $this->assertNotNull($n->ownerDocument); - $this->assertSame($nsOut, $n->namespaceURI); - $this->assertSame($localOut, $n->localName); - } + + /** + * @covers \MensBeam\HTML\DOM\Document::__construct + * @covers \MensBeam\HTML\DOM\Document::loadDOM + * @covers \MensBeam\HTML\DOM\Document::loadHTML + */ + public function testDocumentCreation(): void { + // Test null source + $d = new Document(); + $this->assertSame('MensBeam\HTML\DOM\Document', $d::class); + $this->assertSame(null, $d->firstChild); + + // Test string source + $d = new Document('Ook!'); + $this->assertSame(Parser::QUIRKS_MODE, $d->quirksMode); + + // Test DOM source + $d = new \DOMDocument(); + $d->appendChild($d->createElement('html')); + $d = new Document($d); + $this->assertSame('MensBeam\HTML\DOM\Element', $d->firstChild::class); + $this->assertSame('html', $d->firstChild->nodeName); + } + + + public function provideElements(): iterable { + return [ + // HTML element + [ 'div', 'div', Element::class ], + // HTML element and uppercase local name + [ 'DIV', 'div', Element::class ], + // Template element + [ 'template', 'template', HTMLTemplateElement::class ], + // Template element and uppercase local name + [ 'TEMPLATE', 'template', HTMLTemplateElement::class ] + ]; + } + + /** + * @dataProvider provideElements + * @covers \MensBeam\HTML\DOM\Document::createElement + */ + public function testElementCreation(string $localIn, string $localOut, string $class): void { + $d = new Document; + $n = $d->createElement($localIn); + $this->assertInstanceOf($class, $n); + $this->assertNotNull($n->ownerDocument); + $this->assertSame($localOut, $n->localName); + } + + + public function provideElementsNS(): iterable { + return [ + // HTML element with a null namespace + [ null, null, 'div', 'div', Element::class ], + // Template element with a null namespace + [ null, null, 'template', 'template', HTMLTemplateElement::class ], + // Template element with a null namespace and uppercase name + [ null, null, 'TEMPLATE', 'TEMPLATE', HTMLTemplateElement::class ], + // Template element + [ Parser::HTML_NAMESPACE, Parser::HTML_NAMESPACE, 'template', 'template', HTMLTemplateElement::class ], + // SVG element with SVG namespace + [ Parser::SVG_NAMESPACE, Parser::SVG_NAMESPACE, 'svg', 'svg', Element::class ], + // SVG element with SVG namespace and uppercase local name + [ Parser::SVG_NAMESPACE, Parser::SVG_NAMESPACE, 'SVG', 'SVG', Element::class ] + ]; + } + + /** + * @dataProvider provideElementsNS + * @covers \MensBeam\HTML\DOM\Document::createElementNS + */ + public function testElementCreationNS(?string $nsIn, ?string $nsOut, string $localIn, string $localOut, string $class): void { + $d = new Document; + $n = $d->createElementNS($nsIn, $localIn); + $this->assertInstanceOf($class, $n); + $this->assertNotNull($n->ownerDocument); + $this->assertSame($nsOut, $n->namespaceURI); + $this->assertSame($localOut, $n->localName); + } }