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

MyIntervals / PHP-CSS-Parser / 20772587941

07 Jan 2026 06:19AM UTC coverage: 70.316% (+1.1%) from 69.191%
20772587941

Pull #1442

github

web-flow
Merge 44fbf83d1 into 2b61cd568
Pull Request #1442: [FEATURE] Convert legacy color notation to modern css 4 notation

4 of 9 new or added lines in 2 files covered. (44.44%)

65 existing lines in 7 files now uncovered.

1400 of 1991 relevant lines covered (70.32%)

32.28 hits per line

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

97.16
/src/OutputFormat.php
1
<?php
2

3
declare(strict_types=1);
4

5
namespace Sabberworm\CSS;
6

7
final class OutputFormat
8
{
9
    /**
10
     * Value format: `"` means double-quote, `'` means single-quote
11
     *
12
     * @var non-empty-string
13
     */
14
    private $stringQuotingType = '"';
15

16
    /**
17
     * Output RGB colors in hash notation if possible
18
     *
19
     * @var bool
20
     */
21
    private $usesRgbHashNotation = true;
22

23
    /**
24
     * Output RGB colors in CSS 4 notation if possible
25
     *
26
     * @var bool
27
     */
28
    private $usesModernColorSyntax = false;
29

30
    /**
31
     * Declaration format
32
     *
33
     * Semicolon after the last rule of a declaration block can be omitted. To do that, set this false.
34
     *
35
     * @var bool
36
     */
37
    private $renderSemicolonAfterLastRule = true;
38

39
    /**
40
     * Spacing
41
     * Note that these strings are not sanity-checked: the value should only consist of whitespace
42
     * Any newline character will be indented according to the current level.
43
     * The triples (After, Before, Between) can be set using a wildcard
44
     * (e.g. `$outputFormat->set('Space*Rules', "\n");`)
45
     *
46
     * @var string
47
     */
48
    private $spaceAfterRuleName = ' ';
49

50
    /**
51
     * @var string
52
     */
53
    private $spaceBeforeRules = '';
54

55
    /**
56
     * @var string
57
     */
58
    private $spaceAfterRules = '';
59

60
    /**
61
     * @var string
62
     */
63
    private $spaceBetweenRules = '';
64

65
    /**
66
     * @var string
67
     */
68
    private $spaceBeforeBlocks = '';
69

70
    /**
71
     * @var string
72
     */
73
    private $spaceAfterBlocks = '';
74

75
    /**
76
     * @var string
77
     */
78
    private $spaceBetweenBlocks = "\n";
79

80
    /**
81
     * Content injected in and around at-rule blocks.
82
     *
83
     * @var string
84
     */
85
    private $contentBeforeAtRuleBlock = '';
86

87
    /**
88
     * @var string
89
     */
90
    private $contentAfterAtRuleBlock = '';
91

92
    /**
93
     * This is what’s printed before and after the comma if a declaration block contains multiple selectors.
94
     *
95
     * @var string
96
     */
97
    private $spaceBeforeSelectorSeparator = '';
98

99
    /**
100
     * @var string
101
     */
102
    private $spaceAfterSelectorSeparator = ' ';
103

104
    /**
105
     * This is what’s inserted before the separator in value lists, by default.
106
     *
107
     * @var string
108
     */
109
    private $spaceBeforeListArgumentSeparator = '';
110

111
    /**
112
     * Keys are separators (e.g. `,`).  Values are the space sequence to insert, or an empty string.
113
     *
114
     * @var array<non-empty-string, string>
115
     */
116
    private $spaceBeforeListArgumentSeparators = [];
117

118
    /**
119
     * This is what’s inserted after the separator in value lists, by default.
120
     *
121
     * @var string
122
     */
123
    private $spaceAfterListArgumentSeparator = '';
124

125
    /**
126
     * Keys are separators (e.g. `,`).  Values are the space sequence to insert, or an empty string.
127
     *
128
     * @var array<non-empty-string, string>
129
     */
130
    private $spaceAfterListArgumentSeparators = [];
131

132
    /**
133
     * @var string
134
     */
135
    private $spaceBeforeOpeningBrace = ' ';
136

137
    /**
138
     * Content injected in and around declaration blocks.
139
     *
140
     * @var string
141
     */
142
    private $contentBeforeDeclarationBlock = '';
143

144
    /**
145
     * @var string
146
     */
147
    private $contentAfterDeclarationBlockSelectors = '';
148

149
    /**
150
     * @var string
151
     */
152
    private $contentAfterDeclarationBlock = '';
153

154
    /**
155
     * Indentation character(s) per level. Only applicable if newlines are used in any of the spacing settings.
156
     *
157
     * @var string
158
     */
159
    private $indentation = "\t";
160

161
    /**
162
     * Output exceptions.
163
     *
164
     * @var bool
165
     */
166
    private $shouldIgnoreExceptions = false;
167

168
    /**
169
     * Render comments for lists and RuleSets
170
     *
171
     * @var bool
172
     */
173
    private $shouldRenderComments = false;
174

175
    /**
176
     * @var OutputFormatter|null
177
     */
178
    private $outputFormatter;
179

180
    /**
181
     * @var OutputFormat|null
182
     */
183
    private $nextLevelFormat;
184

185
    /**
186
     * @var int<0, max>
187
     */
188
    private $indentationLevel = 0;
189

190
    /**
191
     * @return non-empty-string
192
     *
193
     * @internal
194
     */
195
    public function getStringQuotingType(): string
2✔
196
    {
197
        return $this->stringQuotingType;
2✔
198
    }
199

200
    /**
201
     * @param non-empty-string $quotingType
202
     *
203
     * @return $this fluent interface
204
     */
205
    public function setStringQuotingType(string $quotingType): self
2✔
206
    {
207
        $this->stringQuotingType = $quotingType;
2✔
208

209
        return $this;
2✔
210
    }
211

212
    /**
213
     * @internal
214
     */
215
    public function usesRgbHashNotation(): bool
3✔
216
    {
217
        return $this->usesRgbHashNotation;
3✔
218
    }
219

220
    /**
221
     * @return $this fluent interface
222
     */
223
    public function setRGBHashNotation(bool $usesRgbHashNotation): self
3✔
224
    {
225
        $this->usesRgbHashNotation = $usesRgbHashNotation;
3✔
226

227
        return $this;
3✔
228
    }
229

230
    /**
231
     * @internal
232
     */
NEW
233
    public function usesModernColorSyntax(): bool
×
234
    {
NEW
235
        return $this->usesModernColorSyntax;
×
236
    }
237

238
    /**
239
     * @return $this fluent interface
240
     */
NEW
241
    public function setUseModernColorSyntax(bool $usesModernColorSyntax): self
×
242
    {
NEW
243
        $this->usesModernColorSyntax = $usesModernColorSyntax;
×
244

NEW
245
        return $this;
×
246
    }
247

248
    /**
249
     * @internal
250
     */
251
    public function shouldRenderSemicolonAfterLastRule(): bool
4✔
252
    {
253
        return $this->renderSemicolonAfterLastRule;
4✔
254
    }
255

256
    /**
257
     * @return $this fluent interface
258
     */
259
    public function setSemicolonAfterLastRule(bool $renderSemicolonAfterLastRule): self
17✔
260
    {
261
        $this->renderSemicolonAfterLastRule = $renderSemicolonAfterLastRule;
17✔
262

263
        return $this;
17✔
264
    }
265

266
    /**
267
     * @internal
268
     */
269
    public function getSpaceAfterRuleName(): string
5✔
270
    {
271
        return $this->spaceAfterRuleName;
5✔
272
    }
273

274
    /**
275
     * @return $this fluent interface
276
     */
277
    public function setSpaceAfterRuleName(string $whitespace): self
17✔
278
    {
279
        $this->spaceAfterRuleName = $whitespace;
17✔
280

281
        return $this;
17✔
282
    }
283

284
    /**
285
     * @internal
286
     */
287
    public function getSpaceBeforeRules(): string
4✔
288
    {
289
        return $this->spaceBeforeRules;
4✔
290
    }
291

292
    /**
293
     * @return $this fluent interface
294
     */
295
    public function setSpaceBeforeRules(string $whitespace): self
29✔
296
    {
297
        $this->spaceBeforeRules = $whitespace;
29✔
298

299
        return $this;
29✔
300
    }
301

302
    /**
303
     * @internal
304
     */
305
    public function getSpaceAfterRules(): string
4✔
306
    {
307
        return $this->spaceAfterRules;
4✔
308
    }
309

310
    /**
311
     * @return $this fluent interface
312
     */
313
    public function setSpaceAfterRules(string $whitespace): self
29✔
314
    {
315
        $this->spaceAfterRules = $whitespace;
29✔
316

317
        return $this;
29✔
318
    }
319

320
    /**
321
     * @internal
322
     */
323
    public function getSpaceBetweenRules(): string
4✔
324
    {
325
        return $this->spaceBetweenRules;
4✔
326
    }
327

328
    /**
329
     * @return $this fluent interface
330
     */
331
    public function setSpaceBetweenRules(string $whitespace): self
29✔
332
    {
333
        $this->spaceBetweenRules = $whitespace;
29✔
334

335
        return $this;
29✔
336
    }
337

338
    /**
339
     * @internal
340
     */
341
    public function getSpaceBeforeBlocks(): string
4✔
342
    {
343
        return $this->spaceBeforeBlocks;
4✔
344
    }
345

346
    /**
347
     * @return $this fluent interface
348
     */
349
    public function setSpaceBeforeBlocks(string $whitespace): self
29✔
350
    {
351
        $this->spaceBeforeBlocks = $whitespace;
29✔
352

353
        return $this;
29✔
354
    }
355

356
    /**
357
     * @internal
358
     */
359
    public function getSpaceAfterBlocks(): string
4✔
360
    {
361
        return $this->spaceAfterBlocks;
4✔
362
    }
363

364
    /**
365
     * @return $this fluent interface
366
     */
367
    public function setSpaceAfterBlocks(string $whitespace): self
29✔
368
    {
369
        $this->spaceAfterBlocks = $whitespace;
29✔
370

371
        return $this;
29✔
372
    }
373

374
    /**
375
     * @internal
376
     */
377
    public function getSpaceBetweenBlocks(): string
4✔
378
    {
379
        return $this->spaceBetweenBlocks;
4✔
380
    }
381

382
    /**
383
     * @return $this fluent interface
384
     */
385
    public function setSpaceBetweenBlocks(string $whitespace): self
29✔
386
    {
387
        $this->spaceBetweenBlocks = $whitespace;
29✔
388

389
        return $this;
29✔
390
    }
391

392
    /**
393
     * @internal
394
     */
395
    public function getContentBeforeAtRuleBlock(): string
2✔
396
    {
397
        return $this->contentBeforeAtRuleBlock;
2✔
398
    }
399

400
    /**
401
     * @return $this fluent interface
402
     */
403
    public function setBeforeAtRuleBlock(string $content): self
2✔
404
    {
405
        $this->contentBeforeAtRuleBlock = $content;
2✔
406

407
        return $this;
2✔
408
    }
409

410
    /**
411
     * @internal
412
     */
413
    public function getContentAfterAtRuleBlock(): string
2✔
414
    {
415
        return $this->contentAfterAtRuleBlock;
2✔
416
    }
417

418
    /**
419
     * @return $this fluent interface
420
     */
421
    public function setAfterAtRuleBlock(string $content): self
2✔
422
    {
423
        $this->contentAfterAtRuleBlock = $content;
2✔
424

425
        return $this;
2✔
426
    }
427

428
    /**
429
     * @internal
430
     */
431
    public function getSpaceBeforeSelectorSeparator(): string
2✔
432
    {
433
        return $this->spaceBeforeSelectorSeparator;
2✔
434
    }
435

436
    /**
437
     * @return $this fluent interface
438
     */
439
    public function setSpaceBeforeSelectorSeparator(string $whitespace): self
2✔
440
    {
441
        $this->spaceBeforeSelectorSeparator = $whitespace;
2✔
442

443
        return $this;
2✔
444
    }
445

446
    /**
447
     * @internal
448
     */
449
    public function getSpaceAfterSelectorSeparator(): string
4✔
450
    {
451
        return $this->spaceAfterSelectorSeparator;
4✔
452
    }
453

454
    /**
455
     * @return $this fluent interface
456
     */
457
    public function setSpaceAfterSelectorSeparator(string $whitespace): self
16✔
458
    {
459
        $this->spaceAfterSelectorSeparator = $whitespace;
16✔
460

461
        return $this;
16✔
462
    }
463

464
    /**
465
     * @internal
466
     */
467
    public function getSpaceBeforeListArgumentSeparator(): string
2✔
468
    {
469
        return $this->spaceBeforeListArgumentSeparator;
2✔
470
    }
471

472
    /**
473
     * @return $this fluent interface
474
     */
475
    public function setSpaceBeforeListArgumentSeparator(string $whitespace): self
2✔
476
    {
477
        $this->spaceBeforeListArgumentSeparator = $whitespace;
2✔
478

479
        return $this;
2✔
480
    }
481

482
    /**
483
     * @return array<non-empty-string, string>
484
     *
485
     * @internal
486
     */
487
    public function getSpaceBeforeListArgumentSeparators(): array
2✔
488
    {
489
        return $this->spaceBeforeListArgumentSeparators;
2✔
490
    }
491

492
    /**
493
     * @param array<non-empty-string, string> $separatorSpaces
494
     *
495
     * @return $this fluent interface
496
     */
497
    public function setSpaceBeforeListArgumentSeparators(array $separatorSpaces): self
2✔
498
    {
499
        $this->spaceBeforeListArgumentSeparators = $separatorSpaces;
2✔
500

501
        return $this;
2✔
502
    }
503

504
    /**
505
     * @internal
506
     */
507
    public function getSpaceAfterListArgumentSeparator(): string
2✔
508
    {
509
        return $this->spaceAfterListArgumentSeparator;
2✔
510
    }
511

512
    /**
513
     * @return $this fluent interface
514
     */
515
    public function setSpaceAfterListArgumentSeparator(string $whitespace): self
2✔
516
    {
517
        $this->spaceAfterListArgumentSeparator = $whitespace;
2✔
518

519
        return $this;
2✔
520
    }
521

522
    /**
523
     * @return array<non-empty-string, string>
524
     *
525
     * @internal
526
     */
527
    public function getSpaceAfterListArgumentSeparators(): array
4✔
528
    {
529
        return $this->spaceAfterListArgumentSeparators;
4✔
530
    }
531

532
    /**
533
     * @param array<non-empty-string, string> $separatorSpaces
534
     *
535
     * @return $this fluent interface
536
     */
537
    public function setSpaceAfterListArgumentSeparators(array $separatorSpaces): self
15✔
538
    {
539
        $this->spaceAfterListArgumentSeparators = $separatorSpaces;
15✔
540

541
        return $this;
15✔
542
    }
543

544
    /**
545
     * @internal
546
     */
547
    public function getSpaceBeforeOpeningBrace(): string
4✔
548
    {
549
        return $this->spaceBeforeOpeningBrace;
4✔
550
    }
551

552
    /**
553
     * @return $this fluent interface
554
     */
555
    public function setSpaceBeforeOpeningBrace(string $whitespace): self
16✔
556
    {
557
        $this->spaceBeforeOpeningBrace = $whitespace;
16✔
558

559
        return $this;
16✔
560
    }
561

562
    /**
563
     * @internal
564
     */
565
    public function getContentBeforeDeclarationBlock(): string
2✔
566
    {
567
        return $this->contentBeforeDeclarationBlock;
2✔
568
    }
569

570
    /**
571
     * @return $this fluent interface
572
     */
573
    public function setBeforeDeclarationBlock(string $content): self
2✔
574
    {
575
        $this->contentBeforeDeclarationBlock = $content;
2✔
576

577
        return $this;
2✔
578
    }
579

580
    /**
581
     * @internal
582
     */
583
    public function getContentAfterDeclarationBlockSelectors(): string
2✔
584
    {
585
        return $this->contentAfterDeclarationBlockSelectors;
2✔
586
    }
587

588
    /**
589
     * @return $this fluent interface
590
     */
591
    public function setAfterDeclarationBlockSelectors(string $content): self
2✔
592
    {
593
        $this->contentAfterDeclarationBlockSelectors = $content;
2✔
594

595
        return $this;
2✔
596
    }
597

598
    /**
599
     * @internal
600
     */
601
    public function getContentAfterDeclarationBlock(): string
2✔
602
    {
603
        return $this->contentAfterDeclarationBlock;
2✔
604
    }
605

606
    /**
607
     * @return $this fluent interface
608
     */
609
    public function setAfterDeclarationBlock(string $content): self
2✔
610
    {
611
        $this->contentAfterDeclarationBlock = $content;
2✔
612

613
        return $this;
2✔
614
    }
615

616
    /**
617
     * @internal
618
     */
619
    public function getIndentation(): string
13✔
620
    {
621
        return $this->indentation;
13✔
622
    }
623

624
    /**
625
     * @return $this fluent interface
626
     */
627
    public function setIndentation(string $indentation): self
15✔
628
    {
629
        $this->indentation = $indentation;
15✔
630

631
        return $this;
15✔
632
    }
633

634
    /**
635
     * @internal
636
     */
637
    public function shouldIgnoreExceptions(): bool
4✔
638
    {
639
        return $this->shouldIgnoreExceptions;
4✔
640
    }
641

642
    /**
643
     * @return $this fluent interface
644
     */
645
    public function setIgnoreExceptions(bool $ignoreExceptions): self
4✔
646
    {
647
        $this->shouldIgnoreExceptions = $ignoreExceptions;
4✔
648

649
        return $this;
4✔
650
    }
651

652
    /**
653
     * @internal
654
     */
655
    public function shouldRenderComments(): bool
5✔
656
    {
657
        return $this->shouldRenderComments;
5✔
658
    }
659

660
    /**
661
     * @return $this fluent interface
662
     */
663
    public function setRenderComments(bool $renderComments): self
30✔
664
    {
665
        $this->shouldRenderComments = $renderComments;
30✔
666

667
        return $this;
30✔
668
    }
669

670
    /**
671
     * @return int<0, max>
672
     *
673
     * @internal
674
     */
675
    public function getIndentationLevel(): int
2✔
676
    {
677
        return $this->indentationLevel;
2✔
678
    }
679

680
    /**
681
     * @param int<1, max> $numberOfTabs
682
     *
683
     * @return $this fluent interface
684
     */
685
    public function indentWithTabs(int $numberOfTabs = 1): self
6✔
686
    {
687
        return $this->setIndentation(\str_repeat("\t", $numberOfTabs));
6✔
688
    }
689

690
    /**
691
     * @param int<1, max> $numberOfSpaces
692
     *
693
     * @return $this fluent interface
694
     */
695
    public function indentWithSpaces(int $numberOfSpaces = 2): self
7✔
696
    {
697
        return $this->setIndentation(\str_repeat(' ', $numberOfSpaces));
7✔
698
    }
699

700
    /**
701
     * @internal since V8.8.0
702
     */
703
    public function nextLevel(): self
5✔
704
    {
705
        if ($this->nextLevelFormat === null) {
5✔
706
            $this->nextLevelFormat = clone $this;
5✔
707
            $this->nextLevelFormat->indentationLevel++;
5✔
708
            $this->nextLevelFormat->outputFormatter = null;
5✔
709
        }
710
        return $this->nextLevelFormat;
5✔
711
    }
712

713
    public function beLenient(): void
1✔
714
    {
715
        $this->shouldIgnoreExceptions = true;
1✔
716
    }
1✔
717

718
    /**
719
     * @internal since 8.8.0
720
     */
721
    public function getFormatter(): OutputFormatter
3✔
722
    {
723
        if ($this->outputFormatter === null) {
3✔
724
            $this->outputFormatter = new OutputFormatter($this);
3✔
725
        }
726

727
        return $this->outputFormatter;
3✔
728
    }
729

730
    /**
731
     * Creates an instance of this class without any particular formatting settings.
732
     */
733
    public static function create(): self
30✔
734
    {
735
        return new OutputFormat();
30✔
736
    }
737

738
    /**
739
     * Creates an instance of this class with a preset for compact formatting.
740
     */
741
    public static function createCompact(): self
14✔
742
    {
743
        $format = self::create();
14✔
744
        $format
745
            ->setSpaceBeforeRules('')
14✔
746
            ->setSpaceBetweenRules('')
14✔
747
            ->setSpaceAfterRules('')
14✔
748
            ->setSpaceBeforeBlocks('')
14✔
749
            ->setSpaceBetweenBlocks('')
14✔
750
            ->setSpaceAfterBlocks('')
14✔
751
            ->setSpaceAfterRuleName('')
14✔
752
            ->setSpaceBeforeOpeningBrace('')
14✔
753
            ->setSpaceAfterSelectorSeparator('')
14✔
754
            ->setSemicolonAfterLastRule(false)
14✔
755
            ->setRenderComments(false);
14✔
756

757
        return $format;
14✔
758
    }
759

760
    /**
761
     * Creates an instance of this class with a preset for pretty formatting.
762
     */
763
    public static function createPretty(): self
13✔
764
    {
765
        $format = self::create();
13✔
766
        $format
767
            ->setSpaceBeforeRules("\n")
13✔
768
            ->setSpaceBetweenRules("\n")
13✔
769
            ->setSpaceAfterRules("\n")
13✔
770
            ->setSpaceBeforeBlocks("\n")
13✔
771
            ->setSpaceBetweenBlocks("\n\n")
13✔
772
            ->setSpaceAfterBlocks("\n")
13✔
773
            ->setSpaceAfterListArgumentSeparators([',' => ' '])
13✔
774
            ->setRenderComments(true);
13✔
775

776
        return $format;
13✔
777
    }
778
}
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

© 2026 Coveralls, Inc