Completed
Push — master ( afd04b...3b4c22 )
by Colin
10s
created

Node::getDepth()   A

Complexity

Conditions 1
Paths 1

Duplication

Lines 0
Ratio 0 %

Size

Total Lines 4
Code Lines 2

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
cc 1
eloc 2
nc 1
nop 0
crap 1
1
<?php
2
3
namespace League\CommonMark\Node;
4
5
use League\CommonMark\Util\ArrayCollection;
6
7
abstract class Node
8
{
9
    /**
10
     * @var int
11
     */
12
    protected $depth = 0;
13
14
    /**
15
     * @var Node|null
16
     */
17
    protected $parent;
18
19
    /**
20
     * @var Node|null
21
     */
22
    protected $previous;
23
24
    /**
25
     * @var Node|null
26
     */
27
    protected $next;
28
29
    /**
30
     * @var Node|null
31
     */
32
    protected $firstChild;
33
34
    /**
35
     * @var Node|null
36
     */
37
    protected $lastChild;
38
39
    /**
40
     * @return Node|null
41
     */
42
    public function previous()
43
    {
44
        return $this->previous;
45
    }
46
47
    /**
48
     * @return Node|null
49
     */
50 1935
    public function next()
51
    {
52 1935
        return $this->next;
53
    }
54
55
    /**
56
     * @return Node|null
57
     */
58 1950
    public function parent()
59
    {
60 1950
        return $this->parent;
61
    }
62
63
    /**
64
     * @param Node|null $node
65
     */
66 1968
    protected function setParent(Node $node = null)
67
    {
68 1968
        $this->parent = $node;
69 1968
        $this->depth = ($node === null) ? 0 : $node->depth + 1;
70 1968
    }
71
72
    /**
73
     * @param Node $sibling
74
     */
75 1494
    public function insertAfter(Node $sibling)
76
    {
77 1494
        $sibling->detach();
78 1494
        $sibling->next = $this->next;
79
80 1494
        if ($sibling->next) {
81 618
            $sibling->next->previous = $sibling;
82 206
        }
83
84 1494
        $sibling->previous = $this;
85 1494
        $this->next = $sibling;
86 1494
        $sibling->setParent($this->parent);
87
88 1494
        if (!$sibling->next) {
89 1494
            $sibling->parent->lastChild = $sibling;
90 498
        }
91 1494
    }
92
93
    /**
94
     * @param Node $sibling
95
     */
96
    public function insertBefore(Node $sibling)
97
    {
98
        $sibling->detach();
99
        $sibling->previous = $this->previous;
100
101
        if ($sibling->previous) {
102
            $sibling->previous->next = $sibling;
103
        }
104
105
        $sibling->next = $this;
106
        $this->previous = $sibling;
107
        $sibling->setParent($this->parent);
108
109
        if (!$sibling->previous) {
110
            $sibling->parent->firstChild = $sibling;
111
        }
112
    }
113
114 384
    public function replaceWith(Node $replacement)
115
    {
116 384
        $replacement->detach();
117 384
        $this->insertAfter($replacement);
118 384
        $this->detach();
119 384
    }
120
121 1968
    public function detach()
122
    {
123 1968
        if ($this->previous) {
124 657
            $this->previous->next = $this->next;
125 1968
        } elseif ($this->parent) {
126 534
            $this->parent->firstChild = $this->next;
127 178
        }
128
129 1968
        if ($this->next) {
130 666
            $this->next->previous = $this->previous;
131 1968
        } elseif ($this->parent) {
132 591
            $this->parent->lastChild = $this->previous;
133 197
        }
134
135 1968
        $this->parent = null;
136 1968
        $this->next = null;
137 1968
        $this->previous = null;
138 1968
        $this->depth = 0;
139 1968
    }
140
141
    /**
142
     * @return bool
143
     */
144
    abstract public function isContainer();
145
146
    /**
147
     * @return Node|null
148
     */
149 1941
    public function firstChild()
150
    {
151 1941
        return $this->firstChild;
152
    }
153
154
    /**
155
     * @return Node|null
156
     */
157 1806
    public function lastChild()
158
    {
159 1806
        return $this->lastChild;
160
    }
161
162
    /**
163
     * @return Node[]
164
     */
165 2031
    public function children()
166
    {
167 2031
        $children = [];
168 2031
        for ($current = $this->firstChild; null !== $current; $current = $current->next) {
169 1956
            $children[] = $current;
170 652
        }
171
172 2031
        return $children;
173
    }
174
175
    /**
176
     * @param Node $child
177
     */
178 1968
    public function appendChild(Node $child)
179
    {
180 1968
        if ($this->lastChild) {
181 1479
            $this->lastChild->insertAfter($child);
182 493
        } else {
183 1968
            $child->detach();
184 1968
            $child->setParent($this);
185 1968
            $this->lastChild = $this->firstChild = $child;
186
        }
187 1968
    }
188
189
    /**
190
     * @param Node $child
191
     */
192
    public function prependChild(Node $child)
193
    {
194
        if ($this->firstChild) {
195
            $this->firstChild->insertBefore($child);
196
        } else {
197
            $child->detach();
198
            $child->setParent($this);
199
            $this->lastChild = $this->firstChild = $child;
200
        }
201
    }
202
203
    /**
204
     * Detaches all child nodes of given node
205
     */
206
    public function detachChildren()
207
    {
208
        foreach ($this->children() as $children) {
209
            $children->setParent(null);
210
        }
211
        $this->firstChild = $this->lastChild = null;
212
    }
213
214
    /**
215
     * Replace all children of given node with collection of another
216
     *
217
     * @param array $children
218
     *
219
     * @return $this
220
     */
221
    public function replaceChildren(array $children)
222
    {
223
        if (!is_array($children) && !(is_object($children) && $children instanceof ArrayCollection)) {
224
            throw new \InvalidArgumentException(sprintf('Expect iterable, got %s', get_class($children)));
225
        }
226
227
        $this->detachChildren();
228
        foreach ($children as $item) {
229
            $this->appendChild($item);
230
        }
231
232
        return $this;
233
    }
234
235
    /**
236
     * @return int
237
     */
238 396
    public function getDepth()
239
    {
240 396
        return $this->depth;
241
    }
242
243
    /**
244
     * @return NodeWalker
245
     */
246 1941
    public function walker()
247
    {
248 1941
        return new NodeWalker($this);
249
    }
250
}
251