Completed
Push — master ( 187d75...242b2a )
by Michael
01:34
created

Node::trimContentRight()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 11
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 8
nc 4
nop 0
dl 0
loc 11
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace dokuwiki\plugin\prosemirror\schema;
4
5
/**
6
 * Class Node
7
 *
8
 * @package dokuwiki\plugin\prosemirror\schema
9
 * @link    http://prosemirror.net/ref.html#model.Node
10
 */
11
class Node implements \JsonSerializable
12
{
13
14
    /** @var  string The type of node that this is */
15
    protected $type;
16
17
    /** @var  Node[] holding the node's children */
18
    protected $content = [];
19
20
    /** @var  string For text nodes, this contains the node's text content. */
21
    protected $text = null;
22
23
    /** @var Mark[] The marks (things like whether it is emphasized or part of a link) associated with this node */
24
    protected $marks = [];
25
26
    /** @var array list of attributes */
27
    protected $attrs = [];
28
29
    /**
30
     * Node constructor.
31
     *
32
     * @param string $type
33
     */
34
    public function __construct($type)
35
    {
36
        $this->type = $type;
37
        if ($type == 'text') {
38
            $this->setText('');
39
        }
40
    }
41
42
    /**
43
     * @param Node $child
44
     */
45
    public function addChild(Node $child)
46
    {
47
        if ($this->type == 'text') {
48
            throw new \RuntimeException('TextNodes may not have children');
49
        }
50
        $this->content[] = $child;
51
    }
52
53
    /**
54
     * @param Mark $mark
55
     */
56
    public function addMark(Mark $mark)
57
    {
58
        $this->marks[] = $mark;
59
    }
60
61
    /**
62
     * @return string
63
     */
64
    public function getType()
65
    {
66
        return $this->type;
67
    }
68
69
    /**
70
     * @return string
71
     */
72
    public function getText()
73
    {
74
        return $this->text;
75
    }
76
77
    /**
78
     * @param string $text
79
     */
80
    public function setText($text)
81
    {
82
        if ($this->type != 'text') {
83
            throw new \RuntimeException('Non-TextNodes may not have text');
84
        }
85
        $this->text = $text;
86
    }
87
88
    /**
89
     * @param string $key   Attribute key to get or set
90
     * @param null   $value Attribute value to set, null to get
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $value is correct as it would always require null to be passed?
Loading history...
91
     *
92
     * @return $this|mixed Either the wanted value or the Node itself
93
     */
94
    public function attr($key, $value = null)
95
    {
96
        if (is_null($value)) {
97
            if (isset($this->attrs[$key])) {
98
                return $this->attrs[$key];
99
            } else {
100
                return null;
101
            }
102
        }
103
104
        $this->attrs[$key] = $value;
105
        return $this;
106
    }
107
108
    /**
109
     * Specify data which should be serialized to JSON
110
     *
111
     * @link  http://php.net/manual/en/jsonserializable.jsonserialize.php
112
     * @return mixed data which can be serialized by <b>json_encode</b>,
113
     * which is a value of any type other than a resource.
114
     * @since 5.4.0
115
     */
116
    function jsonSerialize()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
117
    {
118
        $json = [
119
            'type' => $this->type,
120
        ];
121
        if ($this->type == 'text') {
122
            $json['text'] = $this->text;
123
        } elseif ($this->content) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->content of type dokuwiki\plugin\prosemirror\schema\Node[] is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
124
            $json['content'] = $this->content;
125
        }
126
127
        if ($this->marks) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->marks of type dokuwiki\plugin\prosemirror\schema\Mark[] is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
128
            $json['marks'] = $this->marks;
129
        }
130
        if ($this->attrs) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->attrs of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
131
            $json['attrs'] = $this->attrs;
132
        }
133
134
        return $json;
135
    }
136
137
    /**
138
     * Check if any child nodes have been added to this node
139
     *
140
     * @return bool
141
     */
142
    public function hasContent() {
143
        return !empty($this->content);
144
    }
145
146
    /**
147
     * Trim all whitespace from the beginning of this node's content
148
     *
149
     * If this is a text-node then this node's text is left-trimmed
150
     *
151
     * If the first node in the content is afterwards only an empty string, then it is removed
152
     *
153
     * @return void
154
     */
155
    public function trimContentLeft() {
156
        if ($this->hasContent()) {
157
            $this->content[0]->trimContentLeft();
158
            if ($this->content[0]->getText() === '') {
159
                array_shift($this->content);
160
            }
161
            return;
162
        }
163
        if ($this->text !== null) {
164
            $this->text = ltrim($this->text);
165
        }
166
    }
167
168
    /**
169
     * Trim all whitespace from the end of this node's content
170
     *
171
     * If this is a text-node then this node's text is right-trimmed
172
     *
173
     * If the last node in the content is afterwards only an empty string, then it is removed
174
     *
175
     * @return void
176
     */
177
    public function trimContentRight() {
178
        if ($this->hasContent()) {
179
            $contentLength = count($this->content) - 1;
180
            $this->content[$contentLength]->trimContentRight();
181
            if ($this->content[$contentLength]->getText() === '') {
182
                array_pop($this->content);
183
            }
184
            return;
185
        }
186
        if ($this->text !== null) {
187
            $this->text = rtrim($this->text);
188
        }
189
    }
190
}
191