Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
31 / 31
100.00% covered (success)
100.00%
11 / 11
CRAP
100.00% covered (success)
100.00%
1 / 1
AtRule
100.00% covered (success)
100.00%
31 / 31
100.00% covered (success)
100.00%
11 / 11
17
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%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 newFromName
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
 getPrelude
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getBlock
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setBlock
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 toTokenOrCVArray
100.00% covered (success)
100.00%
11 / 11
100.00% covered (success)
100.00%
1 / 1
4
 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 at-rule
14 */
15class AtRule extends Rule implements DeclarationOrAtRule {
16
17    /** @var string */
18    protected $name;
19
20    /** @var ComponentValueList */
21    protected $prelude;
22
23    /** @var SimpleBlock|null */
24    protected $block = null;
25
26    /**
27     * @param Token $token An at-keyword token
28     */
29    public function __construct( Token $token ) {
30        if ( $token->type() !== Token::T_AT_KEYWORD ) {
31            throw new InvalidArgumentException(
32                "At rule must begin with an at-keyword token, got {$token->type()}"
33            );
34        }
35
36        parent::__construct( $token );
37        $this->name = $token->value();
38        $this->prelude = new ComponentValueList();
39    }
40
41    public function __clone() {
42        $this->prelude = clone $this->prelude;
43        if ( $this->block ) {
44            $this->block = clone $this->block;
45        }
46    }
47
48    /**
49     * Create an at-rule by name
50     * @param string $name
51     * @return AtRule
52     */
53    public static function newFromName( $name ) {
54        return new static( new Token( Token::T_AT_KEYWORD, $name ) );
55    }
56
57    /**
58     * Return the at-rule's name, e.g. "media"
59     * @return string
60     */
61    public function getName() {
62        return $this->name;
63    }
64
65    /**
66     * Return the at-rule's prelude
67     * @return ComponentValueList
68     */
69    public function getPrelude() {
70        return $this->prelude;
71    }
72
73    /**
74     * Return the at-rule's block
75     * @return SimpleBlock|null
76     */
77    public function getBlock() {
78        return $this->block;
79    }
80
81    /**
82     * Set the block
83     * @param SimpleBlock|null $block
84     */
85    public function setBlock( SimpleBlock $block = null ) {
86        if ( $block->getStartTokenType() !== Token::T_LEFT_BRACE ) {
87            throw new InvalidArgumentException( 'At-rule block must be delimited by {}' );
88        }
89        $this->block = $block;
90    }
91
92    /**
93     * @param string $function Function to call, toTokenArray() or toComponentValueArray()
94     * @return Token[]|ComponentValue[]
95     */
96    private function toTokenOrCVArray( $function ) {
97        $ret = [];
98
99        $ret[] = new Token(
100            Token::T_AT_KEYWORD, [ 'value' => $this->name, 'position' => [ $this->line, $this->pos ] ]
101        );
102        // Manually looping and appending turns out to be noticeably faster than array_merge.
103        foreach ( $this->prelude->$function() as $v ) {
104            $ret[] = $v;
105        }
106        if ( $this->block ) {
107            foreach ( $this->block->$function() as $v ) {
108                $ret[] = $v;
109            }
110        } else {
111            $ret[] = new Token( Token::T_SEMICOLON );
112        }
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}