Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
5 / 5
CRAP
100.00% covered (success)
100.00%
1 / 1
Specificity
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
5 / 5
8
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 add
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 max
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
2
 compare
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
3
 __toString
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3declare(strict_types=1);
4
5namespace Phpdftk\Css\Selector;
6
7/**
8 * Selector specificity per CSS Selectors 4 ยง16.
9 *
10 * Three counters: `a` (ID selectors), `b` (class / attribute / pseudo-class
11 * selectors), `c` (type selectors / pseudo-elements). Universal selector
12 * doesn't contribute. Treated as a base-256 big-integer for ordering, with
13 * a guard against overflow on pathological inputs.
14 */
15final readonly class Specificity
16{
17    public function __construct(
18        public int $a = 0,
19        public int $b = 0,
20        public int $c = 0,
21    ) {}
22
23    public function add(self $other): self
24    {
25        return new self($this->a + $other->a, $this->b + $other->b, $this->c + $other->c);
26    }
27
28    /** Element-wise max for `:is()` / `:not()` / `:has()` inner selectors. */
29    public function max(self $other): self
30    {
31        return $this->compare($other) >= 0 ? $this : $other;
32    }
33
34    /** Compare: -1 if $this is less specific, 0 equal, 1 more specific. */
35    public function compare(self $other): int
36    {
37        return ($this->a <=> $other->a)
38            ?: ($this->b <=> $other->b)
39            ?: ($this->c <=> $other->c);
40    }
41
42    public function __toString(): string
43    {
44        return "({$this->a}{$this->b}{$this->c})";
45    }
46}