accepted/calculation-api.d.ts.md
This section is non-normative.
This proposal simply exposes the calculation type to the JavaScript API.
This section is non-normative.
We considered eagerly simplifying calculations as they were constructed to match the behavior of values in Sass itself. However, this poses a problem for API implementations that don't have direct access to compiler logic, such as the Node.js embedded host: they would need to implement the simplification logic locally, which is relatively complex and opens a broad surface area for subtle cross-implementation incompatibilities.
This could potentially be solved by adding an explicit request to the embedded protocol, but this would pose its own problems given that JS is strict about separating asynchronous calls (like those across process boundaries) and synchronous calls (like this API).
Given that, we chose instead to handle simplification only at the custom function boundary rather than when a calculation is constructed.
import {List, ValueObject} from 'immutable';
import {Value, SassNumber, SassString} from '../spec/js-api/value';
Valuedeclare module '../spec/js-api/value' {
interface Value {
assertCalculationReturns this if it's a SassCalculation and throws an error otherwise.
The
nameparameter may be used for error reporting.
assertCalculation(name?: string): SassCalculation;
} // Value
} // module
Optionsdeclare module '../spec/js-api/options' {
interface Options<sync extends 'sync' | 'async'> {
functionsReplace this option's specification with:
Before beginning compilation:
For each key/value pair signature/function in this record:
If signature isn't an <ident-token> followed immediately by an
ArgumentDeclaration, throw an error.
Let name be signature's <ident-token>.
If there's already a global function whose name is
underscore-insensitively equal to name, continue to the next
key/value pair.
Otherwise, add a global function whose signature is signature. When
this function is called:
Let result be the result of calling the associated
CustomFunction with the given arguments. If this call throws an
error, treat it as a Sass error thrown by the Sass function.
As in the rest of Sass,
_s and-s are considered equivalent when determining which function signatures match.
Throw an error if result is or transitively contains:
An object that's not an instance of the Value class.
A SassFunction whose signature field isn't a valid Sass
function signature that could appear after the @function
directive in a Sass stylesheet.
Return a copy of result.internal with all calculations it
transitively contains (including the return value itself if it's a
calculation) replaced with the result of simplifying those
calculations.
functions?: Record<string, CustomFunction<sync>>;
} // Options
} // module
CalculationValueThe type of values that can be arguments to a SassCalculation.
export type CalculationValue =
| SassNumber
| SassCalculation
| SassString
| CalculationOperation
| CalculationInterpolation;
SassCalculationThe JS API representation of a Sass calculation.
Note: in the JS API calculations are not simplified eagerly. This also means that unsimplified calculations are not equal to the numbers they would be simplified to.
export class SassCalculation extends Value {
internalThe private internal field refers to a Sass calculation.
calcCreates a value that represents calc(argument).
If argument is a quoted SassString, throw an error.
Return a calculation with name "calc" and argument as its single argument.
static calc(argument: CalculationValue): SassCalculation;
minCreates a value that represents min(...arguments).
If arguments contains a quoted SassString, throw an error.
Return a calculation with name "min" and arguments as its arguments.
static min(
arguments: CalculationValue[] | List<CalculationValue>
): SassCalculation;
maxCreates a value that represents max(...arguments).
If arguments contains a quoted SassString, throw an error.
Return a calculation with name "max" and arguments as its arguments.
static max(
arguments: CalculationValue[] | List<CalculationValue>
): SassCalculation;
clampCreates a value that represents calc(min, value, max) expression.
If min, max, or clamp is a quoted SassString, throw an error.
If value is undefined and max is not undefined, throw an error.
If either value or max is undefined and neither min nor value is a
SassString or CalculationInterpolation, throw an error.
Return a calculation with name "clamp" and min, value, and max as its
arguments, excluding any arguments that are undefined.
static clamp(
min: CalculationValue,
value?: CalculationValue,
max?: CalculationValue
): SassCalculation;
nameReturns internal's name field.
get name(): string;
Returns a list of internal's arguments.
get arguments(): List<CalculationValue>;
} // SassCalculation
CalculationOperatorThe set of possible operators in a Sass calculation.
export type CalculationOperator = '+' | '-' | '*' | '/';
CalculationOperationThe JS API representation of a Sass CalculationOperation.
export class CalculationOperation implements ValueObject {
internalA private property like Value.internal that refers to a Sass
CalculationOperation.
Creates a Sass CalculationOperation:
left or right is a quoted SassString.CalculationOperation.constructor(
operator: CalculationOperator,
left: CalculationValue,
right: CalculationValue
);
operatorReturns internal's operator field.
get operator(): CalculationOperator;
leftReturns internal's left field.
get left(): CalculationValue;
rightReturns internal's right field.
get right(): CalculationValue;
equalsWhether internal is equal to other.internal in Sass.
equals(other: unknown): boolean;
hashCodeReturns the same number for any two CalculationOperations that are equal
according to equals.
hashCode(): number;
} // CalculationOperation
CalculationInterpolationThe JS API representation of a Sass CalculationInterpolation.
export class CalculationInterpolation implements ValueObject {
internalA private property like Value.internal that refers to a Sass
CalculationInterpolation.
Creates a Sass CalculationInterpolation by setting the value field to the
value argument and returns it.
constructor(value: string);
valueReturns internal's value field.
get value(): string;
equalsWhether internal is equal to other.internal in Sass.
equals(other: unknown): boolean;
hashCodeReturns the same number for any two CalculationInterpolations that are equal
according to equals.
hashCode(): number;
} // CalculationInterpolation