• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

MyIntervals / PHP-CSS-Parser / 12999504056

27 Jan 2025 10:24PM UTC coverage: 44.039% (-7.0%) from 51.041%
12999504056

push

github

web-flow
[TASK] Drop expansion of shorthand properties (#838)

Those were deprecated in version 8.7.0.

Fixes #511

761 of 1728 relevant lines covered (44.04%)

10.34 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

82.61
/src/Value/Size.php
1
<?php
2

3
declare(strict_types=1);
4

5
namespace Sabberworm\CSS\Value;
6

7
use Sabberworm\CSS\OutputFormat;
8
use Sabberworm\CSS\Parsing\ParserState;
9
use Sabberworm\CSS\Parsing\UnexpectedEOFException;
10
use Sabberworm\CSS\Parsing\UnexpectedTokenException;
11

12
/**
13
 * A `Size` consists of a numeric `size` value and a unit.
14
 */
15
class Size extends PrimitiveValue
16
{
17
    /**
18
     * vh/vw/vm(ax)/vmin/rem are absolute insofar as they don’t scale to the immediate parent (only the viewport)
19
     *
20
     * @var array<int, string>
21
     */
22
    private const ABSOLUTE_SIZE_UNITS = [
23
        'px',
24
        'pt',
25
        'pc',
26
        'cm',
27
        'mm',
28
        'mozmm',
29
        'in',
30
        'vh',
31
        'dvh',
32
        'svh',
33
        'lvh',
34
        'vw',
35
        'vmin',
36
        'vmax',
37
        'rem',
38
    ];
39

40
    /**
41
     * @var array<int, string>
42
     */
43
    private const RELATIVE_SIZE_UNITS = ['%', 'em', 'ex', 'ch', 'fr'];
44

45
    /**
46
     * @var array<int, string>
47
     */
48
    private const NON_SIZE_UNITS = ['deg', 'grad', 'rad', 's', 'ms', 'turn', 'Hz', 'kHz'];
49

50
    /**
51
     * @var array<int, array<string, string>>|null
52
     */
53
    private static $SIZE_UNITS = null;
54

55
    /**
56
     * @var float
57
     */
58
    private $fSize;
59

60
    /**
61
     * @var string|null
62
     */
63
    private $sUnit;
64

65
    /**
66
     * @var bool
67
     */
68
    private $bIsColorComponent;
69

70
    /**
71
     * @param float|int|string $fSize
72
     * @param string|null $sUnit
73
     * @param bool $bIsColorComponent
74
     * @param int $lineNumber
75
     */
76
    public function __construct($fSize, $sUnit = null, $bIsColorComponent = false, $lineNumber = 0)
68✔
77
    {
78
        parent::__construct($lineNumber);
68✔
79
        $this->fSize = (float) $fSize;
68✔
80
        $this->sUnit = $sUnit;
68✔
81
        $this->bIsColorComponent = $bIsColorComponent;
68✔
82
    }
68✔
83

84
    /**
85
     * @param bool $bIsColorComponent
86
     *
87
     * @throws UnexpectedEOFException
88
     * @throws UnexpectedTokenException
89
     */
90
    public static function parse(ParserState $parserState, $bIsColorComponent = false): Size
63✔
91
    {
92
        $sSize = '';
63✔
93
        if ($parserState->comes('-')) {
63✔
94
            $sSize .= $parserState->consume('-');
5✔
95
        }
96
        while (\is_numeric($parserState->peek()) || $parserState->comes('.') || $parserState->comes('e', true)) {
63✔
97
            if ($parserState->comes('.')) {
63✔
98
                $sSize .= $parserState->consume('.');
15✔
99
            } elseif ($parserState->comes('e', true)) {
63✔
100
                $sLookahead = $parserState->peek(1, 1);
11✔
101
                if (\is_numeric($sLookahead) || $sLookahead === '+' || $sLookahead === '-') {
11✔
102
                    $sSize .= $parserState->consume(2);
2✔
103
                } else {
104
                    break; // Reached the unit part of the number like "em" or "ex"
11✔
105
                }
106
            } else {
107
                $sSize .= $parserState->consume(1);
63✔
108
            }
109
        }
110

111
        $sUnit = null;
63✔
112
        $aSizeUnits = self::getSizeUnits();
63✔
113
        foreach ($aSizeUnits as $iLength => &$aValues) {
63✔
114
            $sKey = \strtolower($parserState->peek($iLength));
63✔
115
            if (\array_key_exists($sKey, $aValues)) {
63✔
116
                if (($sUnit = $aValues[$sKey]) !== null) {
56✔
117
                    $parserState->consume($iLength);
56✔
118
                    break;
56✔
119
                }
120
            }
121
        }
122
        return new Size((float) $sSize, $sUnit, $bIsColorComponent, $parserState->currentLine());
63✔
123
    }
124

125
    /**
126
     * @return array<int, array<string, string>>
127
     */
128
    private static function getSizeUnits()
63✔
129
    {
130
        if (!\is_array(self::$SIZE_UNITS)) {
63✔
131
            self::$SIZE_UNITS = [];
×
132
            foreach (\array_merge(self::ABSOLUTE_SIZE_UNITS, self::RELATIVE_SIZE_UNITS, self::NON_SIZE_UNITS) as $val) {
×
133
                $iSize = \strlen($val);
×
134
                if (!isset(self::$SIZE_UNITS[$iSize])) {
×
135
                    self::$SIZE_UNITS[$iSize] = [];
×
136
                }
137
                self::$SIZE_UNITS[$iSize][\strtolower($val)] = $val;
×
138
            }
139

140
            \krsort(self::$SIZE_UNITS, SORT_NUMERIC);
×
141
        }
142

143
        return self::$SIZE_UNITS;
63✔
144
    }
145

146
    /**
147
     * @param string $sUnit
148
     */
149
    public function setUnit($sUnit): void
×
150
    {
151
        $this->sUnit = $sUnit;
×
152
    }
×
153

154
    /**
155
     * @return string|null
156
     */
157
    public function getUnit()
36✔
158
    {
159
        return $this->sUnit;
36✔
160
    }
161

162
    /**
163
     * @param float|int|string $fSize
164
     */
165
    public function setSize($fSize): void
2✔
166
    {
167
        $this->fSize = (float) $fSize;
2✔
168
    }
2✔
169

170
    /**
171
     * @return float
172
     */
173
    public function getSize()
9✔
174
    {
175
        return $this->fSize;
9✔
176
    }
177

178
    /**
179
     * @return bool
180
     */
181
    public function isColorComponent()
2✔
182
    {
183
        return $this->bIsColorComponent;
2✔
184
    }
185

186
    /**
187
     * Returns whether the number stored in this Size really represents a size (as in a length of something on screen).
188
     *
189
     * @return false if the unit an angle, a duration, a frequency or the number is a component in a Color object.
190
     */
191
    public function isSize(): bool
2✔
192
    {
193
        if (\in_array($this->sUnit, self::NON_SIZE_UNITS, true)) {
2✔
194
            return false;
1✔
195
        }
196
        return !$this->isColorComponent();
2✔
197
    }
198

199
    public function isRelative(): bool
2✔
200
    {
201
        if (\in_array($this->sUnit, self::RELATIVE_SIZE_UNITS, true)) {
2✔
202
            return true;
1✔
203
        }
204
        if ($this->sUnit === null && $this->fSize != 0) {
2✔
205
            return true;
2✔
206
        }
207
        return false;
2✔
208
    }
209

210
    public function __toString(): string
×
211
    {
212
        return $this->render(new OutputFormat());
×
213
    }
214

215
    public function render(OutputFormat $oOutputFormat): string
29✔
216
    {
217
        $l = \localeconv();
29✔
218
        $sPoint = \preg_quote($l['decimal_point'], '/');
29✔
219
        $sSize = \preg_match('/[\\d\\.]+e[+-]?\\d+/i', (string) $this->fSize)
29✔
220
            ? \preg_replace("/$sPoint?0+$/", '', \sprintf('%f', $this->fSize)) : (string) $this->fSize;
29✔
221
        return \preg_replace(["/$sPoint/", '/^(-?)0\\./'], ['.', '$1.'], $sSize)
29✔
222
            . ($this->sUnit ?? '');
29✔
223
    }
224
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc