mirror of
https://github.com/sass/sass.git
synced 2024-09-21 18:47:25 +00:00
[First-Class Calc] Throw errors for definitely-incompatible units
This commit is contained in:
parent
437ce42ea2
commit
be097e6cf2
@ -3,6 +3,8 @@
|
|||||||
* Store interpolations as a separate data type so that they can be parenthesized
|
* Store interpolations as a separate data type so that they can be parenthesized
|
||||||
when used in `CalculationOperation`s.
|
when used in `CalculationOperation`s.
|
||||||
|
|
||||||
|
* Throw errors when combining units that are known to be incompatible.
|
||||||
|
|
||||||
* Allow variables in `CalcValue`s to return calculations.
|
* Allow variables in `CalcValue`s to return calculations.
|
||||||
|
|
||||||
* Fix some broken formatting.
|
* Fix some broken formatting.
|
||||||
|
@ -11,6 +11,9 @@
|
|||||||
* ["Contagious" Calculations](#contagious-calculations)
|
* ["Contagious" Calculations](#contagious-calculations)
|
||||||
* [Interpolation in `calc()`](#interpolation-in-calc)
|
* [Interpolation in `calc()`](#interpolation-in-calc)
|
||||||
* [Vendor Prefixed `calc()`](#vendor-prefixed-calc)
|
* [Vendor Prefixed `calc()`](#vendor-prefixed-calc)
|
||||||
|
* [Definitions](#definitions)
|
||||||
|
* [Possibly-Compatible Units](#possibly-compatible-units)
|
||||||
|
* [Possibly-Compatible Numbers](#possibly-compatible-numbers)
|
||||||
* [Syntax](#syntax)
|
* [Syntax](#syntax)
|
||||||
* [`SpecialFunctionExpression`](#specialfunctionexpression)
|
* [`SpecialFunctionExpression`](#specialfunctionexpression)
|
||||||
* [`CalcExpression`](#calcexpression)
|
* [`CalcExpression`](#calcexpression)
|
||||||
@ -200,6 +203,49 @@ vendor-prefixed `calc()` expressions will continue to be parsed as opaque
|
|||||||
special functions the way they always have, but they will not be interoperable
|
special functions the way they always have, but they will not be interoperable
|
||||||
with any of the new calculation features this proposal adds.
|
with any of the new calculation features this proposal adds.
|
||||||
|
|
||||||
|
## Definitions
|
||||||
|
|
||||||
|
### Possibly-Compatible Units
|
||||||
|
|
||||||
|
Two units are *possibly-compatible* with one another if and only if either both
|
||||||
|
units appear in the same row in the following table, or either unit doesn't
|
||||||
|
appear in the following table. Units are matched case-insensitively to determine
|
||||||
|
possible-compatibility.
|
||||||
|
|
||||||
|
> This is intended to be kept in sync with the unit types in [CSS Values and
|
||||||
|
> Units]. Note that all unknown units are possibly-compatible with all other
|
||||||
|
> units; this preserves forwards-compatibility with new units that are
|
||||||
|
> introduced in browsers over time.
|
||||||
|
|
||||||
|
[CSS Values and Units]: https://www.w3.org/TR/css-values-3/
|
||||||
|
|
||||||
|
| Type | Units |
|
||||||
|
| -------------- | -------------------------------------------------------------------------------------------- |
|
||||||
|
| `<length>` | `em`, `ex`, `ch`, `rem`, `vw`, `vh`, `vmin`, `vmax`, `cm`, `mm`, `Q`, `in`, `pt`, `pc`, `px` |
|
||||||
|
| `<angle>` | `deg`, `grad`, `rad`, `turn` |
|
||||||
|
| `<time>` | `s`, `ms` |
|
||||||
|
| `<frequency>` | `Hz`, `kHz` |
|
||||||
|
| `<resolution>` | `dpi`, `dpcm`, `dppx` |
|
||||||
|
|
||||||
|
### Possibly-Compatible Numbers
|
||||||
|
|
||||||
|
Two numbers are *possibly-compatible* if there's a one-to-one mapping between
|
||||||
|
their numerator units, and another such mapping between their denominator units,
|
||||||
|
such that each pair of units is [possibly-compatible](#possibly-compatible-units).
|
||||||
|
Two numbers are *definitely-incompatible* if they are not possibly-compatible.
|
||||||
|
|
||||||
|
> The definition of definite-incompatibility captures the notion of numbers that
|
||||||
|
> can be determined at build time to be incompatible with one another, and thus
|
||||||
|
> erroneous to ever combine. This allows us to eagerly produce error messages
|
||||||
|
> for certain incompatible units rather than serving them to the browser where
|
||||||
|
> they're much more difficult to debug.
|
||||||
|
>
|
||||||
|
> For example, `1px` is possibly-compatible with `2em`. Unitless numbers are
|
||||||
|
> only possibly-compatible with other unitless numbers. In theory, this
|
||||||
|
> definition defines a notion of possible-compatiblity for numbers with more
|
||||||
|
> complex units, but in practice these numbers are already flagged as errors
|
||||||
|
> prior to any possible-compatibility checks.
|
||||||
|
|
||||||
## Syntax
|
## Syntax
|
||||||
|
|
||||||
### `SpecialFunctionExpression`
|
### `SpecialFunctionExpression`
|
||||||
@ -372,14 +418,24 @@ This algorithm takes a calculation `calc` and returns a number or a calculation.
|
|||||||
it.
|
it.
|
||||||
|
|
||||||
* If `calc`'s name is `"min"`, `"max"`, or `"clamp"` and `arguments` are all
|
* If `calc`'s name is `"min"`, `"max"`, or `"clamp"` and `arguments` are all
|
||||||
numbers whose units are mutually [compatible], return the result of calling
|
numbers:
|
||||||
[`math.min()`], [`math.max()`], or `math.clamp()` (respectively) with those
|
|
||||||
arguments.
|
* If those arguments' units are mutually [compatible], return the result of
|
||||||
|
calling [`math.min()`], [`math.max()`], or `math.clamp()` (respectively)
|
||||||
|
with those arguments.
|
||||||
|
|
||||||
[compatible]: ../spec/types/number.md#compatible-units
|
[compatible]: ../spec/types/number.md#compatible-units
|
||||||
[`math.min()`]: ../spec/built-in-modules/math.md#min
|
[`math.min()`]: ../spec/built-in-modules/math.md#min
|
||||||
[`math.max()`]: ../spec/built-in-modules/math.md#max
|
[`math.max()`]: ../spec/built-in-modules/math.md#max
|
||||||
|
|
||||||
|
* Otherwise, if any of those arguments have more than one numerator unit or
|
||||||
|
more than zero denominator units, throw an error.
|
||||||
|
|
||||||
|
* Otherwise, if any two of those arguments are [definitely-incompatible],
|
||||||
|
throw an error.
|
||||||
|
|
||||||
|
[definitely-incompatible]: #possibly-compatible-numbers
|
||||||
|
|
||||||
* Otherwise, return a calculation with the same name as `calc` and `arguments`
|
* Otherwise, return a calculation with the same name as `calc` and `arguments`
|
||||||
as its arguments.
|
as its arguments.
|
||||||
|
|
||||||
@ -413,10 +469,11 @@ This algorithm takes a `CalculationValue` `value` and returns a
|
|||||||
* If `left` and `right` are both numbers with [compatible] units, return
|
* If `left` and `right` are both numbers with [compatible] units, return
|
||||||
`left + right` or `left - right`, respectively.
|
`left + right` or `left - right`, respectively.
|
||||||
|
|
||||||
> TODO: Should we throw an error here for units we can prove are actively
|
* Otherwise, if either `left` or `right` is a number with more than one
|
||||||
> incompatible? For example, unitless numbers are always incompatible with
|
numerator unit or more than zero denominator units, throw an error.
|
||||||
> numbers of any units, and numbers across different known types (length +
|
|
||||||
> time) are also invalid.
|
* Otherwise, if `left` and `right` are [definitely-incompatible] numbers,
|
||||||
|
throw an error.
|
||||||
|
|
||||||
> TODO: Should we try to simplify `calc(1px + 1% + 1px)`?
|
> TODO: Should we try to simplify `calc(1px + 1% + 1px)`?
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user