Skip to content

Commit 00e80fa

Browse files
committed
Mostly done with Typed-Calc patch.
1 parent 2732add commit 00e80fa

File tree

1 file changed

+165
-54
lines changed

1 file changed

+165
-54
lines changed

css-typed-om/Overview.bs

Lines changed: 165 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -841,30 +841,160 @@ rather than on {{CSSNumericValue}} instances.
841841
and return the result.
842842
</div>
843843

844-
{{CSSNumericValue}}s can be <dfn export for=CSSNumericValue lt="strong type|strongly typed">strongly typed</dfn> to a type
845-
and/or <dfn export for=CSSNumericValue lt="weak type|weakly typed">weakly typed</dfn> to one or more types,
846-
or <dfn export for=CSSNumericValue>untyped</dfn>.
844+
### Numeric Value Typing ### {#numeric-typing}
845+
846+
Each {{CSSNumericValue}} has an associated <dfn for=CSSNumericValue>type</dfn>,
847+
which is a combination of an [=ordered map|map=] of [=base types=] to integers,
848+
and a [=percent hint=].
849+
The <dfn for=CSSNumericValue lt="base type">base types</dfn> are
850+
"length",
851+
"angle",
852+
"time",
853+
"frequency",
854+
"resolution",
855+
"flex",
856+
and "percent".
857+
The ordering of a [=type=]’s entries always matches this [=base type=] ordering.
858+
The <dfn for=CSSNumericValue>percent hint</dfn>
859+
is either null or a [=base type=] other than "percent".
847860

848-
A {{CSSUnitValue}} is [=weakly typed=] to the [=CSS type=] of its {{CSSUnitValue/unit}} internal slot’s value
849-
if that [=CSS type=] is "percent" or "number".
850-
It's [=strongly typed=] to that [=CSS type=] otherwise.
851-
It's never [=untyped=].
861+
<div algorithm>
862+
To <dfn local-lt="add | addition">add two types</dfn> |type1| and |type2|,
863+
perform the following steps:
864+
865+
1. Replace |type1| with a fresh copy of |type1|,
866+
and |type2| with a fresh copy of |type2|.
867+
Let |finalType| be a new [=type=]
868+
with an initially empty [=ordered map=]
869+
and an initially null [=percent hint=].
870+
871+
2.
872+
<dl class=switch>
873+
: If both |type1| and |type2| have non-null [=percent hints=]
874+
with different values
875+
:: The types can't be added.
876+
Return failure.
877+
878+
: If |type1| has a non-null [=percent hint=] |hint| and |type2| doesn't
879+
:: [=Apply the percent hint=] |hint| to |type2|.
880+
881+
Vice versa if |type2| has a non-null [=percent hint=] and |type1| doesn't.
882+
883+
: Otherwise
884+
:: Continue to the next step.
885+
</dl>
886+
887+
888+
3.
889+
<dl class=switch>
890+
: If all the [=map/entries=] of |type1| with non-zero values
891+
are [=map/contained=] in |type2| with the same value,
892+
and vice-versa
893+
:: Copy all of |type1|’s [=map/entries=] to |finalType|,
894+
and then copy all of |type2|’s [=map/entries=] to |finalType|
895+
that |finalType| doesn't already [=map/contain=].
896+
Set |finalType|’s [=percent hint=] to |type1|’s [=percent hint=].
897+
Return |finalType|.
898+
899+
: If |type1| and/or |type2| [=map/contain=] "percent" with a non-zero value,
900+
and |type1| and/or |type2| [=map/contain=] a key *other than* "percent" with a non-zero value
901+
:: For each [=base type=] other than "percent" |hint|:
902+
903+
1. Provisionally [=apply the percent hint=] |hint| to both |type1| and |type2|.
904+
905+
2. If, afterwards, all the [=map/entries=] of |type1| with non-zero values
906+
are [=map/contained=] in |type2| with the same value,
907+
and vice versa,
908+
then copy all of |type1|’s [=map/entries=] to |finalType|,
909+
and then copy all of |type2|’s [=map/entries=] to |finalType|
910+
that |finalType| doesn't already [=map/contain=].
911+
Set |finalType|’s [=percent hint=] to |hint|.
912+
Return |finalType|.
913+
914+
3. Otherwise, revert |type1| and |type2| to their state at the start of this loop.
915+
916+
If the loop finishes without returning |finalType|,
917+
then the types can't be added.
918+
Return failure.
919+
920+
Note: You can shortcut this in some cases
921+
by just checking the sum of all the [=map/values=]
922+
of |type1| vs |type2|.
923+
If the sums are different,
924+
the types can't be added.
925+
926+
: Otherwise
927+
:: The types can't be added.
928+
Return failure.
929+
</dl>
930+
</div>
931+
932+
<div algorithm>
933+
To <dfn>apply the percent hint</dfn> |hint| to a |type|,
934+
perform the following steps:
935+
936+
1. If |type| doesn't [=map/contain=] |hint|, set |type|[|hint|] to 0.
937+
2. If |type| [=map/contains=] "percent", add |type|["percent"] to |type|[|hint|],
938+
then set |type|["percent"] to 0.
939+
4. Set |type|’s [=percent hint=] to |hint|.
940+
</div>
852941

