9.5 KiB
JavaScript Calculation API: Draft 3.1
Table of Contents
Background
This section is non-normative.
This proposal simply exposes the calculation type to the JavaScript API.
Summary
This section is non-normative.
Design Decisions
Simplification
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.
API
import {List, ValueObject} from 'immutable';
import {Value, SassNumber, SassString} from '../spec/js-api/value';
Types
Value
declare module '../spec/js-api/value' {
interface Value {
assertCalculation
Returns this
if it's a SassCalculation
and throws an error otherwise.
The
name
parameter may be used for error reporting.
assertCalculation(name?: string): SassCalculation;
} // Value
} // module
Options
declare module '../spec/js-api/options' {
interface Options<sync extends 'sync' | 'async'> {
functions
Replace this option's specification with:
Before beginning compilation:
-
For each key/value pair
signature
/function
in this record:-
If
signature
isn't an followed immediately by anArgumentDeclaration
, throw an error. -
Let
name
besignature
's . -
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 associatedCustomFunction
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
whosesignature
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
CalculationValue
The type of values that can be arguments to a SassCalculation
.
export type CalculationValue =
| SassNumber
| SassCalculation
| SassString
| CalculationOperation
| CalculationInterpolation;
SassCalculation
The 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 {
internal
The private internal
field refers to a Sass calculation.
calc
Creates a value that represents calc(argument)
.
-
If
argument
is a quotedSassString
, throw an error. -
Return a calculation with name
"calc"
andargument
as its single argument.
static calc(argument: CalculationValue): SassCalculation;
min
Creates a value that represents min(...arguments)
.
-
If
arguments
contains a quotedSassString
, throw an error. -
Return a calculation with name
"min"
andarguments
as its arguments.
static min(
arguments: CalculationValue[] | List<CalculationValue>
): SassCalculation;
max
Creates a value that represents max(...arguments)
.
-
If
arguments
contains a quotedSassString
, throw an error. -
Return a calculation with name
"max"
andarguments
as its arguments.
static max(
arguments: CalculationValue[] | List<CalculationValue>
): SassCalculation;
clamp
Creates a value that represents calc(min, value, max)
expression.
-
If
min
,max
, orclamp
is a quotedSassString
, throw an error. -
If
value
is undefined andmax
is not undefined, throw an error. -
If either
value
ormax
is undefined and neithermin
norvalue
is aSassString
orCalculationInterpolation
, throw an error. -
Return a calculation with name
"clamp"
andmin
,value
, andmax
as its arguments, excluding any arguments that are undefined.
static clamp(
min: CalculationValue,
value?: CalculationValue,
max?: CalculationValue
): SassCalculation;
name
Returns internal
's name
field.
get name(): string;
Returns a list of internal
's arguments.
get arguments(): List<CalculationValue>;
} // SassCalculation
CalculationOperator
The set of possible operators in a Sass calculation.
export type CalculationOperator = '+' | '-' | '*' | '/';
CalculationOperation
The JS API representation of a Sass CalculationOperation
.
export class CalculationOperation implements ValueObject {
internal
A private property like Value.internal
that refers to a Sass
CalculationOperation
.
Constructor
Creates a Sass CalculationOperation
:
- Throw an error if
left
orright
is a quotedSassString
. - Set the fields to the arguments of the corresponding names.
- Return the resulting
CalculationOperation
.
constructor(
operator: CalculationOperator,
left: CalculationValue,
right: CalculationValue
);
operator
Returns internal
's operator
field.
get operator(): CalculationOperator;
left
Returns internal
's left
field.
get left(): CalculationValue;
right
Returns internal
's right
field.
get right(): CalculationValue;
equals
Whether internal
is equal to other.internal
in Sass.
equals(other: unknown): boolean;
hashCode
Returns the same number for any two CalculationOperation
s that are equal
according to equals
.
hashCode(): number;
} // CalculationOperation
CalculationInterpolation
The JS API representation of a Sass CalculationInterpolation
.
export class CalculationInterpolation implements ValueObject {
internal
A private property like Value.internal
that refers to a Sass
CalculationInterpolation
.
Constructor
Creates a Sass CalculationInterpolation
by setting the value
field to the
value
argument and returns it.
constructor(value: string);
value
Returns internal
's value
field.
get value(): string;
equals
Whether internal
is equal to other.internal
in Sass.
equals(other: unknown): boolean;
hashCode
Returns the same number for any two CalculationInterpolation
s that are equal
according to equals
.
hashCode(): number;
} // CalculationInterpolation