Skip to content

Commit 381409d

Browse files
committed
Describe how to normalize a math expression.
1 parent e0dd265 commit 381409d

File tree

1 file changed

+75
-36
lines changed

1 file changed

+75
-36
lines changed

css-typed-om/Overview.bs

Lines changed: 75 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -804,16 +804,8 @@ rather than on {{CSSNumericValue}} instances.
804804
[=throw=] a {{SyntaxError}}
805805
and abort this algorithm.
806806

807-
3. If |result| is a <<dimension-token>>, <<number-token>>, or <<percentage-token>>,
808-
return a new {{CSSUnitValue}} object
809-
with its {{CSSUnitValue/value}} internal slot set to the token's value,
810-
and its {{CSSUnitValue/value}} internal slot set to the token's unit if it's a <<dimension-token>>,
811-
or `"number"` if it's a <<number-token>>,
812-
or `"percentage"` if it's a <<percentage-token>>.
813-
814-
4. If |result| is a <<calc()>>:
815-
816-
Issue: TODO
807+
3. [=Normalize a numeric value=] |result|,
808+
and return the result.
817809
</div>
818810

819811
{{CSSNumericValue}}s can be <dfn export for=CSSNumericValue lt="strong type|strongly typed">strongly typed</dfn> to a type
@@ -1877,8 +1869,8 @@ CSS <<number>>, <<percentage>>, and <<dimension>> values become {{CSSUnitValue}}
18771869
<div algorithm>
18781870
To <dfn export>normalize a numeric value</dfn> |num|:
18791871

1880-
1. If |num| is a ''calc()'' expression,
1881-
[=normalize a calc() expression=] from |num|
1872+
1. If |num| is a ''calc()'', ''min()'', or ''max()'' expression,
1873+
[=normalize a math expression=] from |num|
18821874
and return the result.
18831875

18841876
2. If |num| is the unitless value ''0'' and |num| is a <<dimension>>,
@@ -1898,34 +1890,81 @@ CSS <<number>>, <<percentage>>, and <<dimension>> values become {{CSSUnitValue}}
18981890
</div>
18991891

19001892
<div algorithm>
1901-
To <dfn export>normalize a ''calc()'' expression</dfn> |num|
1902-
1903-
1. Simplify |num| into an equivalent summation of terms with unique units
1904-
(preserving terms with a zero value).
1905-
1906-
2. If |num| is a [=computed value=] and |num| contains only a single term,
1907-
[=normalize a numeric value=] from that single term
1908-
and return the result.
1909-
1910-
3. Return a {{CSSCalcValue}},
1911-
whose [=map entries=] is an ordered map which contains, in order:
1912-
1913-
1. If |num| contains a <<number>> term,
1914-
the [=map/entry=] «[ "number" → |val| ]»,
1915-
where |val| is the value of that term.
1916-
2. If |num| contains any <<dimension>> terms,
1917-
the [=map/entries=] «[ |unit| → |val| ]» for each term,
1918-
where |unit| is the term's unit and |val| is the term's value,
1919-
sorted in [=ASCII case-insensitive=] alphabetical order by their |unit|.
1920-
3. If |num| contains a <<percentage>> term,
1921-
the [=map/entry=] «[ "percent" → |val| ]»,
1922-
where |val| is the value of that term.
1893+
To <dfn for=CSSMath export local-lt="normalize">normalize a math expression</dfn> |num|:
1894+
1895+
1. If |num| is a ''min()'' or ''max()'' expression:
1896+
1. Let |values| be the result of [=CSSMath/normalizing=]
1897+
the arguments to the expression,
1898+
treating each argument as if it were the contents of a ''calc()'' expression.
1899+
1900+
2. Return a new {{CSSMathMin}} or {{CSSMathMax}} object, respectively,
1901+
with its {{CSSMathMin/values}} internal slot
1902+
set to |values|.
1903+
1904+
2. Assert: Otherwise, |num| is a ''calc()''.
1905+
1906+
3. Turn |num|’s argument
1907+
into an expression tree
1908+
using standard PEMDAS precedence rules,
1909+
with the following exceptions/clarification:
1910+
1911+
* Treat subtraction as instead being addition,
1912+
with the RHS argument instead wrapped in a special "negate" node.
1913+
* Treat division as instead being multiplication,
1914+
with the RHS argument instead wrapped in a special "invert" node.
1915+
* Addition and multiplication are N-ary;
1916+
each node can have any number of arguments.
1917+
* If an expression has only a single value in it,
1918+
and no operation,
1919+
treat it as an addition node with the single argument.
1920+
1921+
4. Recursively transform the expression tree into objects,
1922+
as follows:
1923+
1924+
<dl class=switch>
1925+
: addition node
1926+
:: becomes a new {{CSSMathSum}} object,
1927+
with its {{CSSMathSum/values}} internal slot
1928+
set to its list of arguments
1929+
: multiplication node
1930+
:: becomes a new {{CSSMathProduct}} object,
1931+
with its {{CSSMathProduct/values}} internal slot
1932+
set to its list of arguments
1933+
: negate node
1934+
:: becomes a new {{CSSMathNegate}} object,
1935+
with its {{CSSMathNegate/value}} internal slot
1936+
set to its argument
1937+
: invert node
1938+
:: becomes a new {{CSSMathInvert}} object,
1939+
with its {{CSSMathInvert/value}} internal slot
1940+
set to its argument
1941+
: leaf node
1942+
:: normalized as appropriate
1943+
</dl>
1944+
1945+
<div class=example>
1946+
For example, ''calc(1px - 2 * 3em)''
1947+
produces the structure:
1948+
1949+
<pre>
1950+
CSSMathSum(
1951+
CSS.px(1),
1952+
CSSMathNegate(
1953+
CSSMathProduct(
1954+
2,
1955+
CSS.em(3)
1956+
)
1957+
)
1958+
)
1959+
</pre>
1960+
</div>
19231961

19241962
Note: The value computation process may transform different units into identical ones,
19251963
simplifying the resulting expression.
19261964
For example, ''calc(1px + 2em)'' as a specified value
1927-
results in a {{CSSCalcValue}} with <nobr>«[ "em" → 2, "px" → 1 ]»</nobr>,
1928-
but as a computed value will give a {{CSSUnitValue}} something like <code>{unit: "px", value: 33}</code>.
1965+
results in a <nobr><code>CSSMathSum(CSS.px(1), CSS.em(2))</code></nobr>,
1966+
but as a computed value will give <nobr><code>CSS.px(33)</code></nobr> or similar
1967+
(depending on the value of an ''em'' in that context).
19291968
</div>
19301969

19311970

0 commit comments

Comments
 (0)