853-
A {{CSSMathSum}}, {{CSSMathProduct}}, {{CSSMathMin}}, or {{CSSMathMax}}
854-
is [=strongly typed=]
855-
if any of the values in its {{CSSMathSum/values}} internal slot
856-
are [=strongly typed=],
857-
to that same [=strong type=].
858-
It's [=weakly typed=] to the union of the [=weak types=]
859-
of all of the values in its {{CSSMathSum/values}} internal slot.
860-
It's [=untyped=] if its {{CSSMathSum/values}} internal slot [=list/is empty=].
942+
<div algorithm>
943+
To <dfn for=CSSNumericValue local-lt="multiply | multiplication">multiply two types</dfn> |type1| and |type2|,
944+
perform the following steps:
945+
946+
1. Replace |type1| with a fresh copy of |type1|,
947+
and |type2| with a fresh copy of |type2|.
948+
Let |finalType| be a new [=type=]
949+
with an initially empty [=ordered map=]
950+
and an initially null [=percent hint=].
951+
952+
2. If both |type1| and |type2| have non-null [=percent hints=]
953+
with different values,
954+
the types can't be multiplied.
955+
Return failure.
956+
957+
3. If |type1| has a non-null [=percent hint=] |hint| and |type2| doesn't,
958+
[=apply the percent hint=] |hint| to |type2|.
861959

862-
A {{CSSMathNegate}} or {{CSSMathInvert}}
863-
is [=strongly typed=],
864-
[=weakly typed=],
865-
or [=untyped=]
866-
identically to the value in its {{CSSMathNegate/value}} internal slot.
960+
Vice versa if |type2| has a non-null [=percent hint=] and |type1| doesn't.
961+
962+
4. Copy all of |type1|’s [=map/entries=] to |finalType|,
963+
then [=map/for each=] |baseType| → |power| of |type2|:
964+
965+
1. If |finalType|[|baseType|] [=map/exists=],
966+
increment its value by |power|.
967+
2. Otherwise, set |finalType|[|baseType|] to |power|.
968+
969+
Set |finalType|’s [=percent hint=] to |type1|’s [=percent hint=].
970+
971+
5. Return |finalType|.
972+
</div>
867973

974+
A [=type=] is said to <dfn for=CSSNumericValue>match</dfn> a CSS production in some circumstances:
975+
976+
* A [=type=] matches <<length>>
977+
if its only non-zero [=map/entry=] is «[ "length" → 1 ]»
978+
and its [=percent hint=] is null.
979+
Similarly for <<angle>>, <<time>>, <<frequency>>, <<resolution>>, and <<flex>>.
980+
* A [=type=] matches <<percentage>>
981+
if its only non-zero [=map/entry=] is «[ "percent" → 1 ]».
982+
* A [=type=] matches <<length-percentage>>
983+
if its only non-zero [=map/entry=] is either «[ "length" → 1 ]» or «[ "percentage" → 1 ]»
984+
Same for <<angle-percentage>>, <<time-percentage>>, etc.
985+
* A [=type=] matches <<number>>
986+
if it has no non-zero [=map/entries=]
987+
and its [=percent hint=] is null.
988+
* A [=type=] matches <<number-percentage>>
989+
if it has no non-zero [=map/entries=],
990+
or its only non-zero [=map/entry=] is «[ "percentage" → 1 ]».
991+
992+
Many specifications use ''[ <<length>> | <<percentage>> ]''
993+
instead of ''<<length-percentage>>'' in their grammar,
994+
and specify in prose that the <<length>> and <<percentage>> can be combined.
995+
For the purposes of [=matching=],
996+
these cases should be treated as <<length-percentage>>.
997+
Similarly for <<angle-percentage>>, etc.
868998

