PluginProbe
MaxButtons – Create buttons / 7.10
MaxButtons – Create buttons v7.10
6.23 6.24 6.25 6.26 6.26.1 6.27 6.28 6.3 6.4 6.5 6.6 6.7 6.8 6.9 7.0 7.1 7.1.1 7.1.2 7.1.3 7.10 7.11 7.13 7.13.1 7.13.2 7.13.3 All 100 releases
maxbuttons / assets / libraries / scssphp / src / Node / Number.php

Number.php in MaxButtons – Create buttons 7.10, at assets/libraries/scssphp/src/Node/Number.php

331 lines 7.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * SCSSPHP
4 *
5 * @copyright 2012-2018 Leaf Corcoran
6 *
7 * @license http://opensource.org/licenses/MIT MIT
8 *
9 * @link http://leafo.github.io/scssphp
10 */
11
12 namespace Leafo\ScssPhp\Node;
13
14 use Leafo\ScssPhp\Compiler;
15 use Leafo\ScssPhp\Node;
16 use Leafo\ScssPhp\Type;
17
18 /**
19 * Dimension + optional units
20 *
21 * {@internal
22 * This is a work-in-progress.
23 *
24 * The \ArrayAccess interface is temporary until the migration is complete.
25 * }}
26 *
27 * @author Anthon Pang <anthon.pang@gmail.com>
28 */
29 class Number extends Node implements \ArrayAccess
30 {
31 /**
32 * @var integer
33 */
34 static public $precision = 10;
35
36 /**
37 * @see http://www.w3.org/TR/2012/WD-css3-values-20120308/
38 *
39 * @var array
40 */
41 static protected $unitTable = [
42 'in' => [
43 'in' => 1,
44 'pc' => 6,
45 'pt' => 72,
46 'px' => 96,
47 'cm' => 2.54,
48 'mm' => 25.4,
49 'q' => 101.6,
50 ],
51 'turn' => [
52 'deg' => 360,
53 'grad' => 400,
54 'rad' => 6.28318530717958647692528676, // 2 * M_PI
55 'turn' => 1,
56 ],
57 's' => [
58 's' => 1,
59 'ms' => 1000,
60 ],
61 'Hz' => [
62 'Hz' => 1,
63 'kHz' => 0.001,
64 ],
65 'dpi' => [
66 'dpi' => 1,
67 'dpcm' => 2.54,
68 'dppx' => 96,
69 ],
70 ];
71
72 /**
73 * @var integer|float
74 */
75 public $dimension;
76
77 /**
78 * @var array
79 */
80 public $units;
81
82 /**
83 * Initialize number
84 *
85 * @param mixed $dimension
86 * @param mixed $initialUnit
87 */
88 public function __construct($dimension, $initialUnit)
89 {
90 $this->type = Type::T_NUMBER;
91 $this->dimension = $dimension;
92 $this->units = is_array($initialUnit)
93 ? $initialUnit
94 : ($initialUnit ? [$initialUnit => 1]
95 : []);
96 }
97
98 /**
99 * Coerce number to target units
100 *
101 * @param array $units
102 *
103 * @return \Leafo\ScssPhp\Node\Number
104 */
105 public function coerce($units)
106 {
107 if ($this->unitless()) {
108 return new Number($this->dimension, $units);
109 }
110
111 $dimension = $this->dimension;
112
113 foreach (static::$unitTable['in'] as $unit => $conv) {
114 $from = isset($this->units[$unit]) ? $this->units[$unit] : 0;
115 $to = isset($units[$unit]) ? $units[$unit] : 0;
116 $factor = pow($conv, $from - $to);
117 $dimension /= $factor;
118 }
119
120 return new Number($dimension, $units);
121 }
122
123 /**
124 * Normalize number
125 *
126 * @return \Leafo\ScssPhp\Node\Number
127 */
128 public function normalize()
129 {
130 $dimension = $this->dimension;
131 $units = [];
132
133 $this->normalizeUnits($dimension, $units, 'in');
134
135 return new Number($dimension, $units);
136 }
137
138 /**
139 * {@inheritdoc}
140 */
141 public function offsetExists($offset)
142 {
143 if ($offset === -3) {
144 return $this->sourceColumn !== null;
145 }
146
147 if ($offset === -2) {
148 return $this->sourceLine !== null;
149 }
150
151 if ($offset === -1
152 || $offset === 0
153 || $offset === 1
154 || $offset === 2
155 ) {
156 return true;
157 }
158
159 return false;
160 }
161
162 /**
163 * {@inheritdoc}
164 */
165 public function offsetGet($offset)
166 {
167 switch ($offset) {
168 case -3:
169 return $this->sourceColumn;
170
171 case -2:
172 return $this->sourceLine;
173
174 case -1:
175 return $this->sourceIndex;
176
177 case 0:
178 return $this->type;
179
180 case 1:
181 return $this->dimension;
182
183 case 2:
184 return $this->units;
185 }
186 }
187
188 /**
189 * {@inheritdoc}
190 */
191 public function offsetSet($offset, $value)
192 {
193 if ($offset === 1) {
194 $this->dimension = $value;
195 } elseif ($offset === 2) {
196 $this->units = $value;
197 } elseif ($offset == -1) {
198 $this->sourceIndex = $value;
199 } elseif ($offset == -2) {
200 $this->sourceLine = $value;
201 } elseif ($offset == -3) {
202 $this->sourceColumn = $value;
203 }
204 }
205
206 /**
207 * {@inheritdoc}
208 */
209 public function offsetUnset($offset)
210 {
211 if ($offset === 1) {
212 $this->dimension = null;
213 } elseif ($offset === 2) {
214 $this->units = null;
215 } elseif ($offset === -1) {
216 $this->sourceIndex = null;
217 } elseif ($offset === -2) {
218 $this->sourceLine = null;
219 } elseif ($offset === -3) {
220 $this->sourceColumn = null;
221 }
222 }
223
224 /**
225 * Returns true if the number is unitless
226 *
227 * @return boolean
228 */
229 public function unitless()
230 {
231 return ! array_sum($this->units);
232 }
233
234 /**
235 * Returns unit(s) as the product of numerator units divided by the product of denominator units
236 *
237 * @return string
238 */
239 public function unitStr()
240 {
241 $numerators = [];
242 $denominators = [];
243
244 foreach ($this->units as $unit => $unitSize) {
245 if ($unitSize > 0) {
246 $numerators = array_pad($numerators, count($numerators) + $unitSize, $unit);
247 continue;
248 }
249
250 if ($unitSize < 0) {
251 $denominators = array_pad($denominators, count($denominators) + $unitSize, $unit);
252 continue;
253 }
254 }
255
256 return implode('*', $numerators) . (count($denominators) ? '/' . implode('*', $denominators) : '');
257 }
258
259 /**
260 * Output number
261 *
262 * @param \Leafo\ScssPhp\Compiler $compiler
263 *
264 * @return string
265 */
266 public function output(Compiler $compiler = null)
267 {
268 $dimension = round($this->dimension, static::$precision);
269
270 $units = array_filter($this->units, function ($unitSize) {
271 return $unitSize;
272 });
273
274 if (count($units) > 1 && array_sum($units) === 0) {
275 $dimension = $this->dimension;
276 $units = [];
277
278 $this->normalizeUnits($dimension, $units, 'in');
279
280 $dimension = round($dimension, static::$precision);
281 $units = array_filter($units, function ($unitSize) {
282 return $unitSize;
283 });
284 }
285
286 $unitSize = array_sum($units);
287
288 if ($compiler && ($unitSize > 1 || $unitSize < 0 || count($units) > 1)) {
289 $compiler->throwError((string) $dimension . $this->unitStr() . " isn't a valid CSS value.");
290 }
291
292 reset($units);
293 $unit = key($units);
294 $dimension = number_format($dimension, static::$precision, '.', '');
295
296 return (static::$precision ? rtrim(rtrim($dimension, '0'), '.') : $dimension) . $unit;
297 }
298
299 /**
300 * {@inheritdoc}
301 */
302 public function __toString()
303 {
304 return $this->output();
305 }
306
307 /**
308 * Normalize units
309 *
310 * @param integer|float $dimension
311 * @param array $units
312 * @param string $baseUnit
313 */
314 private function normalizeUnits(&$dimension, &$units, $baseUnit = 'in')
315 {
316 $dimension = $this->dimension;
317 $units = [];
318
319 foreach ($this->units as $unit => $exp) {
320 if (isset(static::$unitTable[$baseUnit][$unit])) {
321 $factor = pow(static::$unitTable[$baseUnit][$unit], $exp);
322
323 $unit = $baseUnit;
324 $dimension /= $factor;
325 }
326
327 $units[$unit] = $exp + (isset($units[$unit]) ? $units[$unit] : 0);
328 }
329 }
330 }
331