@@ -12,22 +12,40 @@ import '../deprecation.dart';
12
12
import '../evaluation_context.dart' ;
13
13
import '../exception.dart' ;
14
14
import '../module/built_in.dart' ;
15
- import '../util/number.dart' ;
16
15
import '../value.dart' ;
17
16
18
17
/// The global definitions of Sass math functions.
19
18
final global = UnmodifiableListView ([
20
- _abs, _ceil, _floor, _max, _min, _percentage, _randomFunction, _round,
21
- _unit, //
19
+ _function ("abs" , r"$number" , (arguments) {
20
+ var number = arguments[0 ].assertNumber ("number" );
21
+ if (number.hasUnit ("%" )) {
22
+ warnForDeprecation (
23
+ "Passing percentage units to the global abs() function is "
24
+ "deprecated.\n "
25
+ "In the future, this will emit a CSS abs() function to be resolved "
26
+ "by the browser.\n "
27
+ "To preserve current behavior: math.abs($number )"
28
+ "\n "
29
+ "To emit a CSS abs() now: abs(#{$number })\n "
30
+ "More info: https://sass-lang.com/d/abs-percent" ,
31
+ Deprecation .absPercent);
32
+ }
33
+ return SassNumber .withUnits (number.value.abs (),
34
+ numeratorUnits: number.numeratorUnits,
35
+ denominatorUnits: number.denominatorUnits);
36
+ }),
37
+
38
+ _ceil, _floor, _max, _min, _percentage, _randomFunction, _round, _unit, //
22
39
_compatible.withName ("comparable" ),
23
40
_isUnitless.withName ("unitless" ),
24
41
]);
25
42
26
43
/// The Sass math module.
27
44
final module = BuiltInModule ("math" , functions: < Callable > [
28
- _abs, _acos, _asin, _atan, _atan2, _ceil, _clamp, _cos, _compatible, //
29
- _floor, _hypot, _isUnitless, _log, _max, _min, _percentage, _pow, //
30
- _randomFunction, _round, _sin, _sqrt, _tan, _unit, _div
45
+ _numberFunction ("abs" , (value) => value.abs ()),
46
+ _acos, _asin, _atan, _atan2, _ceil, _clamp, _cos, _compatible, _floor, //
47
+ _hypot, _isUnitless, _log, _max, _min, _percentage, _pow, _randomFunction,
48
+ _round, _sin, _sqrt, _tan, _unit, _div
31
49
], variables: {
32
50
"e" : SassNumber (math.e),
33
51
"pi" : SassNumber (math.pi),
@@ -89,8 +107,6 @@ final _round = _numberFunction("round", (number) => number.round().toDouble());
89
107
/// Distance functions
90
108
///
91
109
92
- final _abs = _numberFunction ("abs" , (value) => value.abs ());
93
-
94
110
final _hypot = _function ("hypot" , r"$numbers..." , (arguments) {
95
111
var numbers =
96
112
arguments[0 ].asList.map ((argument) => argument.assertNumber ()).toList ();
@@ -133,32 +149,87 @@ final _log = _function("log", r"$number, $base: null", (arguments) {
133
149
final _pow = _function ("pow" , r"$base, $exponent" , (arguments) {
134
150
var base = arguments[0 ].assertNumber ("base" );
135
151
var exponent = arguments[1 ].assertNumber ("exponent" );
136
- return pow (base , exponent);
152
+ if (base .hasUnits) {
153
+ throw SassScriptException ("\$ base: Expected $base to have no units." );
154
+ } else if (exponent.hasUnits) {
155
+ throw SassScriptException (
156
+ "\$ exponent: Expected $exponent to have no units." );
157
+ } else {
158
+ return SassNumber (math.pow (base .value, exponent.value));
159
+ }
137
160
});
138
161
139
- final _sqrt = _singleArgumentMathFunc ("sqrt" , sqrt);
162
+ final _sqrt = _function ("sqrt" , r"$number" , (arguments) {
163
+ var number = arguments[0 ].assertNumber ("number" );
164
+ if (number.hasUnits) {
165
+ throw SassScriptException ("\$ number: Expected $number to have no units." );
166
+ } else {
167
+ return SassNumber (math.sqrt (number.value));
168
+ }
169
+ });
140
170
141
171
///
142
172
/// Trigonometric functions
143
173
///
144
174
145
- final _acos = _singleArgumentMathFunc ("acos" , acos);
175
+ final _acos = _function ("acos" , r"$number" , (arguments) {
176
+ var number = arguments[0 ].assertNumber ("number" );
177
+ if (number.hasUnits) {
178
+ throw SassScriptException ("\$ number: Expected $number to have no units." );
179
+ } else {
180
+ return SassNumber .withUnits (math.acos (number.value) * 180 / math.pi,
181
+ numeratorUnits: ['deg' ]);
182
+ }
183
+ });
146
184
147
- final _asin = _singleArgumentMathFunc ("asin" , asin);
185
+ final _asin = _function ("asin" , r"$number" , (arguments) {
186
+ var number = arguments[0 ].assertNumber ("number" );
187
+ if (number.hasUnits) {
188
+ throw SassScriptException ("\$ number: Expected $number to have no units." );
189
+ } else {
190
+ return SassNumber .withUnits (math.asin (number.value) * 180 / math.pi,
191
+ numeratorUnits: ['deg' ]);
192
+ }
193
+ });
148
194
149
- final _atan = _singleArgumentMathFunc ("atan" , atan);
195
+ final _atan = _function ("atan" , r"$number" , (arguments) {
196
+ var number = arguments[0 ].assertNumber ("number" );
197
+ if (number.hasUnits) {
198
+ throw SassScriptException ("\$ number: Expected $number to have no units." );
199
+ } else {
200
+ return SassNumber .withUnits (math.atan (number.value) * 180 / math.pi,
201
+ numeratorUnits: ['deg' ]);
202
+ }
203
+ });
150
204
151
205
final _atan2 = _function ("atan2" , r"$y, $x" , (arguments) {
152
206
var y = arguments[0 ].assertNumber ("y" );
153
207
var x = arguments[1 ].assertNumber ("x" );
154
- return atan2 (y, x);
208
+ return SassNumber .withUnits (
209
+ math.atan2 (y.value, x.convertValueToMatch (y, 'x' , 'y' )) * 180 / math.pi,
210
+ numeratorUnits: ['deg' ]);
155
211
});
156
212
157
- final _cos = _singleArgumentMathFunc ("cos" , cos);
158
-
159
- final _sin = _singleArgumentMathFunc ("sin" , sin);
160
-
161
- final _tan = _singleArgumentMathFunc ("tan" , tan);
213
+ final _cos = _function (
214
+ "cos" ,
215
+ r"$number" ,
216
+ (arguments) => SassNumber (math.cos (arguments[0 ]
217
+ .assertNumber ("number" )
218
+ .coerceValueToUnit ("rad" , "number" ))));
219
+
220
+ final _sin = _function (
221
+ "sin" ,
222
+ r"$number" ,
223
+ (arguments) => SassNumber (math.sin (arguments[0 ]
224
+ .assertNumber ("number" )
225
+ .coerceValueToUnit ("rad" , "number" ))));
226
+
227
+ final _tan = _function (
228
+ "tan" ,
229
+ r"$number" ,
230
+ (arguments) => SassNumber (math.tan (arguments[0 ]
231
+ .assertNumber ("number" )
232
+ .coerceValueToUnit ("rad" , "number" ))));
162
233
163
234
///
164
235
/// Unit functions
@@ -234,16 +305,6 @@ final _div = _function("div", r"$number1, $number2", (arguments) {
234
305
/// Helpers
235
306
///
236
307
237
- /// Returns a [Callable] named [name] that calls a single argument
238
- /// math function.
239
- BuiltInCallable _singleArgumentMathFunc (
240
- String name, SassNumber mathFunc (SassNumber value)) {
241
- return _function (name, r"$number" , (arguments) {
242
- var number = arguments[0 ].assertNumber ("number" );
243
- return mathFunc (number);
244
- });
245
- }
246
-
247
308
/// Returns a [Callable] named [name] that transforms a number's value
248
309
/// using [transform] and preserves its units.
249
310
BuiltInCallable _numberFunction (String name, double transform (double value)) {
0 commit comments