Skip to content
This repository has been archived by the owner on Mar 19, 2020. It is now read-only.

Commit

Permalink
Added support for node cloning
Browse files Browse the repository at this point in the history
  • Loading branch information
TonyBogdanov committed Jan 5, 2018
1 parent 2106258 commit 0bbc920
Show file tree
Hide file tree
Showing 28 changed files with 1,731 additions and 512 deletions.
52 changes: 48 additions & 4 deletions classes/Dom.php
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ public function __construct($content = null)
break;

case $content instanceof self:
$this->nodes = $content->get();
$this->nodes = $content->nodes;
break;

case $content instanceof NodeInterface:
Expand Down Expand Up @@ -196,15 +196,15 @@ public function get(int $index = null)
}

/**
* Add all nodes from the collection constructed by the specified content to the current list of nodes.
* Add the specified content to the end of the collection.
*
* @param $content
* @return Dom
*/
public function add($content): Dom
{
/** @var NodeInterface $node */
foreach ((new static($content))->get() as $node) {
foreach ((new static($content))->nodes as $node) {
if (!in_array($node, $this->nodes, true)) {
$this->nodes[] = $node;
}
Expand Down Expand Up @@ -270,7 +270,7 @@ public function children(): Dom
$dom = new Dom();

/** @var NodeInterface $node */
foreach ($this->get() as $node) {
foreach ($this->nodes as $node) {
if ($node instanceof Element) {
/** @var NodeInterface $child */
foreach ($node as $child) {
Expand All @@ -281,4 +281,48 @@ public function children(): Dom

return $dom;
}

/**
* Insert content, specified by the parameter, to the end of immediate child nodes of all Element nodes in the
* collection.
*
* @param $content
* @return Dom
*/
public function append($content): Dom
{
/** @var NodeInterface $node */
foreach ($this->nodes as $node) {
if ($node instanceof Element) {
/** @var NodeInterface $child */
foreach ((new static($content))->nodes as $child) {
$node->insertAfter(null === $child->parent() ? $child : clone $child);
}
}
}

return $this;
}

/**
* Insert content, specified by the parameter, to the beginning of immediate child nodes of all Element nodes in
* the collection.
*
* @param $content
* @return Dom
*/
public function prepend($content): Dom
{
/** @var NodeInterface $node */
foreach ($this->nodes as $node) {
if ($node instanceof Element) {
/** @var NodeInterface $child */
foreach (array_reverse((new static($content))->nodes) as $child) {
$node->insertBefore($child);
}
}
}

return $this;
}
}
16 changes: 16 additions & 0 deletions classes/Node/CData.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,14 @@ public function __toString(): string
return '<![CDATA[' . $this->content . ']]>';
}

/**
* @inheritDoc
*/
public function __clone()
{
throw new \BadMethodCallException('Native cloning is not allowed, use clone() instead.');
}

/**
* @inheritDoc
*/
Expand Down Expand Up @@ -92,4 +100,12 @@ public function detach(): NodeInterface

return $this;
}

/**
* @inheritDoc
*/
public function clone(): NodeInterface
{
return new static($this->content);
}
}
16 changes: 16 additions & 0 deletions classes/Node/Comment.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,14 @@ public function __toString(): string
return '<!--' . $this->content . '-->';
}

/**
* @inheritDoc
*/
public function __clone()
{
throw new \BadMethodCallException('Native cloning is not allowed, use clone() instead.');
}

/**
* @inheritDoc
*/
Expand Down Expand Up @@ -92,4 +100,12 @@ public function detach(): NodeInterface

return $this;
}

/**
* @inheritDoc
*/
public function clone(): NodeInterface
{
return new static($this->content);
}
}
16 changes: 16 additions & 0 deletions classes/Node/DocType.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,14 @@ public function __toString(): string
return '<!DOCTYPE ' . $this->content . '>';
}

/**
* @inheritDoc
*/
public function __clone()
{
throw new \BadMethodCallException('Native cloning is not allowed, use clone() instead.');
}

/**
* @inheritDoc
*/
Expand Down Expand Up @@ -64,4 +72,12 @@ public function detach(): NodeInterface
explode('::', __METHOD__)[1]
));
}

