Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
33 / 33
100.00% covered (success)
100.00%
9 / 9
CRAP
100.00% covered (success)
100.00%
1 / 1
SimpleBlock
100.00% covered (success)
100.00%
33 / 33
100.00% covered (success)
100.00%
9 / 9
20
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
8 / 8
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
 newFromDelimiter
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 matchingDelimiter
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
5
 getStartTokenType
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getEndTokenType
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
 toTokenArray
100.00% covered (success)
100.00%
15 / 15
100.00% covered (success)
100.00%
1 / 1
7
 __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 simple block
14 */
15class SimpleBlock extends ComponentValue {
16
17    /** @var string */
18    protected $startTokenType;
19
20    /** @var string */
21    protected $endTokenType;
22
23    /** @var ComponentValueList */
24    protected $value;
25
26    /**
27     * @param Token $token Associated token
28     */
29    public function __construct( Token $token ) {
30        $this->endTokenType = static::matchingDelimiter( $token->type() );
31        if ( $this->endTokenType === null ) {
32            throw new InvalidArgumentException(
33                'A SimpleBlock is delimited by either {}, [], or ().'
34            );
35        }
36
37        [ $this->line, $this->pos ] = $token->getPosition();
38        $this->startTokenType = $token->type();
39        $this->value = new ComponentValueList();
40    }
41
42    public function __clone() {
43        $this->value = clone $this->value;
44    }
45
46    /**
47     * Create simple block by token type
48     * @param string $delimiter Token::T_LEFT_PAREN, Token::T_LEFT_BRACE, or
49     *  Token::T_LEFT_BRACKET
50     * @return SimpleBlock
51     */
52    public static function newFromDelimiter( $delimiter ) {
53        return new static( new Token( $delimiter ) );
54    }
55
56    /**
57     * Return the ending delimiter for a starting delimiter
58     * @param string $delim Token::T_* constant
59     * @return string|null Matching Token::T_* constant, if any
60     */
61    public static function matchingDelimiter( $delim ) {
62        switch ( $delim ) {
63            case Token::T_LEFT_BRACE:
64                return Token::T_RIGHT_BRACE;
65            case Token::T_LEFT_BRACKET:
66                return Token::T_RIGHT_BRACKET;
67            case Token::T_LEFT_PAREN:
68                return Token::T_RIGHT_PAREN;
69            default:
70                return null;
71        }
72    }
73
74    /**
75     * Get the start token type
76     * @return string
77     */
78    public function getStartTokenType() {
79        return $this->startTokenType;
80    }
81
82    /**
83     * Get the end token type
84     * @return string
85     */
86    public function getEndTokenType() {
87        return $this->endTokenType;
88    }
89
90    /**
91     * Return the block's value
92     * @return ComponentValueList
93     */
94    public function getValue() {
95        return $this->value;
96    }
97
98    /** @inheritDoc */
99    public function toTokenArray() {
100        $ret = [
101            new Token( $this->startTokenType, [ 'position' => [ $this->line, $this->pos ] ] ),
102        ];
103
104        // Manually looping and appending turns out to be noticeably faster than array_merge.
105        $tokens = $this->value->toTokenArray();
106        if ( $tokens && $this->startTokenType === Token::T_LEFT_BRACE ) {
107            if ( $tokens[0]->type() !== Token::T_WHITESPACE ) {
108                $ret[] = new Token( Token::T_WHITESPACE, [ 'significant' => false ] );
109            }
110            foreach ( $tokens as $v ) {
111                $ret[] = $v;
112            }
113            if ( $tokens[count( $tokens ) - 1]->type() !== Token::T_WHITESPACE ) {
114                $ret[] = new Token( Token::T_WHITESPACE, [ 'significant' => false ] );
115            }
116        } else {
117            foreach ( $tokens as $v ) {
118                $ret[] = $v;
119            }
120        }
121
122        $ret[] = new Token( $this->endTokenType );
123
124        return $ret;
125    }
126
127    public function __toString() {
128        return Util::stringify( $this );
129    }
130}