Node   A
last analyzed

Coupling/Cohesion

Components 1
Dependencies 1

Complexity

Total Complexity 32

Size/Duplication

Total Lines 229
Duplicated Lines 0 %

Test Coverage

Coverage 61.86%

Importance

Changes 0
Metric Value
wmc 32
lcom 1
cbo 1
dl 0
loc 229
ccs 60
cts 97
cp 0.6186
rs 9.6
c 0
b 0
f 0

17 Methods

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