@@ -13,12 +13,19 @@ namespace Sass {
13
13
14
14
namespace Functions {
15
15
16
- bool string_argument (AST_Node_Obj obj) {
16
+ bool isVar (AST_Node_Obj obj) {
17
+ String_Constant* s = Cast<String_Constant>(obj);
18
+ if (s == nullptr ) return false ;
19
+ const std::string& str = s->value ();
20
+ return starts_with (str, " var(" );
21
+ }
22
+
23
+ bool isSpecialNumber (AST_Node_Obj obj) {
17
24
String_Constant* s = Cast<String_Constant>(obj);
18
25
if (s == nullptr ) return false ;
19
26
const std::string& str = s->value ();
20
27
return starts_with (str, " calc(" ) ||
21
- starts_with (str, " var(" );
28
+ starts_with (str, " var(" );
22
29
}
23
30
24
31
void hsla_alpha_percent_deprecation (const ParserState& pstate, const std::string val)
@@ -35,9 +42,9 @@ namespace Sass {
35
42
BUILT_IN (rgb)
36
43
{
37
44
if (
38
- string_argument (env[" $red" ]) ||
39
- string_argument (env[" $green" ]) ||
40
- string_argument (env[" $blue" ])
45
+ isSpecialNumber (env[" $red" ]) ||
46
+ isSpecialNumber (env[" $green" ]) ||
47
+ isSpecialNumber (env[" $blue" ])
41
48
) {
42
49
return SASS_MEMORY_NEW (String_Constant, pstate, " rgb("
43
50
+ env[" $red" ]->to_string ()
@@ -56,68 +63,156 @@ namespace Sass {
56
63
COLOR_NUM (" $blue" ));
57
64
}
58
65
66
+
67
+ // / Asserts that [number] is a percentage or has no units, and normalizes the
68
+ // / value.
69
+ // /
70
+ // / If [number] has no units, its value is clamped to be greater than `0` or
71
+ // / less than [max] and returned. If [number] is a percentage, it's scaled to be
72
+ // / within `0` and [max]. Otherwise, this throws a [SassScriptException].
73
+ // /
74
+ // / [name] is used to identify the argument in the error message.
75
+ double _percentageOrUnitless (Number* number, double max, std::string name, Backtraces traces) {
76
+ double value = 0.0 ;
77
+ if (!number->hasUnits ()) {
78
+ value = number->value ();
79
+ }
80
+ else if (number->hasUnit (" %" )) {
81
+ value = max * number->value () / 100 ;
82
+ }
83
+ else {
84
+ error (name + " : Expected " + number->to_string () +
85
+ " to have unit \" %\" ." , number->pstate (), traces);
86
+ }
87
+ if (value < 0.0 ) return 0.0 ;
88
+ if (value > max) return max;
89
+ return value;
90
+ }
91
+
92
+ double fuzzyRound (double value) {
93
+ return value;
94
+ }
95
+
96
+ AST_Node* getArg (std::string name, Env& env)
97
+ {
98
+ if (env.has_local (name)) {
99
+ return env.get_local (name);
100
+ }
101
+ return nullptr ;
102
+ }
103
+
104
+ Value* _rgb (std::string name, Env& env, Signature sig, ParserState pstate, Backtraces traces)
105
+ {
106
+ AST_Node* _r = getArg (" $red" , env);
107
+ AST_Node* _g = getArg (" $green" , env);
108
+ AST_Node* _b = getArg (" $blue" , env);
109
+ AST_Node* _a = getArg (" $alpha" , env);
110
+ // Check if any `calc()` or `var()` are passed
111
+ if (isSpecialNumber (_r) || isSpecialNumber (_g) || isSpecialNumber (_b) || isSpecialNumber (_a)) {
112
+ std::stringstream fncall;
113
+ fncall << name << " (" ;
114
+ fncall << _r->to_css () << " , " ;
115
+ fncall << _g->to_css () << " , " ;
116
+ fncall << _b->to_css () << " , " ;
117
+ fncall << _a->to_css () << " )" ;
118
+ return SASS_MEMORY_NEW (StringLiteral, pstate, fncall.str ());
119
+ }
120
+
121
+ Number* r = ARGNUM (" $red" );
122
+ Number* g = ARGNUM (" $green" );
123
+ Number* b = ARGNUM (" $blue" );
124
+ Number* a = _a ? ARGNUM (" $alpha" ) : nullptr ;
125
+
126
+ return SASS_MEMORY_NEW (Color_RGBA, pstate,
127
+ fuzzyRound (_percentageOrUnitless (r, 255 , " red" , traces)),
128
+ fuzzyRound (_percentageOrUnitless (g, 255 , " red" , traces)),
129
+ fuzzyRound (_percentageOrUnitless (b, 255 , " red" , traces)),
130
+ a ? _percentageOrUnitless (a, 1.0 , " alpha" , traces) : 1.0 );
131
+
132
+ }
133
+
134
+
135
+ Value* _rgbTwoArg (std::string name, Env& env, Signature sig, ParserState pstate, Backtraces traces)
136
+ {
137
+ AST_Node* _c = getArg (" $color" , env);
138
+ AST_Node* _a = getArg (" $alpha" , env);
139
+ // Check if any `calc()` or `var()` are passed
140
+ if (isVar (_c)) {
141
+ std::stringstream fncall;
142
+ fncall << name << " ("
143
+ << _c->to_css () << " , "
144
+ << _a->to_css () << " )" ;
145
+ return SASS_MEMORY_NEW (StringLiteral,
146
+ pstate, fncall.str ());
147
+ }
148
+ else if (isVar (_a)) {
149
+ if (Color* c = Cast<Color>(_c)) {
150
+ Color_RGBAObj col = c->toRGBA ();
151
+ std::stringstream fncall;
152
+ fncall << name << " ("
153
+ << col->r () << " , "
154
+ << col->g () << " , "
155
+ << col->b () << " , "
156
+ << _a->to_css () << " )" ;
157
+ return SASS_MEMORY_NEW (StringLiteral,
158
+ pstate, fncall.str ());
159
+ }
160
+ else {
161
+ std::stringstream fncall;
162
+ fncall << name << " ("
163
+ << _c->to_css () << " , "
164
+ << _a->to_css () << " )" ;
165
+ return SASS_MEMORY_NEW (StringLiteral,
166
+ pstate, fncall.str ());
167
+ }
168
+ }
169
+ else if (isSpecialNumber (_a)) {
170
+ Color* c = ARGCOL (" $color" );
171
+ Color_RGBAObj col = c->toRGBA ();
172
+ std::stringstream fncall;
173
+ fncall << name << " ("
174
+ << col->r () << " , "
175
+ << col->g () << " , "
176
+ << col->b () << " , "
177
+ << _a->to_css () << " )" ;
178
+ return SASS_MEMORY_NEW (StringLiteral,
179
+ pstate, fncall.str ());
180
+ }
181
+
182
+ Color* c = ARGCOL (" $color" );
183
+ Number* a = ARGNUM (" $alpha" );
184
+
185
+ double alpha = _percentageOrUnitless (a, 1.0 , " alpha" , traces);
186
+
187
+ c = SASS_MEMORY_COPY (c);
188
+ c->a (alpha);
189
+ c->disp (" " );
190
+ return c;
191
+ }
192
+
59
193
Signature rgba_4_sig = " rgba($red, $green, $blue, $alpha)" ;
60
194
BUILT_IN (rgba_4)
61
195
{
62
- if (
63
- string_argument (env[" $red" ]) ||
64
- string_argument (env[" $green" ]) ||
65
- string_argument (env[" $blue" ]) ||
66
- string_argument (env[" $alpha" ])
67
- ) {
68
- return SASS_MEMORY_NEW (String_Constant, pstate, " rgba("
69
- + env[" $red" ]->to_string ()
70
- + " , "
71
- + env[" $green" ]->to_string ()
72
- + " , "
73
- + env[" $blue" ]->to_string ()
74
- + " , "
75
- + env[" $alpha" ]->to_string ()
76
- + " )"
77
- );
78
- }
196
+ return _rgb (" rgba" , env, rgba_4_sig, pstate, traces);
197
+ }
79
198
80
- return SASS_MEMORY_NEW (Color_RGBA,
81
- pstate,
82
- COLOR_NUM (" $red" ),
83
- COLOR_NUM (" $green" ),
84
- COLOR_NUM (" $blue" ),
85
- ALPHA_NUM (" $alpha" ));
199
+ Signature rgba_3_sig = " rgba($red, $green, $blue)" ;
200
+ BUILT_IN (rgba_3)
201
+ {
202
+ return _rgb (" rgba" , env, rgba_3_sig, pstate, traces);
86
203
}
87
204
88
205
Signature rgba_2_sig = " rgba($color, $alpha)" ;
89
206
BUILT_IN (rgba_2)
90
207
{
91
- if (
92
- string_argument (env[" $color" ])
93
- ) {
94
- return SASS_MEMORY_NEW (String_Constant, pstate, " rgba("
95
- + env[" $color" ]->to_string ()
96
- + " , "
97
- + env[" $alpha" ]->to_string ()
98
- + " )"
99
- );
100
- }
101
-
102
- Color_RGBA_Obj c_arg = ARGCOL (" $color" )->toRGBA ();
103
-
104
- if (
105
- string_argument (env[" $alpha" ])
106
- ) {
107
- std::stringstream strm;
108
- strm << " rgba("
109
- << (int )c_arg->r () << " , "
110
- << (int )c_arg->g () << " , "
111
- << (int )c_arg->b () << " , "
112
- << env[" $alpha" ]->to_string ()
113
- << " )" ;
114
- return SASS_MEMORY_NEW (String_Constant, pstate, strm.str ());
115
- }
208
+ return _rgbTwoArg (" rgba" , env, rgba_2_sig, pstate, traces);
209
+ }
116
210
117
- Color_RGBA_Obj new_c = SASS_MEMORY_COPY (c_arg);
118
- new_c->a (ALPHA_NUM (" $alpha" ));
119
- new_c->disp (" " );
120
- return new_c.detach ();
211
+ Signature rgba_1_sig = " rgba($channels)" ;
212
+ BUILT_IN (rgba_1)
213
+ {
214
+ std::cerr << " qweqwe\n " ;
215
+ return nullptr ;
121
216
}
122
217
123
218
// //////////////
@@ -181,9 +276,9 @@ namespace Sass {
181
276
BUILT_IN (hsl)
182
277
{
183
278
if (
184
- string_argument (env[" $hue" ]) ||
185
- string_argument (env[" $saturation" ]) ||
186
- string_argument (env[" $lightness" ])
279
+ isSpecialNumber (env[" $hue" ]) ||
280
+ isSpecialNumber (env[" $saturation" ]) ||
281
+ isSpecialNumber (env[" $lightness" ])
187
282
) {
188
283
return SASS_MEMORY_NEW (String_Constant, pstate, " hsl("
189
284
+ env[" $hue" ]->to_string ()
@@ -208,10 +303,10 @@ namespace Sass {
208
303
BUILT_IN (hsla)
209
304
{
210
305
if (
211
- string_argument (env[" $hue" ]) ||
212
- string_argument (env[" $saturation" ]) ||
213
- string_argument (env[" $lightness" ]) ||
214
- string_argument (env[" $alpha" ])
306
+ isSpecialNumber (env[" $hue" ]) ||
307
+ isSpecialNumber (env[" $saturation" ]) ||
308
+ isSpecialNumber (env[" $lightness" ]) ||
309
+ isSpecialNumber (env[" $alpha" ])
215
310
) {
216
311
return SASS_MEMORY_NEW (String_Constant, pstate, " hsla("
217
312
+ env[" $hue" ]->to_string ()
0 commit comments