869999

8701000

@@ -937,40 +1067,37 @@ are represented as {{CSSUnitValue}}s.
9371067
<div algorithm="CSSUnitValue.type">
9381068
The <dfn attribute for=CSSUnitValue>type</dfn> attribute of a {{CSSUnitValue}} |this| must,
9391069
on reading,
940-
return the [=CSS type=] of |this|’s {{CSSUnitValue/unit}} internal slot’s value.
1070+
1071+
Issue: Figure out how we're exposing types. This should probably move up to the superclass, then.
9411072
</div>
9421073

9431074
<div algorithm="CSS type of a unit">
944-
The <dfn>CSS type</dfn> of a string |unit| is:
1075+
The [=type=] of a {{CSSUnitValue}}
1076+
depends on its {{CSSUnitValue/unit}} as follows:
9451077

9461078
<dl class=switch>
9471079
: |unit| is "number"
948-
:: "number"
1080+
:: [=type=] is «[ ]» (empty map)
9491081
: |unit| is "percent"
950-
:: "percent"
1082+
:: [=type=] is «[ "percent" → 1 ]»
9511083
: |unit| is a <<length>> unit
952-
:: "length"
1084+
:: [=type=] is «[ "length" → 1 ]»
9531085
: |unit| is an <<angle>> unit
954-
:: "angle"
1086+
:: [=type=] is «[ "angle" → 1 ]»
9551087
: |unit| is a <<time>> unit
956-
:: "time"
1088+
:: [=type=] is «[ "time" → 1 ]»
9571089
: |unit| is a <<frequency>> unit
958-
:: "frequency"
1090+
:: [=type=] is «[ "frequence" → 1 ]»
9591091
: |unit| is a <<resolution>> unit
960-
:: "resolution"
1092+
:: [=type=] is «[ "resolution" → 1 ]»
9611093
: |unit| is a <<flex>> unit
962-
:: "flex"
1094+
:: [=type=] is «[ "flex" → 1 ]»
9631095
: anything else
9641096
:: the string does not have a [=CSS type=]
9651097
</dl>
966-
</div>
9671098

968-
A {{CSSUnitValue}} matches a CSS type production,
969-
such as <<number>> or <<length>>,
970-
if its equivalent CSS value
971-
(with the same value and unit,
972-
or similar with "number" and "percent")
973-
matches that production.
1099+
In all cases, the [=percent hint=] of the [=type=] is null.
1100+
</div>
9741101

9751102
<div algorithm>
9761103
When asked to <dfn export local-lt="new unit value">create a new unit value</dfn>
@@ -1111,24 +1238,8 @@ of all the "math" operations.
11111238
The <dfn attribute for="CSSMathValue, CSSMathSum, CSSMathProduct, CSSMathMin, CSSMathMax, CSSMathNegate, CSSMathInvert">type</dfn> attribute
11121239
of a {{CSSMathValue}} |this| must,
11131240
on reading,
1114-
perform the following steps:
1115-
1116-
1. Let |types| initially be an empty [=ordered set=].
1117-
1118-
2. If |this| has a [=strong type=],
1119-
[=set/append=] its [=strong type=] to |types|.
1120-
1121-
3. If |this| has the "percent" [=weak type=],
1122-
[=set/append=] "percent" to |types|.
1123-
1124-
4. If |this| has the "number" [=weak type=],
1125-
[=set/append=] "number" to |types|.
1126-
1127-
5. Return the concatenation of the strings in |types|,
1128-
each separated by a U+002D HYPHEN-MINUS (-) character.
11291241

1130-
Note: This implies that if |this| is [=untyped=],
1131-
this attribute returns the empty string.
1242+
Issue: Figure out how we're outputting .type
11321243
</div>
11331244

11341245
<div algorithm="CSSMathSum(...args)">

0 commit comments

Comments
 (0)