Node   A
last analyzed

Complexity

Total Complexity 33

Size/Duplication

Total Lines 246
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 33
lcom 1
cbo 1
dl 0
loc 246
ccs 88
cts 88
cp 1
rs 9.76
c 0
b 0
f 0

18 Methods

Rating   Name   Duplication   Size   Complexity  
A previous() 0 4 1
A next() 0 4 1
A parent() 0 4 1
A setParent() 0 5 2
A replaceWith() 0 6 1
A detach() 0 19 5
isContainer() 0 1 ?
A firstChild() 0 4 1
A lastChild() 0 4 1
A children() 0 9 2
A appendChild() 0 10 2
A prependChild() 0 10 2
A detachChildren() 0 7 2
A replaceChildren() 0 9 2
A getDepth() 0 4 1
A walker() 0 4 1
A insertAfter() 0 17 4
A insertBefore() 0 17 4
1
<?php
2
3
namespace League\CommonMark\Node;
4
5
abstract class Node
6
{
7
    /**
8
     * @var int
9
     */
10
    protected $depth = 0;
11
12
    /**
13
     * @var Node|null
14
     */
15
    protected $parent;
16
17
    /**
18
     * @var Node|null
19
     */
20
    protected $previous;
21
22
    /**
23
     * @var Node|null
24
     */
25
    protected $next;
26
27
    /**
28
     * @var Node|null
29
     */
30
    protected $firstChild;
31
32
    /**
33
     * @var Node|null
34
     */
35
    protected $lastChild;
36
37
    /**
38
     * @return Node|null
39
     */
40 417
    public function previous(): ?Node
41
    {
42 417
        return $this->previous;
43
    }
44
45
    /**
46
     * @return Node|null
47
     */
48 2052
    public function next(): ?Node
49
    {
50 2052
        return $this->next;
51
    }
52
53
    /**
54
     * @return Node|null
55
     */
56 2070
    public function parent(): ?Node
57
    {
58 2070
        return $this->parent;
59
    }
60
61
    /**
62
     * @param Node|null $node
63
     */
64 2097
    protected function setParent(Node $node = null)
65
    {
66 2097
        $this->parent = $node;
67 2097
        $this->depth = ($node === null) ? 0 : $node->depth + 1;
68 2097
    }
69
70
    /**
71
     * Inserts the $sibling node after $this
72
     *
73
     * @param Node $sibling
74
     */
75 1725
    public function insertAfter(Node $sibling)
76
    {
77 1725
        $sibling->detach();
78 1725
        $sibling->next = $this->next;
79
80 1725
        if ($sibling->next) {
81 696
            $sibling->next->previous = $sibling;
82
        }
83
84 1725
        $sibling->previous = $this;
85 1725
        $this->next = $sibling;
86 1725
        $sibling->setParent($this->parent);
87
88 1725
        if (!$sibling->next && $sibling->parent) {
89 1722
            $sibling->parent->lastChild = $sibling;
90
        }
91 1725
    }
92
93
    /**
94
     * Inserts the $sibling node before $this
95
     *
96
     * @param Node $sibling
97
     */
98 15
    public function insertBefore(Node $sibling)
99
    {
100 15
        $sibling->detach();
101 15
        $sibling->previous = $this->previous;
102
103 15
        if ($sibling->previous) {
104 6
            $sibling->previous->next = $sibling;
105
        }
106
107 15
        $sibling->next = $this;
108 15
        $this->previous = $sibling;
109 15
        $sibling->setParent($this->parent);
110
111 15
        if (!$sibling->previous && $sibling->parent) {
112 6
            $sibling->parent->firstChild = $sibling;
113
        }
114 15
    }
115
116 405
    public function replaceWith(Node $replacement)
117
    {
118 405
        $replacement->detach();
119 405
        $this->insertAfter($replacement);
120 405
        $this->detach();
121 405
    }
122
123 2094
    public function detach()
124
    {
125 2094
        if ($this->previous) {
126 1032
            $this->previous->next = $this->next;
127 2094
        } elseif ($this->parent) {
128 564
            $this->parent->firstChild = $this->next;
129
        }
130
131 2094
        if ($this->next) {
132 945
            $this->next->previous = $this->previous;
133 2094
        } elseif ($this->parent) {
134 909
            $this->parent->lastChild = $this->previous;
135
        }
136
137 2094
        $this->parent = null;
138 2094
        $this->next = null;
139 2094
        $this->previous = null;
140 2094
        $this->depth = 0;
141 2094
    }
142
143
    /**
144
     * @return bool
145
     */
146
    abstract public function isContainer(): bool;
147
148
    /**
149
     * @return Node|null
150
     */
151 2055
    public function firstChild(): ?Node
152
    {
153 2055
        return $this->firstChild;
154
    }
155
156
    /**
157
     * @return Node|null
158
     */
159 2040
    public function lastChild(): ?Node
160
    {
161 2040
        return $this->lastChild;
162
    }
163
164
    /**
165
     * @return Node[]
166
     */
167 2142
    public function children(): iterable
168
    {
169 2142
        $children = [];
170 2142
        for ($current = $this->firstChild; null !== $current; $current = $current->next) {
171 2058
            $children[] = $current;
172
        }
173
174 2142
        return $children;
175
    }
176
177
    /**
178
     * @param Node $child
179
     */
180 2082
    public function appendChild(Node $child)
181
    {
182 2082
        if ($this->lastChild) {
183 1707
            $this->lastChild->insertAfter($child);
184
        } else {
185 2082
            $child->detach();
186 2082
            $child->setParent($this);
187 2082
            $this->lastChild = $this->firstChild = $child;
188
        }
189 2082
    }
190
191
    /**
192
     * Adds $child as the very first child of $this
193
     *
194
     * @param Node $child
195
     */
196 6
    public function prependChild(Node $child)
197
    {
198 6
        if ($this->firstChild) {
199 3
            $this->firstChild->insertBefore($child);
200
        } else {
201 6
            $child->detach();
202 6
            $child->setParent($this);
203 6
            $this->lastChild = $this->firstChild = $child;
204
        }
205 6
    }
206
207
    /**
208
     * Detaches all child nodes of given node
209
     */
210 6
    public function detachChildren()
211
    {
212 6
        foreach ($this->children() as $children) {
213 6
            $children->setParent(null);
214
        }
215 6
        $this->firstChild = $this->lastChild = null;
216 6
    }
217
218
    /**
219
     * Replace all children of given node with collection of another
220
     *
221
     * @param iterable $children
222
     *
223
     * @return $this
224
     */
225 3
    public function replaceChildren(iterable $children)
226
    {
227 3
        $this->detachChildren();
228 3
        foreach ($children as $item) {
229 3
            $this->appendChild($item);
230
        }
231
232 3
        return $this;
233
    }
234
235
    /**
236
     * @return int
237
     */
238 405
    public function getDepth(): int
239
    {
240 405
        return $this->depth;
241
    }
242
243
    /**
244
     * @return NodeWalker
245
     */
246 2040
    public function walker(): NodeWalker
247
    {
248 2040
        return new NodeWalker($this);
249
    }
250
}
251