Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
<?php
2
 
3
/**
4
 * SCSSPHP
5
 *
6
 * @copyright 2012-2020 Leaf Corcoran
7
 *
8
 * @license http://opensource.org/licenses/MIT MIT
9
 *
10
 * @link http://scssphp.github.io/scssphp
11
 */
12
 
13
namespace ScssPhp\ScssPhp\Formatter;
14
 
15
use ScssPhp\ScssPhp\Formatter;
16
use ScssPhp\ScssPhp\Type;
17
 
18
/**
19
 * Nested formatter
20
 *
21
 * @author Leaf Corcoran <leafot@gmail.com>
22
 *
23
 * @deprecated since 1.4.0. Use the Expanded formatter instead.
24
 *
25
 * @internal
26
 */
27
class Nested extends Formatter
28
{
29
    /**
30
     * @var int
31
     */
32
    private $depth;
33
 
34
    /**
35
     * {@inheritdoc}
36
     */
37
    public function __construct()
38
    {
39
        @trigger_error('The Nested formatter is deprecated since 1.4.0. Use the Expanded formatter instead.', E_USER_DEPRECATED);
40
 
41
        $this->indentLevel = 0;
42
        $this->indentChar = '  ';
43
        $this->break = "\n";
44
        $this->open = ' {';
45
        $this->close = ' }';
46
        $this->tagSeparator = ', ';
47
        $this->assignSeparator = ': ';
48
        $this->keepSemicolons = true;
49
    }
50
 
51
    /**
52
     * {@inheritdoc}
53
     */
54
    protected function indentStr()
55
    {
56
        $n = $this->depth - 1;
57
 
58
        return str_repeat($this->indentChar, max($this->indentLevel + $n, 0));
59
    }
60
 
61
    /**
62
     * {@inheritdoc}
63
     */
64
    protected function blockLines(OutputBlock $block)
65
    {
66
        $inner = $this->indentStr();
67
        $glue  = $this->break . $inner;
68
 
69
        foreach ($block->lines as $index => $line) {
70
            if (substr($line, 0, 2) === '/*') {
71
                $replacedLine = preg_replace('/\r\n?|\n|\f/', $this->break, $line);
72
                assert($replacedLine !== null);
73
                $block->lines[$index] = $replacedLine;
74
            }
75
        }
76
 
77
        $this->write($inner . implode($glue, $block->lines));
78
    }
79
 
80
    /**
81
     * {@inheritdoc}
82
     */
83
    protected function block(OutputBlock $block)
84
    {
85
        static $depths;
86
        static $downLevel;
87
        static $closeBlock;
88
        static $previousEmpty;
89
        static $previousHasSelector;
90
 
91
        if ($block->type === 'root') {
92
            $depths = [ 0 ];
93
            $downLevel = '';
94
            $closeBlock = '';
95
            $this->depth = 0;
96
            $previousEmpty = false;
97
            $previousHasSelector = false;
98
        }
99
 
100
        $isMediaOrDirective = \in_array($block->type, [Type::T_DIRECTIVE, Type::T_MEDIA]);
101
        $isSupport = ($block->type === Type::T_DIRECTIVE
102
            && $block->selectors && strpos(implode('', $block->selectors), '@supports') !== false);
103
 
104
        while ($block->depth < end($depths) || ($block->depth == 1 && end($depths) == 1)) {
105
            array_pop($depths);
106
            $this->depth--;
107
 
108
            if (
109
                ! $this->depth && ($block->depth <= 1 || (! $this->indentLevel && $block->type === Type::T_COMMENT)) &&
110
                (($block->selectors && ! $isMediaOrDirective) || $previousHasSelector)
111
            ) {
112
                $downLevel = $this->break;
113
            }
114
 
115
            if (empty($block->lines) && empty($block->children)) {
116
                $previousEmpty = true;
117
            }
118
        }
119
 
120
        if (empty($block->lines) && empty($block->children)) {
121
            return;
122
        }
123
 
124
        $this->currentBlock = $block;
125
 
126
        if (! empty($block->lines) || (! empty($block->children) && ($this->depth < 1 || $isSupport))) {
127
            if ($block->depth > end($depths)) {
128
                if (! $previousEmpty || $this->depth < 1) {
129
                    $this->depth++;
130
 
131
                    $depths[] = $block->depth;
132
                } else {
133
                    // keep the current depth unchanged but take the block depth as a new reference for following blocks
134
                    array_pop($depths);
135
 
136
                    $depths[] = $block->depth;
137
                }
138
            }
139
        }
140
 
141
        $previousEmpty = ($block->type === Type::T_COMMENT);
142
        $previousHasSelector = false;
143
 
144
        if (! empty($block->selectors)) {
145
            if ($closeBlock) {
146
                $this->write($closeBlock);
147
                $closeBlock = '';
148
            }
149
 
150
            if ($downLevel) {
151
                $this->write($downLevel);
152
                $downLevel = '';
153
            }
154
 
155
            $this->blockSelectors($block);
156
 
157
            $this->indentLevel++;
158
        }
159
 
160
        if (! empty($block->lines)) {
161
            if ($closeBlock) {
162
                $this->write($closeBlock);
163
                $closeBlock = '';
164
            }
165
 
166
            if ($downLevel) {
167
                $this->write($downLevel);
168
                $downLevel = '';
169
            }
170
 
171
            $this->blockLines($block);
172
 
173
            $closeBlock = $this->break;
174
        }
175
 
176
        if (! empty($block->children)) {
177
            if ($this->depth > 0 && ($isMediaOrDirective || ! $this->hasFlatChild($block))) {
178
                array_pop($depths);
179
 
180
                $this->depth--;
181
                $this->blockChildren($block);
182
                $this->depth++;
183
 
184
                $depths[] = $block->depth;
185
            } else {
186
                $this->blockChildren($block);
187
            }
188
        }
189
 
190
        // reclear to not be spoiled by children if T_DIRECTIVE
191
        if ($block->type === Type::T_DIRECTIVE) {
192
            $previousHasSelector = false;
193
        }
194
 
195
        if (! empty($block->selectors)) {
196
            $this->indentLevel--;
197
 
198
            if (! $this->keepSemicolons) {
199
                $this->strippedSemicolon = '';
200
            }
201
 
202
            $this->write($this->close);
203
 
204
            $closeBlock = $this->break;
205
 
206
            if ($this->depth > 1 && ! empty($block->children)) {
207
                array_pop($depths);
208
                $this->depth--;
209
            }
210
 
211
            if (! $isMediaOrDirective) {
212
                $previousHasSelector = true;
213
            }
214
        }
215
 
216
        if ($block->type === 'root') {
217
            $this->write($this->break);
218
        }
219
    }
220
 
221
    /**
222
     * Block has flat child
223
     *
224
     * @param \ScssPhp\ScssPhp\Formatter\OutputBlock $block
225
     *
226
     * @return bool
227
     */
228
    private function hasFlatChild($block)
229
    {
230
        foreach ($block->children as $child) {
231
            if (empty($child->selectors)) {
232
                return true;
233
            }
234
        }
235
 
236
        return false;
237
    }
238
}