Skip to content

Commit

Permalink
Revert "Adds built-in clamp() and hypot() (#906)"
Browse files Browse the repository at this point in the history
This reverts commit 24f84e2.
  • Loading branch information
jathak committed Jan 2, 2020
1 parent 3c64add commit 7628040
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 122 deletions.
8 changes: 0 additions & 8 deletions CHANGELOG.md
@@ -1,11 +1,3 @@
## 1.25.0

* Add functions to the built-in "sass:math" module.
* `clamp()`: given a `$min`, $number`, and `$max` values, clamps the `$number`
in between `$min` and `$max`.
* `hypot()`: given *n* numbers, outputs the length of the *n*-dimensional
vector that has components equal to each of the inputs.

## 1.24.0

* Add an optional `with` clause to the `@forward` rule. This works like the
Expand Down
153 changes: 40 additions & 113 deletions lib/src/functions/math.dart
Expand Up @@ -13,60 +13,34 @@ import '../module/built_in.dart';
import '../util/number.dart';
import '../value.dart';

/// A random number generator.
final _random = math.Random();

/// The global definitions of Sass math functions.
final global = UnmodifiableListView([
_abs, _ceil, _floor, _max, _min, _percentage, _randomFunction, _round,
_unit, //
_compatible.withName("comparable"),
_round, _ceil, _floor, _abs, _max, _min, _randomFunction, _unit, //
_percentage,
_isUnitless.withName("unitless"),
_compatible.withName("comparable")
]);

/// The Sass math module.
final module = BuiltInModule("math", functions: [
_abs, _ceil, _clamp, _compatible, _floor, _hypot, _isUnitless, _max, _min, //
_percentage, _randomFunction, _round, _unit,
_round, _ceil, _floor, _abs, _max, _min, _randomFunction, _unit,
_isUnitless, //
_percentage, _compatible
]);

/// Returns a [Callable] named [name] that transforms a number's value
/// using [transform] and preserves its units.
BuiltInCallable _numberFunction(String name, num transform(num value)) {
return BuiltInCallable(name, r"$number", (arguments) {
var number = arguments[0].assertNumber("number");
return SassNumber.withUnits(transform(number.value),
numeratorUnits: number.numeratorUnits,
denominatorUnits: number.denominatorUnits);
});
}

///
/// Bounding functions
///
final _ceil = _numberFunction("ceil", (value) => value.ceil());

final _clamp = BuiltInCallable("clamp", r"$min, $number, $max", (arguments) {
var min = arguments[0].assertNumber("min");
var number = arguments[1].assertNumber("number");
var max = arguments[2].assertNumber("max");

if (min.hasUnits == number.hasUnits && number.hasUnits == max.hasUnits) {
if (min.greaterThanOrEquals(max).isTruthy) return min;
if (min.greaterThanOrEquals(number).isTruthy) return min;
if (number.greaterThanOrEquals(max).isTruthy) return max;
return number;
}

var arg2 = min.hasUnits != number.hasUnits ? number : max;
var arg2Name = min.hasUnits != number.hasUnits ? "\$number" : "\$max";
var unit1 = min.hasUnits ? "has unit ${min.unitString}" : "is unitless";
var unit2 = arg2.hasUnits ? "has unit ${arg2.unitString}" : "is unitless";

throw SassScriptException(
"\$min $unit1 but $arg2Name $unit2. Arguments must all have units or all "
"be unitless.");
final _percentage = BuiltInCallable("percentage", r"$number", (arguments) {
var number = arguments[0].assertNumber("number");
number.assertNoUnits("number");
return SassNumber(number.value * 100, '%');
});

final _round = _numberFunction("round", fuzzyRound);
final _ceil = _numberFunction("ceil", (value) => value.ceil());
final _floor = _numberFunction("floor", (value) => value.floor());
final _abs = _numberFunction("abs", (value) => value.abs());

final _max = BuiltInCallable("max", r"$numbers...", (arguments) {
SassNumber max;
Expand All @@ -88,86 +62,39 @@ final _min = BuiltInCallable("min", r"$numbers...", (arguments) {
throw SassScriptException("At least one argument must be passed.");
});

final _round = _numberFunction("round", fuzzyRound);

///
/// Distance functions
///
final _abs = _numberFunction("abs", (value) => value.abs());

final _hypot = BuiltInCallable("hypot", r"$numbers...", (arguments) {
var numbers =
arguments[0].asList.map((argument) => argument.assertNumber()).toList();

if (numbers.isEmpty) {
throw SassScriptException("At least one argument must be passed.");
}

var numeratorUnits = numbers[0].numeratorUnits;
var denominatorUnits = numbers[0].denominatorUnits;
var subtotal = 0.0;

for (var i = 0; i < numbers.length; i++) {
var number = numbers[i];

if (number.hasUnits != numbers[0].hasUnits) {
var unit1 = numbers[0].hasUnits
? "has unit ${numbers[0].unitString}"
: "is unitless";
var unit2 =
number.hasUnits ? "has unit ${number.unitString}" : "is unitless";
throw SassScriptException(
"Argument 1 $unit1 but argument ${i + 1} $unit2. Arguments must all "
"have units or all be unitless.");
}

number = number.coerce(numeratorUnits, denominatorUnits);
subtotal += math.pow(number.value, 2);
final _randomFunction = BuiltInCallable("random", r"$limit: null", (arguments) {
if (arguments[0] == sassNull) return SassNumber(_random.nextDouble());
var limit = arguments[0].assertNumber("limit").assertInt("limit");
if (limit < 1) {
throw SassScriptException("\$limit: Must be greater than 0, was $limit.");
}

return SassNumber.withUnits(math.sqrt(subtotal),
numeratorUnits: numeratorUnits, denominatorUnits: denominatorUnits);
});

///
/// Unit functions
///
final _compatible =
BuiltInCallable("compatible", r"$number1, $number2", (arguments) {
var number1 = arguments[0].assertNumber("number1");
var number2 = arguments[1].assertNumber("number2");
return SassBoolean(number1.isComparableTo(number2));
});

final _isUnitless = BuiltInCallable("is-unitless", r"$number", (arguments) {
var number = arguments[0].assertNumber("number");
return SassBoolean(!number.hasUnits);
return SassNumber(_random.nextInt(limit) + 1);
});

final _unit = BuiltInCallable("unit", r"$number", (arguments) {
var number = arguments[0].assertNumber("number");
return SassString(number.unitString, quotes: true);
});

///
/// Other functions
///
final _percentage = BuiltInCallable("percentage", r"$number", (arguments) {
final _isUnitless = BuiltInCallable("is-unitless", r"$number", (arguments) {
var number = arguments[0].assertNumber("number");
number.assertNoUnits("number");
return SassNumber(number.value * 100, '%');
return SassBoolean(!number.hasUnits);
});

final _random = math.Random();

final _randomFunction = BuiltInCallable("random", r"$limit: null", (arguments) {
if (arguments[0] == sassNull) return SassNumber(_random.nextDouble());
var limit = arguments[0].assertNumber("limit").assertInt("limit");
if (limit < 1) {
throw SassScriptException("\$limit: Must be greater than 0, was $limit.");
}
return SassNumber(_random.nextInt(limit) + 1);
final _compatible =
BuiltInCallable("compatible", r"$number1, $number2", (arguments) {
var number1 = arguments[0].assertNumber("number1");
var number2 = arguments[1].assertNumber("number2");
return SassBoolean(number1.isComparableTo(number2));
});

/// Returns a [Callable] named [name] that transforms a number's value
/// using [transform] and preserves its units.
BuiltInCallable _numberFunction(String name, num transform(num value)) {
return BuiltInCallable(name, r"$number", (arguments) {
var number = arguments[0].assertNumber("number");
return SassNumber.withUnits(transform(number.value),
numeratorUnits: number.numeratorUnits,
denominatorUnits: number.denominatorUnits);
});
}
2 changes: 1 addition & 1 deletion pubspec.yaml
@@ -1,5 +1,5 @@
name: sass
version: 1.25.0-dev
version: 1.24.0
description: A Sass implementation in Dart.
author: Sass Team
homepage: https://github.com/sass/dart-sass
Expand Down

0 comments on commit 7628040

Please sign in to comment.