Issues (109)

schema/Node.php (5 issues)

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
    /** @var  string The type of node that this is */
14
    protected $type;
15
16
    /** @var  Node[] holding the node's children */
17
    protected $content = [];
18
19
    /** @var  string For text nodes, this contains the node's text content. */
20
    protected $text;
21
22
    /** @var Mark[] The marks (things like whether it is emphasized or part of a link) associated with this node */
23
    protected $marks = [];
24
25
    /** @var array list of attributes */
26
    protected $attrs = [];
27
28
    /**
29
     * Node constructor.
30
     *
31
     * @param string $type
32
     */
33
    public function __construct($type)
34
    {
35
        $this->type = $type;
36
        if ($type == 'text') {
37
            $this->setText('');
38
        }
39
    }
40
41
    /**
42
     * @param Node $child
43
     */
44
    public function addChild(Node $child)
45
    {
46
        if ($this->type == 'text') {
47
            throw new \RuntimeException('TextNodes may not have children');
48
        }
49
        $this->content[] = $child;
50
    }
51
52
    /**
53
     * @param Mark $mark
54
     */
55
    public function addMark(Mark $mark)
56
    {
57
        $this->marks[] = $mark;
58
    }
59
60
    /**
61
     * @return string
62
     */
63
    public function getType()
64
    {
65
        return $this->type;
66
    }
67
68
    /**
69
     * @return string
70
     */
71
    public function getText()
72
    {
73
        return $this->text;
74
    }
75
76
    /**
77
     * @param string $text
78
     */
79
    public function setText($text)
80
    {
81
        if ($this->type != 'text') {
82
            throw new \RuntimeException('Non-TextNodes may not have text');
83
        }
84
        $this->text = $text;
85
    }
86
87
    /**
88
     * @param string $key   Attribute key to get or set
89
     * @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...
90
     *
91
     * @return $this|mixed Either the wanted value or the Node itself
92
     */
93
    public function attr($key, $value = null)
94
    {
95
        if (is_null($value)) {
0 ignored issues
show
The condition is_null($value) is always true.
Loading history...
96
            if (isset($this->attrs[$key])) {
97
                return $this->attrs[$key];
98
            } else {
99
                return null;
100
            }
101
        }
102
103
        $this->attrs[$key] = $value;
104
        return $this;
105
    }
106
107
    /**
108
     * Specify data which should be serialized to JSON
109
     *
110
     * @link  http://php.net/manual/en/jsonserializable.jsonserialize.php
111
     * @return mixed data which can be serialized by <b>json_encode</b>,
112
     * which is a value of any type other than a resource.
113
     * @since 5.4.0
114
     */
115
    public function jsonSerialize()
116
    {
117
        $json = [
118
            'type' => $this->type,
119
        ];
120
        if ($this->type == 'text') {
121
            $json['text'] = $this->text;
122
        } 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...
123
            $json['content'] = $this->content;
124
        }
125
126
        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...
127
            $json['marks'] = $this->marks;
128
        }
129
        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...
130
            $json['attrs'] = $this->attrs;
131
        }
132
133
        return $json;
134
    }
135
136
    /**
137
     * Check if any child nodes have been added to this node
138
     *
139
     * @return bool
140
     */
141
    public function hasContent()
142
    {
143
        return $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
    {
157
        if ($this->hasContent()) {
158
            $this->content[0]->trimContentLeft();
159
            if ($this->content[0]->getText() === '') {
160
                array_shift($this->content);
161
            }
162
            return;
163
        }
164
        if ($this->text !== null) {
165
            $this->text = ltrim($this->text);
166
        }
167
    }
168
169
    /**
170
     * Trim all whitespace from the end of this node's content
171
     *
172
     * If this is a text-node then this node's text is right-trimmed
173
     *
174
     * If the last node in the content is afterwards only an empty string, then it is removed
175
     *
176
     * @return void
177
     */
178
    public function trimContentRight()
179
    {
180
        if ($this->hasContent()) {
181
            $contentLength = count($this->content) - 1;
182
            $this->content[$contentLength]->trimContentRight();
183
            if ($this->content[$contentLength]->getText() === '') {
184
                array_pop($this->content);
185
            }
186
            return;
187
        }
188
        if ($this->text !== null) {
189
            $this->text = rtrim($this->text);
190
        }
191
    }
192
}
193