/**
* @inheritDoc
*/
public function clone(): NodeInterface
{
return new static($this->content);
}
}
38 changes: 38 additions & 0 deletions classes/Node/Element.php
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,14 @@ public function __toString(): string
return $html;
}

/**
* @inheritDoc
*/
public function __clone()
{
throw new \BadMethodCallException('Native cloning is not allowed, use clone() instead.');
}

/**
* Return TRUE if the specified name exists as attribute.
* The attribute name is lowercased.
Expand Down Expand Up @@ -192,6 +200,36 @@ public function detach(): NodeInterface
return $this;
}

/**
* @inheritDoc
*/
public function clone(): NodeInterface
{
$clone = new static($this->tag);

/**
* Inherit attributes.
*
* @var string $name
* @var string $value
*/
foreach ($this->attributes as $name => $value) {
$clone->setAttribute($name, $value);
}

/**
* Inherit cloned child nodes.
*
* @var int $index
* @var NodeInterface $child
*/
foreach ($this->children as $index => $child) {
$clone->insertAfter($child->clone());
}

return $clone;
}

/**
* @inheritDoc
*/
Expand Down
17 changes: 17 additions & 0 deletions classes/Node/NodeInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,14 @@ interface NodeInterface
*/
public function __toString(): string;

/**
* Throw exception to signify native cloning is not allowed.
* One should use clone() instead.
*
* @throws \BadMethodCallException
*/
public function __clone();

/**
* Return the parent node or null if such isn't set.
*
Expand Down Expand Up @@ -45,4 +53,13 @@ public function attach(NodeInterface $parent): NodeInterface;
* @return $this
*/
public function detach(): NodeInterface;

/**
* Ensure child nodes are also cloned when applicable.
* Ensure old node is detached from parent.
* Ensure (new) cloned node is attached to parent node.
*
* @return NodeInterface
*/
public function clone(): NodeInterface;
}
16 changes: 16 additions & 0 deletions classes/Node/Text.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,14 @@ public function __toString(): string
return htmlspecialchars($this->content);
}

/**
* @inheritDoc
*/
public function __clone()
{
throw new \BadMethodCallException('Native cloning is not allowed, use clone() instead.');
}

/**
* @inheritDoc
*/
Expand Down Expand Up @@ -92,4 +100,12 @@ public function detach(): NodeInterface

return $this;
}

/**
* @inheritDoc
*/
public function clone(): NodeInterface
{
return new static($this->content);
}
}
68 changes: 67 additions & 1 deletion docs/class-SDom.Dom.html
Original file line number Diff line number Diff line change
Expand Up @@ -332,7 +332,7 @@ <h2>Implementation of</h2>
<code><a href="source-class-SDom.Dom.html#204-214">add</a>( <span> <span class="property-name">$content</span> </span> )</code>

<div class="description">
Add all nodes from the collection constructed by the specified content to the current list of nodes.
Add the specified content to the end of the collection.



Expand Down Expand Up @@ -507,6 +507,72 @@ <h2>Implementation of</h2>



</div>
</div>
</td>
</tr>



<tr id="_append">

<td class="attributes col-md-1">
<code class="keyword">
public


</code>
</td>

<td class="name">
<div>
<a class="anchor pull-right" href="#_append">#</a>
<code><a href="source-class-SDom.Dom.html#292-305">append</a>( <span> <span class="property-name">$content</span> </span> )</code>

<div class="description">
Insert content, specified by the parameter, to the end of immediate child nodes of all Element nodes in the
collection.








</div>
</div>
</td>
</tr>



<tr id="_prepend">

<td class="attributes col-md-1">
<code class="keyword">
public


</code>
</td>

<td class="name">
<div>
<a class="anchor pull-right" href="#_prepend">#</a>
<code><a href="source-class-SDom.Dom.html#314-327">prepend</a>( <span> <span class="property-name">$content</span> </span> )</code>

<div class="description">
Insert content, specified by the parameter, to the beginning of immediate child nodes of all Element nodes in
the collection.








</div>
</div>
</td>
Expand Down
Loading

0 comments on commit 0bbc920

Please sign in to comment.