Skip to content

Commit 2e59a97

Browse files
committed
support for bulk node manipulation using childnodes
1 parent 62f99c9 commit 2e59a97

File tree

3 files changed

+162
-7
lines changed

3 files changed

+162
-7
lines changed

src/Contracts/DomElementInterface.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,11 @@ public function getNextSibling(): ?DomElementInterface;
2121

2222
public function getChildNodes(): DomNodeIterator;
2323

24-
public function setParentNode(DomElementInterface $node = null): ?DomElementInterface;
24+
public function setParentNode(DomElementInterface $node = null): DomElementInterface;
2525

26-
public function setPrevSibling(DomElementInterface $node = null): ?DomElementInterface;
26+
public function setPrevSibling(DomElementInterface $node = null): DomElementInterface;
2727

28-
public function setNextSibling(DomElementInterface $node = null): ?DomElementInterface;
28+
public function setNextSibling(DomElementInterface $node = null): DomElementInterface;
2929

3030
/**
3131
* Append a new child node to current node.

src/DomNodeIterator.php

Lines changed: 152 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
use PhpTemplates\Dom\Contracts\DomElementInterface;
66

7-
class DomNodeIterator implements \Iterator
7+
class DomNodeIterator implements \Iterator, DomElementInterface
88
{
99
public ?DomElementInterface $head = null;
1010
private ?DomElementInterface $current = null;
@@ -105,4 +105,155 @@ public function __toString(): string
105105

106106
return $output;
107107
}
108+
109+
public function getParentNode(): ?DomElementInterface
110+
{
111+
if ($this->head) {
112+
return $this->head->getParentNode();
113+
}
114+
}
115+
116+
public function getPrevSibling(): ?DomElementInterface
117+
{
118+
if ($this->head) {
119+
return $this->head->getPrevSibling();
120+
}
121+
}
122+
123+
public function getNextSibling(): ?DomElementInterface
124+
{
125+
if ($this->head) {
126+
return $this->head->getNextSibling();
127+
}
128+
}
129+
130+
public function getChildNodes(): DomNodeIterator
131+
{
132+
if ($this->head) {
133+
return $this->head->getChildNodes();
134+
}
135+
136+
return new DomNodeIterator;
137+
}
138+
139+
public function setParentNode(DomElementInterface $node = null): DomElementInterface
140+
{
141+
$this->rewind();
142+
while ($elNode = $this->current) {
143+
$this->next();
144+
$elNode->setParentNode($node);
145+
}
146+
147+
return $this;
148+
}
149+
150+
public function setPrevSibling(DomElementInterface $node = null): DomElementInterface
151+
{
152+
$this->rewind();
153+
while ($elNode = $this->current) {
154+
$this->next();
155+
$elNode->setPrevSibling($node);
156+
}
157+
158+
return $this;
159+
}
160+
161+
public function setNextSibling(DomElementInterface $node = null): DomElementInterface
162+
{
163+
$this->rewind();
164+
while ($elNode = $this->current) {
165+
$this->next();
166+
$elNode->setNextSibling($node);
167+
}
168+
169+
return $this;
170+
}
171+
172+
public function appendChild(DomElementInterface $node): DomElementInterface
173+
{
174+
$this->rewind();
175+
while ($elNode = $this->current) {
176+
$this->next();
177+
$elNode->appendChild($node);
178+
}
179+
180+
return $this;
181+
}
182+
183+
public function prependChild(DomElementInterface $node): DomElementInterface
184+
{
185+
$this->rewind();
186+
while ($elNode = $this->current) {
187+
$this->next();
188+
$elNode->prependChild($node);
189+
}
190+
191+
return $this;
192+
}
193+
194+
public function insertBefore(DomElementInterface $node): DomElementInterface
195+
{
196+
$this->rewind();
197+
while ($elNode = $this->current) {
198+
$this->next();
199+
$elNode->insertBefore($node);
200+
}
201+
202+
return $this;
203+
}
204+
205+
public function appendTo(DomElementInterface $node): DomElementInterface
206+
{
207+
$this->rewind();
208+
while ($elNode = $this->current) {
209+
$this->next();
210+
$elNode->appendTo($node);
211+
}
212+
213+
return $this;
214+
}
215+
216+
public function insertAfter(DomElementInterface $node): DomElementInterface
217+
{
218+
$this->rewind();
219+
while ($elNode = $this->current) {
220+
$this->next();
221+
$elNode->insertAfter($node);
222+
}
223+
224+
return $this;
225+
}
226+
227+
public function before(DomElementInterface $node): DomElementInterface
228+
{
229+
$this->rewind();
230+
while ($elNode = $this->current) {
231+
$this->next();
232+
$elNode->before($node);
233+
}
234+
235+
return $this;
236+
}
237+
238+
public function after(DomElementInterface $node): DomElementInterface
239+
{
240+
$this->rewind();
241+
while ($elNode = $this->current) {
242+
$this->next();
243+
$elNode->after($node);
244+
}
245+
246+
return $this;
247+
}
248+
249+
public function detach(): DomElementInterface
250+
{
251+
$this->rewind();
252+
while ($elNode = $this->current) {
253+
$this->next();
254+
$elNode->detach();
255+
}
256+
257+
return $this;
258+
}
108259
}

src/Traits/DomElement.php

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,21 +71,21 @@ public function getChildNodes(): DomNodeIterator
7171
return $this->childNodes;
7272
}
7373

74-
public function setParentNode(DomElementInterface $node = null): ?DomElementInterface
74+
public function setParentNode(DomElementInterface $node = null): DomElementInterface
7575
{
7676
$this->parentNode = $node;
7777

7878
return $this;
7979
}
8080

81-
public function setPrevSibling(DomElementInterface $node = null): ?DomElementInterface
81+
public function setPrevSibling(DomElementInterface $node = null): DomElementInterface
8282
{
8383
$this->prevSibling = $node;
8484

8585
return $this;
8686
}
8787

88-
public function setNextSibling(DomElementInterface $node = null): ?DomElementInterface
88+
public function setNextSibling(DomElementInterface $node = null): DomElementInterface
8989
{
9090
$this->nextSibling = $node;
9191

@@ -205,10 +205,14 @@ public function after(DomElementInterface $node): DomElementInterface
205205

206206
public function detach(): DomElementInterface
207207
{
208+
$parent = $this->getParentNode();
208209
$prev = $this->getPrevSibling();
209210
$next = $this->getNextSibling();
210211
$prev && $prev->setNextSibling($next);
211212
$next && $next->setPrevSibling($prev);
213+
if ($parent && $parent->getChildNodes()->head === $this) {
214+
$parent->getChildNodes()->head = $next;
215+
}
212216
$this->setParentNode(null);
213217
$this->setPrevSibling(null);
214218
$this->setNextSibling(null);

0 commit comments

Comments
 (0)