Completed
Branch scrutinizer (fbaa3d)
by Thomas
02:21
created

HtmlElementCss::removeCss()   B

Complexity

Conditions 6
Paths 5

Size

Total Lines 29
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 1 Features 0
Metric Value
cc 6
eloc 20
c 1
b 1
f 0
nc 5
nop 1
dl 0
loc 29
rs 8.9777
1
<?php
2
3
namespace Sulao\HtmlQuery;
4
5
/**
6
 * Class HtmlElementCss
7
 *
8
 * @package Sulao\HtmlQuery
9
 */
10
trait HtmlElementCss
11
{
12
    abstract public function hasAttr(string $attributeName);
13
    abstract public function setAttr(string $name, string $value);
14
    abstract public function getAttr(string $name);
15
    abstract public function removeAttr(string $attributeName);
16
17
    /**
18
     * Adds the specified class(es).
19
     *
20
     * @param string $className
21
     */
22
    public function addClass(string $className)
23
    {
24
        if (!$this->hasAttr('class')) {
25
            $this->setAttr('class', $className);
26
            return;
27
        }
28
29
        $classNames = Helper::splitClass($className);
30
        $class = (string) $this->getAttr('class');
31
        $classes = Helper::splitClass($class);
32
33
        $classArr = array_diff($classNames, $classes);
34
        if (empty($classArr)) {
35
            return;
36
        }
37
38
        $class .= ' ' . implode(' ', $classArr);
39
        $this->setAttr('class', $class);
40
    }
41
42
    /**
43
     * Determine whether the node is assigned the given class.
44
     *
45
     * @param string $className
46
     *
47
     * @return bool
48
     */
49
    public function hasClass(string $className)
50
    {
51
        $class = (string) $this->getAttr('class');
52
        $classes = Helper::splitClass($class);
53
54
        return in_array($className, $classes);
55
    }
56
57
    /**
58
     * Remove a single class, multiple classes, or all classes.
59
     *
60
     * @param string|null $className
61
     */
62
    public function removeClass(?string $className = null)
63
    {
64
        if (!$this->hasAttr('class')) {
65
            return;
66
        }
67
68
        if (is_null($className)) {
69
            $this->removeAttr('class');
70
            return;
71
        }
72
73
        $classNames = Helper::splitClass($className);
74
        $class = (string) $this->getAttr('class');
75
        $classes = Helper::splitClass($class);
76
77
        $classArr = array_diff($classes, $classNames);
78
        if (empty($classArr)) {
79
            $this->removeAttr('class');
80
            return;
81
        }
82
83
        $class = implode(' ', $classArr);
84
        $this->setAttr('class', $class);
85
    }
86
87
    /**
88
     * Add or remove class(es), depending on either the class's presence
89
     * or the value of the state argument.
90
     *
91
     * @param string $className
92
     * @param bool|null   $state
93
     */
94
    public function toggleClass(string $className, ?bool $state = null)
95
    {
96
        if (!is_null($state)) {
97
            if ($state) {
98
                $this->addClass($className);
99
            } else {
100
                $this->removeClass($className);
101
            }
102
            return;
103
        }
104
105
        if (!$this->hasAttr('class')) {
106
            $this->setAttr('class', $className);
107
            return;
108
        }
109
110
        $classNames = Helper::splitClass($className);
111
        $classes = Helper::splitClass((string) $this->getAttr('class'));
112
113
        $classArr = array_diff($classes, $classNames);
114
        $classArr = array_merge(
115
            $classArr,
116
            array_diff($classNames, $classes)
117
        );
118
        if (empty($classArr)) {
119
            $this->removeClass($className);
120
            return;
121
        }
122
123
        $this->setAttr('class', implode(' ', $classArr));
124
    }
125
126
    /**
127
     * Get the value of a computed style property
128
     *
129
     * @param string $name
130
     *
131
     * @return string|null
132
     */
133
    public function getCss(string $name)
134
    {
135
        $style = (string) $this->getAttr('style');
136
        $css = Helper::splitCss($style);
137
        if (!$css) {
138
            return null;
139
        }
140
141
        if (array_key_exists($name, $css)) {
142
            return $css[$name];
143
        }
144
145
        $arr = array_change_key_case($css, CASE_LOWER);
146
        $key = strtolower($name);
147
        if (array_key_exists($key, $arr)) {
148
            return $arr[$key];
149
        }
150
151
        return null;
152
    }
153
154
    /**
155
     * Set or Remove one CSS property.
156
     *
157
     * @param string      $name
158
     * @param string|null $value
159
     */
160
    public function setCss(string $name, ?string $value)
161
    {
162
        if ((string) $value === '') {
163
            $this->removeCss($name);
164
            return;
165
        }
166
167
        $style = (string) $this->getAttr('style');
168
        if (!$style) {
169
            $this->setAttr('style', $name . ': ' . $value . ';');
170
            return;
171
        }
172
173
        $css = Helper::splitCss($style);
174
        if (!array_key_exists($name, $css)) {
175
            $allKeys = array_keys($css);
176
            $arr = array_combine(
177
                $allKeys,
178
                array_map('strtolower', $allKeys)
179
            ) ?: [];
180
181
            $keys = array_keys($arr, strtolower($name));
182
            foreach ($keys as $key) {
183
                unset($css[$key]);
184
            }
185
        }
186
187
        $css[$name] = $value;
188
        $style = Helper::implodeCss($css);
189
        $this->setAttr('style', $style);
190
    }
191
192
    /**
193
     * Remove one CSS property.
194
     *
195
     * @param string $name
196
     */
197
    public function removeCss(string $name)
198
    {
199
        $style = (string) $this->getAttr('style');
200
        if (!$style) {
201
            return;
202
        }
203
204
        $css = Helper::splitCss($style);
205
        $removed = false;
206
        if (array_key_exists($name, $css)) {
207
            unset($css[$name]);
208
            $removed = true;
209
        } else {
210
            $allKeys = array_keys($css);
211
            $arr = array_combine(
212
                $allKeys,
213
                array_map('strtolower', $allKeys)
214
            ) ?: [];
215
216
            $keys = array_keys($arr, strtolower($name));
217
            foreach ($keys as $key) {
218
                unset($css[$key]);
219
                $removed = true;
220
            }
221
        }
222
223
        if ($removed) {
224
            $style = Helper::implodeCss($css);
225
            $this->setAttr('style', $style);
226
        }
227
    }
228
}
229