Browse Source

Added ChildNode::remove, NonElementParentNode

master
Dustin Wilson 2 years ago
parent
commit
6d8bc49ed8
  1. 3
      lib/CharacterData.php
  2. 12
      lib/ChildNode.php
  3. 3
      lib/Element.php
  4. 36
      lib/NonDocumentTypeChildNode.php
  5. 2
      lib/NonElementParentNode.php
  6. 79
      tests/cases/TestChildNode.php
  7. 32
      tests/cases/TestNonDocumentTypeChildNode.php
  8. 1
      tests/phpunit.dist.xml

3
lib/CharacterData.php

@ -10,7 +10,8 @@ namespace MensBeam\HTML\DOM;
abstract class CharacterData extends Node {
use ChildNode;
use ChildNode, NonDocumentTypeChildNode;
protected function __get_data(): string {
// PHP's DOM does this correctly already.

12
lib/ChildNode.php

@ -94,9 +94,21 @@ trait ChildNode {
$parent->insertBefore($node, $viablePreviousSibling);
}
public function remove(): void {
# The remove() method steps are:
# 1. If this’s parent is null, then return.
if ($this->parentNode === null) {
return;
}
# 2. Remove this.
$this->parentNode->removeChild($this);
}
public function replaceWith(Node|string ...$nodes): void {
// Before exists in PHP DOM, but it can insert incorrect nodes because of PHP
// DOM's incorrect (for HTML) pre-insertion validation.
# The replaceWith(nodes) method steps are:
#
# 1. Let parent be this’s parent.

3
lib/Element.php

@ -17,7 +17,8 @@ use MensBeam\HTML\Parser,
class Element extends Node {
use ChildNode, DocumentOrElement, ParentNode;
use ChildNode, DocumentOrElement, NonDocumentTypeChildNode, ParentNode;
protected function __get_attributes(): NamedNodeMap {
// NamedNodeMaps cannot be created from their constructors normally.

36
lib/NonDocumentTypeChildNode.php

@ -0,0 +1,36 @@
<?php
/**
* @license MIT
* Copyright 2017 Dustin Wilson, J. King, et al.
* See LICENSE and AUTHORS files for details
*/
declare(strict_types=1);
namespace MensBeam\HTML\DOM;
use MensBeam\HTML\DOM\Inner\{
Document as InnerDocument,
Reflection
};
trait NonDocumentTypeChildNode {
protected function __get_nextElementSibling(): ?Element {
// The nextElementSibling getter steps are to return the first following sibling
// that is an element; otherwise null.
// PHP's DOM does this correctly already.
$inner = $this->innerNode;
$result = $inner->nextElementSibling;
return ($result !== null) ? $inner->ownerDocument->getWrapperNode($result) : null;
}
protected function __get_previousElementSibling(): ?Element {
// The previousElementSibling getter steps are to return the first preceding
// sibling that is an element; otherwise null.
// PHP's DOM does this correctly already.
$inner = $this->innerNode;
$result = $inner->previousElementSibling;
return ($result !== null) ? $inner->ownerDocument->getWrapperNode($result) : null;
}
}

2
lib/NonElementParentNode.php

@ -16,7 +16,7 @@ use MensBeam\HTML\Parser;
trait NonElementParentNode {
public function getElementById(string $elementId): ?Element {
$document = (!$this instanceof Element) ? $this->innerNode : $this->innerNode->ownerDocument;
$document = $this->getInnerDocument();
$innerElement = $this->innerNode->getElementById($elementId);
return ($innerElement !== null) ? $document->getWrapperNode($innerElement) : null;
}

79
tests/cases/TestChildNode.php

@ -18,6 +18,49 @@ use MensBeam\HTML\DOM\{
/** @covers \MensBeam\HTML\DOM\ChildNode */
class TestChildNode extends \PHPUnit\Framework\TestCase {
/**
* @covers \MensBeam\HTML\DOM\ChildNode::after
* @covers \MensBeam\HTML\DOM\ChildNode::before
* @covers \MensBeam\HTML\DOM\ChildNode::replaceWith
*
* @covers \MensBeam\HTML\DOM\Comment::__construct
* @covers \MensBeam\HTML\DOM\Document::__construct
* @covers \MensBeam\HTML\DOM\Document::__get_documentElement
* @covers \MensBeam\HTML\DOM\Document::createComment
* @covers \MensBeam\HTML\DOM\Document::createDocumentFragment
* @covers \MensBeam\HTML\DOM\Document::createElement
* @covers \MensBeam\HTML\DOM\Document::createTextNode
* @covers \MensBeam\HTML\DOM\Document::serialize
* @covers \MensBeam\HTML\DOM\DocumentFragment::__construct
* @covers \MensBeam\HTML\DOM\DOMImplementation::__construct
* @covers \MensBeam\HTML\DOM\Element::__construct
* @covers \MensBeam\HTML\DOM\Node::__construct
* @covers \MensBeam\HTML\DOM\Node::__get_firstChild
* @covers \MensBeam\HTML\DOM\Node::__get_ownerDocument
* @covers \MensBeam\HTML\DOM\Node::__get_parentNode
* @covers \MensBeam\HTML\DOM\Node::__toString
* @covers \MensBeam\HTML\DOM\Node::appendChild
* @covers \MensBeam\HTML\DOM\Node::containsInner
* @covers \MensBeam\HTML\DOM\Node::convertNodesToNode
* @covers \MensBeam\HTML\DOM\Node::getInnerDocument
* @covers \MensBeam\HTML\DOM\Node::getInnerNode
* @covers \MensBeam\HTML\DOM\Node::getRootNode
* @covers \MensBeam\HTML\DOM\Node::insertBefore
* @covers \MensBeam\HTML\DOM\Node::postInsertionBugFixes
* @covers \MensBeam\HTML\DOM\Node::preInsertionBugFixes
* @covers \MensBeam\HTML\DOM\Node::preInsertionValidity
* @covers \MensBeam\HTML\DOM\Node::replaceChild
* @covers \MensBeam\HTML\DOM\Text::__construct
* @covers \MensBeam\HTML\DOM\Inner\Document::__construct
* @covers \MensBeam\HTML\DOM\Inner\Document::__get_wrapperNode
* @covers \MensBeam\HTML\DOM\Inner\Document::getWrapperNode
* @covers \MensBeam\HTML\DOM\Inner\NodeCache::get
* @covers \MensBeam\HTML\DOM\Inner\NodeCache::has
* @covers \MensBeam\HTML\DOM\Inner\NodeCache::key
* @covers \MensBeam\HTML\DOM\Inner\NodeCache::set
* @covers \MensBeam\HTML\DOM\Inner\Reflection::createFromProtectedConstructor
* @covers \MensBeam\HTML\DOM\Inner\Reflection::getProtectedProperty
*/
public function testMethod_after_before_replaceWith(): void {
$d = new Document();
$d->appendChild($d->createElement('html'));
@ -64,4 +107,40 @@ class TestChildNode extends \PHPUnit\Framework\TestCase {
$o->replaceWith('poo', $o, $e);
$this->assertSame('<body><span></span>eekackpooookeek<div></div><span></span>eek<div></div></body>', (string)$body);
}
/**
* @covers \MensBeam\HTML\DOM\ChildNode::remove
*
* @covers \MensBeam\HTML\DOM\Document::__construct
* @covers \MensBeam\HTML\DOM\Document::__get_body
* @covers \MensBeam\HTML\DOM\Document::load
* @covers \MensBeam\HTML\DOM\DOMImplementation::__construct
* @covers \MensBeam\HTML\DOM\Element::__construct
* @covers \MensBeam\HTML\DOM\Node::__construct
* @covers \MensBeam\HTML\DOM\Node::__get_parentNode
* @covers \MensBeam\HTML\DOM\Node::getInnerDocument
* @covers \MensBeam\HTML\DOM\Node::getInnerNode
* @covers \MensBeam\HTML\DOM\Node::hasChildNodes
* @covers \MensBeam\HTML\DOM\Node::postParsingTemplatesFix
* @covers \MensBeam\HTML\DOM\Node::removeChild
* @covers \MensBeam\HTML\DOM\Inner\Document::__construct
* @covers \MensBeam\HTML\DOM\Inner\Document::__get_xpath
* @covers \MensBeam\HTML\DOM\Inner\Document::getWrapperNode
* @covers \MensBeam\HTML\DOM\Inner\NodeCache::get
* @covers \MensBeam\HTML\DOM\Inner\NodeCache::has
* @covers \MensBeam\HTML\DOM\Inner\NodeCache::key
* @covers \MensBeam\HTML\DOM\Inner\NodeCache::set
* @covers \MensBeam\HTML\DOM\Inner\Reflection::createFromProtectedConstructor
* @covers \MensBeam\HTML\DOM\Inner\Reflection::getProtectedProperty
*/
public function testMethod_remove(): void {
$d = new Document('<!DOCTYPE html><html><body></body></html>');
$body = $d->body;
$body->remove();
$this->assertNull($d->body);
// Test removal of an element without a parent.
$body->remove();
}
}

32
tests/cases/TestNonDocumentTypeChildNode.php

@ -0,0 +1,32 @@
<?php
/**
* @license MIT
* Copyright 2017 Dustin Wilson, J. King, et al.
* See LICENSE and AUTHORS files for details
*/
declare(strict_types=1);
namespace MensBeam\HTML\DOM\TestCase;
use MensBeam\HTML\DOM\{
Document,
DOMException,
Element,
Node
};
/** @covers \MensBeam\HTML\DOM\NonDocumentTypeChildNode */
class TestNonDocumentTypeChildNode extends \PHPUnit\Framework\TestCase {
public function testProperty_nextElementSibling_previousElementSibling(): void {
$d = new Document('<!DOCTYPE html><html><body></body></html>');
$body = $d->body;
$br = $body->appendChild($d->createElement('br'));
$body->appendChild($d->createTextNode('eek'));
$ook = $body->appendChild($d->createTextNode('ook'));
$br2 = $body->appendChild($d->createElement('br'));
$this->assertSame($br2, $br->nextElementSibling);
$this->assertSame($br, $ook->previousElementSibling);
}
}

1
tests/phpunit.dist.xml

@ -26,6 +26,7 @@
<file>cases/TestElement.php</file>
<file>cases/TestInnerDocument.php</file>
<file>cases/TestNode.php</file>
<file>cases/TestNonDocumentTypeChildNode.php</file>
<file>cases/TestParentNode.php</file>
</testsuite>
</testsuites>

Loading…
Cancel
Save