Skip to content

Commit 374cd73

Browse files
committed
Initial commit of the new calc() stuff. Still many dangling references.
1 parent 26b53b1 commit 374cd73

File tree

1 file changed

+179
-89
lines changed

1 file changed

+179
-89
lines changed

css-typed-om/Overview.bs

Lines changed: 179 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -222,8 +222,8 @@ future without breaking code that relies on calling
222222
{{StylePropertyMap/set()}} for those properties.
223223
</div>
224224

225-
The <dfn method for=StylePropertyMap>append(DOMString <var>property</var>,
226-
(CSSStyleValue or DOMString)... <var>values</var>)</dfn> method, when invoked, must
225+
The <dfn method for=StylePropertyMap>append(DOMString <var>property</var>,
226+
(CSSStyleValue or DOMString)... <var>values</var>)</dfn> method, when invoked, must
227227
[=append to a StylePropertyMap=] with property <var>property</var> and values <var>values</var>.
228228

229229
<div algorithm>
@@ -316,7 +316,7 @@ Issue(276): interaction with custom properties
316316

317317
Issue(309): should StylePropertyMaps be case sensitive?
318318

319-
Issue(310): consider using properties in addition to get/set
319+
Issue(310): consider using properties in addition to get/set
320320

321321
Computed {{StylePropertyMapReadOnly}} objects {#computed-stylepropertymapreadonly-objects}
322322
--------------------------------------------------------------------------
@@ -524,7 +524,8 @@ Numeric Values: {#numeric-objects}
524524

525525
* {{CSSUnitValue}} objects represent values that contain a single unit type
526526
(for example "42px").
527-
* {{CSSCalcValue}} objects represent values that contain multiple units
527+
* {{CSSMathValue}} objects represent math expressions,
528+
which can contain more than one value/unit
528529
(for example "calc(56em + 10%)").
529530

530531
{{CSSNumericValue}} objects are not range-restricted.
@@ -748,21 +749,31 @@ rather than on {{CSSNumericValue}} instances.
748749
with its [=map entries=] set to |newEntries|.
749750
</div>
750751

751-
{{CSSNumericValue}}s can be <dfn>strongly typed</dfn>
752-
or <dfn>weakly typed</dfn> to a type,
753-
or <dfn>untyped</dfn>.
752+
{{CSSNumericValue}}s can be <dfn export for=CSSNumericValue lt="strong type|strongly typed">strongly typed</dfn> to a type
753+
and/or <dfn export for=CSSNumericValue lt="weak type|weakly typed">weakly typed</dfn> to one or more types,
754+
or <dfn export for=CSSNumericValue>untyped</dfn>.
754755

755-
A {{CSSUnitValue}} is [=weakly typed=] to its [=CSS type=]
756+
A {{CSSUnitValue}} is [=weakly typed=] to the [=CSS type=] of its {{CSSUnitValue/unit}} internal slot’s value
756757
if that [=CSS type=] is "percent" or "number".
757-
It's [=strongly typed=] to its [=CSS type=] otherwise.
758+
It's [=strongly typed=] to that [=CSS type=] otherwise.
758759
It's never [=untyped=].
759760

760-
A {{CSSCalcValue}} is [=strongly typed=] if its [=CSS type set=]
761-
contains a value other than "percent" or "number",
762-
to that value.
763-
It's [=weakly typed=] if it's not [=strongly typed=],
764-
but its [=CSS type set=] [=set/is not empty=].
765-
It's [=untyped=] if its [=CSS type set=] [=set/is empty=].
761+
A {{CSSMathSum}}, {{CSSMathProduct}}, {{CSSMathMin}}, or {{CSSMathMax}}
762+
is [=strongly typed=]
763+
if any of the values in its {{CSSMathSum/values}} internal slot
764+
are [=strongly typed=],
765+
to that same [=strong type=].
766+
It's [=weakly typed=] to the union of the [=weak types=]
767+
of all of the values in its {{CSSMathSum/values}} internal slot.
768+
It's [=untyped=] if its {{CSSMathSum/values}} internal slot [=list/is empty=].
769+
770+
A {{CSSMathNegate}} or {{CSSMathInvert}}
771+
is [=strongly typed=],
772+
[=weakly typed=],
773+
or [=untyped=]
774+
identically to the value in its {{CSSMathNegate/value}} internal slot.
775+
776+
766777

767778

768779
<!--
@@ -834,7 +845,7 @@ are represented as {{CSSUnitValue}}s.
834845
<div algorithm="CSSUnitValue.type">
835846
The <dfn attribute for=CSSUnitValue>type</dfn> attribute of a {{CSSUnitValue}} |this| must,
836847
on reading,
837-
return the [=CSS type=] of |this|’s {{CSSUnitValue/unit}}.
848+
return the [=CSS type=] of |this|’s {{CSSUnitValue/unit}} internal slot’s value.
838849
</div>
839850

840851
<div algorithm="CSS type of a unit">
@@ -880,110 +891,189 @@ matches that production.
880891
██████ ██ ██ ████████ ██████ ███ ███
881892
-->
882893

883-
### Complex Numeric Values: {{CSSCalcValue}} objects ### {#complex-numeric}
894+
### Complex Numeric Values: {{CSSMathValue}} objects ### {#complex-numeric}
884895

885-
Numeric values that can only be expressed with a combination of units
886-
are represented as {{CSSCalcValue}}.
887-
This is a Map-like value,
888-
where each entry represents the value of one unit,
889-
and the object as a whole represents the sum of its units.
896+
Numeric values that are more complicated than a single value+unit
897+
are represented by a tree of {{CSSMathValue}} subclasses,
898+
eventually terminating in {{CSSUnitValue}} objects at the leaf nodes.
899+
The ''calc()'', ''min()'', and ''max()'' functions in CSS
900+
are represented in this way.
890901

891902
<div class=example>
892903
For example,
893904
the CSS value ''calc(1em + 5px)''
894-
will be represented by a {{CSSCalcValue}}
895-
[=map/contains|containing=] <nobr>«[ "em" → 1, "px" → 5 ]»</nobr>.
905+
will be represented by a {{CSSMathSum}}
906+
like <code>CSSMathSum(CSS.em(1), CSS.px(5))</code>.
907+
908+
A more complex expression,
909+
like ''calc(1em + 5px * 2)'',
910+
will be represented by a nested structure
911+
like <code>CSSMathSum(CSS.em(1), CSSMathProduct(CSS.px(5), 2))</code>.
896912
</div>
897913

898914
<xmp class=idl>
899-
[Constructor(record<DOMString, double> recordValue)]
900-
interface CSSCalcValue : CSSNumericValue {
901-
maplike<DOMString, double>;
902-
CSSCalcValue set(DOMString unit, double value);
915+
interface CSSMathValue : CSSNumericValue {
916+
readonly attribute CSSMathOperator operator;
903917
readonly attribute DOMString type;
904918
};
919+
920+
[Constructor(CSSNumericValue... args)]
921+
interface CSSMathSum : CSSMathValue {
922+
attribute CSSNumericArray values;
923+
};
924+
925+
[Constructor(CSSNumericValue... args)]
926+
interface CSSMathProduct : CSSMathValue {
927+
attribute CSSNumericArray values;
928+
};
929+
930+
[Constructor(CSSNumericValue... args)]
931+
interface CSSMathMin : CSSMathValue {
932+
attribute CSSNumericArray values;
933+
};
934+
935+
[Constructor(CSSNumericValue... args)]
936+
interface CSSMathMax : CSSMathValue {
937+
attribute CSSNumericArray values;
938+
};
939+
940+
[Constructor(CSSNumericValue arg)]
941+
interface CSSMathNegate : CSSMathValue {
942+
attribute CSSNumericValue value;
943+
};
944+
945+
[Constructor(CSSNumericValue arg)]
946+
interface CSSMathInvert : CSSMathValue {
947+
attribute CSSNumericValue value;
948+
};
949+
950+
interface CSSNumericArray {}; // See issue below
951+
952+
enum CSSMathOperator {
953+
"+",
954+
"-",
955+
"*",
956+
"/",
957+
"min",
958+
"max",
959+
};
905960
</xmp>
906961

907-
<div algorithm="CSSCalcValue(recordValue)">
908-
The <dfn constructor for=CSSCalcValue>CSSCalcValue(|recordValue|)</dfn> constructor must,
909-
when called,
910-
perform the following steps:
962+
Issue: {{CSSNumericArray}} will be an Array-like
963+
restricted to containing CSSNumericValue objects.
964+
This is dependent on [WebIDL#345](https://github.com/heycam/webidl/issues/345) getting resolved properly.
911965

912-
1. Let |strongType| be initially null.
966+
Note: CSSMathValue, being a pure superclass,
967+
cannot be directly constructed.
968+
It exists solely to host the common attributes
969+
of all the "math" operations.
913970

914-
2. [=map/For each=] unit → value of |recordValue|:
971+
<div algorithm="CSSMathValue.operator">
972+
The <dfn attribute for="CSSMathValue, CSSMathSum, CSSMathProduct, CSSMathMin, CSSMathMax, CSSMathNegate, CSSMathInvert">operator</dfn> attribute
973+
of a {{CSSMathValue}} |this| must,
974+
on getting,
975+
return the following string,
976+
depending on the interface of |this|:
915977

916-
1. If |unit| does not have a [=CSS type=],
917-
[=throw=] a {{TypeError}}.
918-
2. If |unit| is a [=strong type=],
919-
and |strongType| is null,
920-
let |strongType| be |unit|’s [=CSS type=].
921-
3. If |unit| is a [=strong type=],
922-
and |strongType| is not equal to that type,
923-
[=throw=] a {{TypeError}}.
978+
<dl class=switch>
979+
: {{CSSMathSum}}
980+
:: <code>"+"</code>
924981

925-
3. Return a new {{CSSCalcValue}} whose <a>map entries</a> are |recordValue|.
926-
</div>
982+
: {{CSSMathProduct}}
983+
:: <code>"*"</code>
927984

928-
Issue: When IDL grows a map-iterator concept,
929-
add a constructor that takes one.
930-
It's supremely awkward to handle one manually right now.
985+
: {{CSSMathMin}}
986+
:: <code>"min"</code>
931987

932-
<div algorithm="CSSCalcValue.set()">
933-
The <dfn method for=CSSCalcValue>set(|unit|, |value|)</dfn> method,
934-
when called on a {{CSSCalcValue}} |this|,
935-
must perform the following steps:
988+
: {{CSSMathMax}}
989+
:: <code>"max"</code>
936990

937-
1. Let |newType| be the [=CSS type=] of |unit|.
938-
If |unit| does not have a [=CSS type=],
939-
[=throw=] a {{TypeError}}.
991+
: {{CSSMathNegate}}
992+
:: <code>"-"</code>
940993

941-
2. If |this| has no [=strong type=],
942-
or if |newType| is "percent", "number",
943-
or equal to |this|’s [=strong type=],
944-
[=map/set=] the key |unit| to the value |value| in |this|’s [=map entries=],
945-
and return |this|.
994+
: {{CSSMathInvert}}
995+
:: <code>"/"</code>
996+
</dl>
946997

947-
3. Otherwise, [=throw=] a {{TypeError}}.
998+
Note: These are all instances of the {{CSSMathOperator}} enum.
948999
</div>
9491000

950-
<div algorithm="CSSCalcValue.type">
951-
The <dfn attribute for=CSSCalcValue>type</dfn> attribute
952-
of a {{CSSCalcValue}} |this| must,
1001+
<div algorithm="CSSMathValue.type">
1002+
The <dfn attribute for="CSSMathValue, CSSMathSum, CSSMathProduct, CSSMathMin, CSSMathMax, CSSMathNegate, CSSMathInvert">type</dfn> attribute
1003+
of a {{CSSMathValue}} |this| must,
9531004
on reading,
954-
must return the concatenation of the entries in |this|’s [=CSS type set=],
955-
each separated by a U+002D HYPHEN-MINUS (-) character.
956-
If there are multiple entries,
957-
they must be concatenated in the order:
958-
[=strong type=],
959-
"percent",
960-
"number".
961-
962-
Note: This implies that if the [=CSS type set=] is empty
963-
(because |this| [=map/is empty=]),
1005+
perform the following steps:
1006+
1007+
1. Let |types| initially be an empty [=ordered set=].
1008+
1009+
2. If |this| has a [=strong type=],
1010+
[=ordered set/append=] its [=strong type=] to |types|.
1011+
1012+
3. If |this| has the "percent" [=weak type=],
1013+
[=ordered set/append=] "percent" to |types|.
1014+
1015+
4. If |this| has the "number" [=weak type=],
1016+
[=ordered set/append=] "number" to |types|.
1017+
1018+
5. Return the concatenation of the strings in |types|,
1019+
each separated by a U+002D HYPHEN-MINUS (-) character.
1020+
1021+
Note: This implies that if |this| is [=untyped=],
9641022
this attribute returns the empty string.
9651023
</div>
9661024

967-
<div algorithm="CSS type set">
968-
The <dfn for=CSSCalcValue>CSS type set</dfn> of a {{CSSCalcValue}} |this|
969-
is an [=ordered set=]
970-
that contains the [=CSS types=] of every key
971-
[=map/contains|contained=] in |this|’s [=map entries=].
1025+
<div algorithm="CSSMathSum(...args)">
1026+
The <dfn constructor for="CSSMathSum">CSSMathSum(...|args|)</dfn> constructor must,
1027+
when called,
1028+
perform the following steps:
1029+
1030+
1. If |args| [=list/is empty=],
1031+
[=throw=] a {{SyntaxError}}.
1032+
1033+
2. Let |strongType| initially be null.
9721034

973-
Note: The [=CSS type set=] will contain at most 3 entries;
974-
"percent", "number",
975-
and this {{CSSCalcValue}}’s [=strong type=].
1035+
3. Let |values| be an initially empty [=list=].
1036+
1037+
4. [=list/For each=] |arg| of |args|:
1038+
1039+
1. If |arg| has a [=strong type=], and |strongType| is null,
1040+
let |strongType| by |arg|’s [=strong type=].
1041+
1042+
2. If |arg| has a [=strong type=],
1043+
and |strongType| is not equal to that type,
1044+
[=throw=] a {{TypeError}}.
1045+
1046+
3. [=list/Append=] |arg| to |values|.
1047+
1048+
5. Return a new {{CSSMathSum}}
1049+
whose {{CSSMathSum/values}} internal slot
1050+
is set to |values|.
1051+
1052+
The <dfn constructor for="CSSMathProduct">CSSMathProduct(...|args|)</dfn>,
1053+
<dfn constructor for="CSSMathMin">CSSMathMin(...|args|)</dfn>,
1054+
and <dfn constructor for="CSSMathMax">CSSMathMax(...|args|)</dfn> constructors
1055+
are defined identically to the above,
1056+
except that in the last step
1057+
they return a new {{CSSMathProduct}}, {{CSSMathMin}}, or {{CSSMathMax}} object,
1058+
respectively.
9761059
</div>
9771060

978-
A {{CSSCalcValue}} has a <dfn for=CSSCalcValue>strong type</dfn>
979-
if its [=CSS type set=] [=set/contains=] a value other than "percent" or "number",
980-
equal to that other value.
1061+
<div algorithm="CSSMathNegate(arg)">
1062+
The <dfn constructor for="CSSMathNegate">CSSMathNegate(|arg|)</dfn> constructor must,
1063+
when called,
1064+
perform the following steps:
1065+
1066+
1. Return a new {{CSSMathNegate}}
1067+
whose {{CSSMathNegate/value}} internal slot
1068+
is set to |arg|.
1069+
1070+
The <dfn constructor for="CSSMathInvert">CSSMathInvert(|arg|)</dfn> constructor
1071+
is defined identically to the above,
1072+
except that in the last step
1073+
it returns a new {{CSSMathInvert}} object.
1074+
</div>
9811075

982-
A {{CSSCalcValue}} matches a CSS type production,
983-
such as <<number>> or <<length-percentage>>,
984-
if its equivalent CSS ''calc()'' value matches that production.
9851076

986-
Issue(359): Need to be able to deal with min()/max() too
9871077

9881078
<!--
9891079
██ ██ ██ ██ ██ ██ ██████ ██████ ██████
@@ -1624,7 +1714,7 @@ This section describes how Typed OM objects are constructed from CSS values.
16241714

16251715
If a property's grammar is more complex than one of the types listed here,
16261716
it produces a raw {{CSSStyleValue}},
1627-
with a <a for=CSSStyleValue>stringification behavior</a>
1717+
with a <a for=CSSStyleValue>stringification behavior</a>
16281718
that produces the CSSOM serialization of the property.
16291719

16301720
Issue: Better to define a full table of properties and what types they normalize to.

0 commit comments

Comments
 (0)