Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
30 / 30
100.00% covered (success)
100.00%
11 / 11
CRAP
100.00% covered (success)
100.00%
1 / 1
Declaration
100.00% covered (success)
100.00%
30 / 30
100.00% covered (success)
100.00%
11 / 11
16
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
2
 __clone
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getPosition
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getName
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getValue
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getImportant
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setImportant
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 toTokenOrCVArray
100.00% covered (success)
100.00%
14 / 14
100.00% covered (success)
100.00%
1 / 1
5
 toTokenArray
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 toComponentValueArray
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 __toString
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2/**
3 * @file
4 * @license https://opensource.org/licenses/Apache-2.0 Apache-2.0
5 */
6
7namespace Wikimedia\CSS\Objects;
8
9use InvalidArgumentException;
10use Wikimedia\CSS\Util;
11
12/**
13 * Represent a CSS declaration
14 */
15class Declaration implements DeclarationOrAtRule {
16
17    /** @var int Line in the input where this declaration starts */
18    protected $line = -1;
19
20    /** @var int Position in the input where this declaration starts */
21    protected $pos = -1;
22
23    /** @var string */
24    protected $name;
25
26    /** @var ComponentValueList */
27    protected $value;
28
29    /** @var bool */
30    protected $important = false;
31
32    /**
33     * @param Token $token Token starting the declaration
34     */
35    public function __construct( Token $token ) {
36        if ( $token->type() !== Token::T_IDENT ) {
37            throw new InvalidArgumentException(
38                "Declaration must begin with an ident token, got {$token->type()}"
39            );
40        }
41
42        [ $this->line, $this->pos ] = $token->getPosition();
43        $this->name = $token->value();
44        $this->value = new ComponentValueList();
45    }
46
47    public function __clone() {
48        $this->value = clone $this->value;
49    }
50
51    /**
52     * Get the position of this Declaration in the input stream
53     * @return array [ $line, $pos ]
54     */
55    public function getPosition() {
56        return [ $this->line, $this->pos ];
57    }
58
59    /**
60     * Return the declaration's name
61     * @return string
62     */
63    public function getName() {
64        return $this->name;
65    }
66
67    /**
68     * Return the declaration's value
69     * @return ComponentValueList
70     */
71    public function getValue() {
72        return $this->value;
73    }
74
75    /**
76     * Return the declaration's 'important' flag
77     * @return bool
78     */
79    public function getImportant() {
80        return $this->important;
81    }
82
83    /**
84     * Set the 'important' flag
85     * @param bool $flag
86     */
87    public function setImportant( $flag ) {
88        $this->important = (bool)$flag;
89    }
90
91    /**
92     * @param string $function Function to call, toTokenArray() or toComponentValueArray()
93     * @return Token[]|ComponentValue[]
94     */
95    private function toTokenOrCVArray( $function ) {
96        $ret = [];
97
98        $ret[] = new Token(
99            Token::T_IDENT,
100            [ 'value' => $this->name, 'position' => [ $this->line, $this->pos ] ]
101        );
102        $ret[] = $v = new Token( Token::T_COLON );
103        // Manually looping and appending turns out to be noticeably faster than array_merge.
104        foreach ( $this->value->$function() as $v ) {
105            $ret[] = $v;
106        }
107        if ( $this->important ) {
108            if ( !$v instanceof Token || $v->type() !== Token::T_WHITESPACE ) {
109                $ret[] = new Token( Token::T_WHITESPACE, [ 'significant' => false ] );
110            }
111            $ret[] = new Token( Token::T_DELIM, '!' );
112            $ret[] = new Token( Token::T_IDENT, 'important' );
113        }
114        return $ret;
115    }
116
117    /** @inheritDoc */
118    public function toTokenArray() {
119        return $this->toTokenOrCVArray( __FUNCTION__ );
120    }
121
122    /** @inheritDoc */
123    public function toComponentValueArray() {
124        return $this->toTokenOrCVArray( __FUNCTION__ );
125    }
126
127    public function __toString() {
128        return Util::stringify( $this );
129    }
130}