@@ -68,6 +68,116 @@ namespace Sass {
68
68
return value;
69
69
}
70
70
71
+
72
+ // / Returns whether [value] is an unquoted string that start with `var(` and
73
+ // / contains `/`.
74
+ bool _isVarSlash (Expression* value) {
75
+ if (String_Constant * string = Cast<String_Constant>(value)) {
76
+ return starts_with (string->value (), " var(" ) &&
77
+ string_constains (string->value (), ' /' );
78
+ }
79
+ if (StringLiteral * string = Cast<StringLiteral>(value)) {
80
+ return starts_with (string->text (), " var(" ) &&
81
+ string_constains (string->text (), ' /' );
82
+ }
83
+ return false ;
84
+ }
85
+
86
+
87
+ Expression* _parseChannels (std::string name, std::vector<std::string> argumentNames, Value* channels, ParserState pstate, Backtraces traces)
88
+ {
89
+ if (isVar (channels)) {
90
+ std::stringstream fncall;
91
+ fncall << name << " ("
92
+ << channels->to_css () << " )" ;
93
+ return SASS_MEMORY_NEW (StringLiteral,
94
+ pstate, fncall.str ());
95
+ }
96
+
97
+ // Expression* list = Listize::perform(channels);
98
+
99
+ if (List * list = Cast<List>(channels)) {
100
+ bool isCommaSeparated = list->separator () == SASS_COMMA;
101
+ bool isBracketed = list->is_bracketed ();
102
+ if (isCommaSeparated || isBracketed) {
103
+ std::stringstream msg;
104
+ msg << " $channels must be" ;
105
+ if (isBracketed) msg << " an unbracketed" ;
106
+ if (isCommaSeparated) {
107
+ msg << (isBracketed ? " ," : " a" );
108
+ msg << " space-separated" ;
109
+ }
110
+ msg << " list." ;
111
+ error (msg.str (), pstate, traces);
112
+ }
113
+
114
+ if (list->length () > 3 ) {
115
+ error (
116
+ " Only 3 elements allowed, but ${list.length} were passed." ,
117
+ pstate, traces);
118
+ }
119
+ else if (list->length () < 3 ) {
120
+ bool hasVar = false ;
121
+ for (Expression* item : list->elements ()) {
122
+ if (isVar (item)) {
123
+ hasVar = true ;
124
+ break ;
125
+ }
126
+ }
127
+ if (hasVar || (!list->empty () && _isVarSlash (list->last ()))) {
128
+ std::stringstream fncall;
129
+ fncall << name << " (" ;
130
+ for (size_t i = 0 , iL = list->length (); i < iL; i++) {
131
+ if (i > 0 ) { fncall << " , " ; }
132
+ fncall << list->get (i)->to_css ();
133
+ }
134
+ fncall << " )" ;
135
+ return SASS_MEMORY_NEW (StringLiteral,
136
+ pstate, fncall.str ());
137
+ }
138
+ else {
139
+ std::string argument = argumentNames[list->length ()];
140
+ error (
141
+ " Missing element " + argument + " ." ,
142
+ pstate, traces);
143
+ }
144
+ }
145
+
146
+ Number* secondNumber = Cast<Number>(list->get (2 ));
147
+ String_Constant* secondString = Cast<String_Constant>(list->get (2 ));
148
+ if (secondNumber && secondNumber->hasAsSlash ()) {
149
+ List* rv = SASS_MEMORY_NEW (List, pstate);
150
+ rv->append (list->get (0 ));
151
+ rv->append (list->get (1 ));
152
+ rv->append (secondNumber->lhsAsSlash ());
153
+ rv->append (secondNumber->rhsAsSlash ());
154
+ return rv;
155
+ }
156
+ else if (secondString &&
157
+ // !maybeSlashSeparated.hasQuotes &&
158
+ string_constains (secondString->value (), ' /' )) {
159
+ std::stringstream fncall;
160
+ fncall << name << " (" ;
161
+ for (size_t i = 0 , iL = list->length (); i < iL; i++) {
162
+ if (i > 0 ) { fncall << " , " ; }
163
+ fncall << list->get (i)->to_css ();
164
+
165
+ }
166
+ fncall << " )" ;
167
+ return SASS_MEMORY_NEW (StringLiteral,
168
+ pstate, fncall.str ());
169
+ }
170
+ else {
171
+ return list;
172
+ }
173
+ }
174
+ else {
175
+ error (" $channels must be a space-separated list." ,
176
+ pstate, traces);
177
+ }
178
+ return nullptr ;
179
+ }
180
+
71
181
AST_Node* getArg (std::string name, Env& env)
72
182
{
73
183
if (env.has_local (name)) {
@@ -227,154 +337,53 @@ namespace Sass {
227
337
return _rgbTwoArg (" rgba" , env, rgba_2_sig, pstate, traces);
228
338
}
229
339
230
- // / Returns whether [value] is an unquoted string that start with `var(` and
231
- // / contains `/`.
232
- bool _isVarSlash (Expression* value) {
233
- if (String_Constant * string = Cast<String_Constant>(value)) {
234
- return starts_with (string->value (), " var(" ) &&
235
- string_constains (string->value (), ' /' );
340
+ Signature rgba_1_sig = " rgba($channels)" ;
341
+ BUILT_IN (rgba_1)
342
+ {
343
+ Value* channels = ARG (" $channels" , Value, " a value" );
344
+ ExpressionObj parsed = _parseChannels (" rgba" ,
345
+ { " $red" , " $green" , " $blue" }, channels, pstate, traces);
346
+ if (StringLiteral * str = Cast<StringLiteral>(parsed)) {
347
+ return str;
236
348
}
237
- if (StringLiteral * string = Cast<StringLiteral>(value)) {
238
- return starts_with (string->text (), " var(" ) &&
239
- string_constains (string->text (), ' /' );
349
+ if (List * list = Cast<List>(parsed)) {
350
+ return _rgb (" rgba" , list->elements (), rgba_1_sig, pstate, traces);
240
351
}
241
- return false ;
352
+ return nullptr ;
242
353
}
243
354
244
-
245
- Expression* _parseChannels (std::string name, std::vector<std::string> argumentNames, Value* channels, ParserState pstate, Backtraces traces )
355
+ Signature rgb_4_sig = " rgb($red, $green, $blue, $alpha) " ;
356
+ BUILT_IN (rgb_4 )
246
357
{
247
- if (isVar (channels)) {
248
- std::stringstream fncall;
249
- fncall << name << " ("
250
- << channels->to_css () << " )" ;
251
- return SASS_MEMORY_NEW (StringLiteral,
252
- pstate, fncall.str ());
253
- }
254
-
255
- // Expression* list = Listize::perform(channels);
256
-
257
- if (List * list = Cast<List>(channels)) {
258
- bool isCommaSeparated = list->separator () == SASS_COMMA;
259
- bool isBracketed = list->is_bracketed ();
260
- if (isCommaSeparated || isBracketed) {
261
- std::stringstream msg;
262
- msg << " $channels must be" ;
263
- if (isBracketed) msg << " an unbracketed" ;
264
- if (isCommaSeparated) {
265
- msg << (isBracketed ? " ," : " a" );
266
- msg << " space-separated" ;
267
- }
268
- msg << " list." ;
269
- error (msg.str (), pstate, traces);
270
- }
271
-
272
- if (list->length () > 3 ) {
273
- error (
274
- " Only 3 elements allowed, but ${list.length} were passed." ,
275
- pstate, traces);
276
- }
277
- else if (list->length () < 3 ) {
278
- bool hasVar = false ;
279
- for (Expression* item : list->elements ()) {
280
- if (isVar (item)) {
281
- hasVar = true ;
282
- break ;
283
- }
284
- }
285
- if (hasVar || (!list->empty () && _isVarSlash (list->last ()))) {
286
- std::stringstream fncall;
287
- fncall << name << " (" ;
288
- for (size_t i = 0 , iL = list->length (); i < iL; i++) {
289
- if (i > 0 ) { fncall << " , " ; }
290
- fncall << list->get (i)->to_css ();
291
- }
292
- fncall << " )" ;
293
- return SASS_MEMORY_NEW (StringLiteral,
294
- pstate, fncall.str ());
295
- }
296
- else {
297
- std::string argument = argumentNames[list->length ()];
298
- error (
299
- " Missing element " + argument + " ." ,
300
- pstate, traces);
301
- }
302
- }
358
+ return _rgb (" rgb" , env, rgb_4_sig, pstate, traces);
359
+ }
303
360
304
- Number* secondNumber = Cast<Number>(list->get (2 ));
305
- String_Constant* secondString = Cast<String_Constant>(list->get (2 ));
306
- if (secondNumber && secondNumber->hasAsSlash ()) {
307
- List* rv = SASS_MEMORY_NEW (List, pstate);
308
- rv->append (list->get (0 ));
309
- rv->append (list->get (1 ));
310
- rv->append (secondNumber->lhsAsSlash ());
311
- rv->append (secondNumber->rhsAsSlash ());
312
- return rv;
313
- }
314
- else if (secondString &&
315
- // !maybeSlashSeparated.hasQuotes &&
316
- string_constains (secondString->value (), ' /' )) {
317
- std::stringstream fncall;
318
- fncall << name << " (" ;
319
- for (size_t i = 0 , iL = list->length (); i < iL; i++) {
320
- if (i > 0 ) { fncall << " , " ; }
321
- fncall << list->get (i)->to_css ();
361
+ Signature rgb_3_sig = " rgb($red, $green, $blue)" ;
362
+ BUILT_IN (rgb_3)
363
+ {
364
+ return _rgb (" rgb" , env, rgb_3_sig, pstate, traces);
365
+ }
322
366
323
- }
324
- fncall << " )" ;
325
- return SASS_MEMORY_NEW (StringLiteral,
326
- pstate, fncall.str ());
327
- }
328
- else {
329
- return list;
330
- }
331
- }
332
- else {
333
- error (" $channels must be a space-separated list." ,
334
- pstate, traces);
335
- }
336
- return nullptr ;
367
+ Signature rgb_2_sig = " rgb($color, $alpha)" ;
368
+ BUILT_IN (rgb_2)
369
+ {
370
+ return _rgbTwoArg (" rgb" , env, rgb_2_sig, pstate, traces);
337
371
}
338
372
339
- Signature rgba_1_sig = " rgba ($channels)" ;
340
- BUILT_IN (rgba_1 )
373
+ Signature rgb_1_sig = " rgb ($channels)" ;
374
+ BUILT_IN (rgb_1 )
341
375
{
342
376
Value* channels = ARG (" $channels" , Value, " a value" );
343
- ExpressionObj parsed = _parseChannels (" rgba " ,
377
+ ExpressionObj parsed = _parseChannels (" rgb " ,
344
378
{ " $red" , " $green" , " $blue" }, channels, pstate, traces);
345
379
if (StringLiteral * str = Cast<StringLiteral>(parsed)) {
346
380
return str;
347
381
}
348
382
if (List * list = Cast<List>(parsed)) {
349
- return _rgb (" rgb" , list->elements (), rgba_1_sig, pstate, traces);
350
- }
351
- }
352
-
353
- Signature rgb_sig = " rgb($red, $green, $blue)" ;
354
- BUILT_IN (rgb)
355
- {
356
- if (
357
- isSpecialNumber (env[" $red" ]) ||
358
- isSpecialNumber (env[" $green" ]) ||
359
- isSpecialNumber (env[" $blue" ])
360
- ) {
361
- return SASS_MEMORY_NEW (String_Constant, pstate, " rgb("
362
- + env[" $red" ]->to_string ()
363
- + " , "
364
- + env[" $green" ]->to_string ()
365
- + " , "
366
- + env[" $blue" ]->to_string ()
367
- + " )"
368
- );
383
+ return _rgb (" rgb" , list->elements (), rgb_1_sig, pstate, traces);
369
384
}
370
-
371
- return SASS_MEMORY_NEW (Color_RGBA,
372
- pstate,
373
- COLOR_NUM (" $red" ),
374
- COLOR_NUM (" $green" ),
375
- COLOR_NUM (" $blue" ));
385
+ return nullptr ;
376
386
}
377
-
378
387
// //////////////
379
388
// RGB FUNCTIONS
380
389
// //////////////
0 commit comments