@@ -30,6 +30,9 @@ Markup Shorthands: markdown yes
30
30
[data-algorithm] :not(.heading) > :last-child {
31
31
margin-bottom: 0;
32
32
}
33
+ [data-algorithm] [data-algorithm] {
34
+ margin: 1em 0;
35
+ }
33
36
</style>
34
37
35
38
<pre class=anchors>
@@ -723,26 +726,215 @@ The following are the arithmetic operations you can perform on dimensions:
723
726
into another one with the specified |unit|.
724
727
When called, it must perform the following steps:
725
728
726
- 1. If |unit| does not have a [=CSS type=] ,
727
- [=throw=] a {{SyntaxError}}
728
- and abort this algorithm .
729
+ 1. Let |type| be the result of [=creating a type=] from |unit|.
730
+ If |type| is failure,
731
+ [=throw=] a {{SyntaxError}} .
729
732
730
- 2. If |this| is a {{CSSUnitValue}}
731
- and |this|’s {{CSSUnitValue/unit}} internal slot and |unit| are [=compatible units=] ,
732
- return a new {{CSSUnitValue}}
733
- with its {{CSSUnitValue/unit}} internal slot set to |unit|
734
- and its {{CSSUnitValue/value}} internal slot set to |this|’s {{CSSUnitValue/value}}
735
- multiplied by the conversion ratio between the two units.
736
-
737
- 3. If |this| is a {{CSSCalcValue}} :
738
- 1. Let |sum| be 0.
739
- 2. [=map/For each=] |oldUnit| → |value| in |this|’s [=map entries=] :
740
- 1. If |oldUnit| and |unit| are not [=compatible units=] ,
741
- [=throw=] a {{TypeError}} .
742
- 2. Increment |sum| by |value| times the conversion ratio between |oldUnit| and |unit|.
743
- 3. Return a new {{CSSUnitValue}}
744
- with its {{CSSUnitValue/unit}} internal slot set to |unit|
745
- and its {{CSSUnitValue/value}} internal slot set to |sum|.
733
+ 2. Let |sum| be the result of [=creating a sum value=] from |this|.
734
+ If |sum| is failure,
735
+ [=throw=] a {{TypeError}} .
736
+
737
+ 3. If |sum| has more than one [=list/item=] ,
738
+ [=throw=] a {{TypeError}} .
739
+ Otherwise, let |item| be the sole [=list/item=] in |sum|.
740
+
741
+ 4. If |item| has more than one [=map/value=] in its [=sum value/unit map=] ,
742
+ or that single [=map/value=] ’s value is anything other than `1`,
743
+ [=throw=] a {{TypeError}} .
744
+ Otherwise, let |item unit| be the sole [=map/key=] in the [=sum value/unit map=] ,
745
+ and |item value| be |item|’s [=sum value/value=] .
746
+
747
+ 5. If |unit| and |item unit| are not [=compatible units=] ,
748
+ [=throw=] a {{TypeError}} .
749
+
750
+ 6. Return a new {{CSSUnitValue}}
751
+ whose {{CSSUnitValue/unit}} internal slot
752
+ is set to |unit|,
753
+ and whose {{CSSUnitValue/value}} internal slot
754
+ is set to |item value|
755
+ multiplied by the conversion ratio between |item unit|
756
+ and |unit|.
757
+ </div>
758
+
759
+ <div algorithm="sum value">
760
+ A <dfn>sum value</dfn>
761
+ is an abstract representation of a {{CSSNumericValue}}
762
+ as a sum of numbers with (possibly complex) units.
763
+ Not all {{CSSNumericValue}} s can be expressed as a [=sum value=] .
764
+
765
+ A [=sum value=] is a [=list=] .
766
+ Each entry in the list is a [=tuple=] of a <dfn for="sum value">value</dfn> ,
767
+ which is a number,
768
+ and a <dfn for="sum value">unit map</dfn> ,
769
+ which is a [=ordered map|map=] of units (strings) to powers (integers).
770
+
771
+ <div class=example>
772
+ Here are a few examples of CSS values,
773
+ and their equivalent [=sum values=] :
774
+
775
+ * ''1px'' becomes `«(1, «"px"→1»)»`
776
+ * ''calc(1px + 1in)'' becomes `«(97, «"px"→1»)»`
777
+ (because ''in'' and ''px'' are [=compatible units=] ,
778
+ and ''px'' is the [=canonical unit=] for them)
779
+ * ''calc(1px + 2em)'' becomes `«(1, «"px"→1»), (2, «"em"→»1)»`
780
+ * ''calc(1px * 2em)'' becomes `«(2, «"em"→1, "px"→1»)»`
781
+ * ''calc(1px + 1deg)'' can't be represented as a [=sum value=]
782
+ because it's an invalid computation
783
+ * ''calc(1px * 1deg)'' becomes `«(2, «"deg"→1, "px"→1»)»`
784
+ </div>
785
+
786
+ To <dfn lt="create a sum value|creating a sum value">create a sum value</dfn> from a {{CSSNumericValue}} |this|,
787
+ the steps differ based on |this|’s class:
788
+
789
+ <dl class=switch>
790
+ : {{CSSUnitValue}}
791
+ ::
792
+ <div algorithm="sum value from CSSUnitValue">
793
+ 1. Let |unit| be the value of |this|’s {{CSSUnitValue/unit}} internal slot,
794
+ and |value| be the value of |this|’s {{CSSUnitValue/value}} internal slot.
795
+ 2. If |unit| is a member of a set of [=compatible units=] ,
796
+ and is not the set's [=canonical unit=] ,
797
+ multiply |value| by the conversion ratio between |unit| and the [=canonical unit=] ,
798
+ and change |unit| to the [=canonical unit=] .
799
+ 3. If |unit| is `"number"`,
800
+ return «(|value|, «»)».
801
+ 3. Otherwise, return <code> «(|value|, «|unit|→1»)»</code> .
802
+ </div>
803
+
804
+ : {{CSSMathSum}}
805
+ ::
806
+ <div algorithm="sum value from CSSMathSum">
807
+ 1. Let |values| initially be an empty list.
808
+
809
+ 2. [=list/For each=] |item| in |this|’s {{CSSMathSum/values}} internal slot:
810
+
811
+ 1. Let |value| be the result of [=creating a sum value=] from |item|.
812
+ If |value| is failure,
813
+ return failure.
814
+
815
+ 2. [=list/For each=] |subvalue| of |value|:
816
+
817
+ 1. If |values| already contains an [=list/item=]
818
+ with the same [=sum value/unit map=] as |subvalue|,
819
+ increment that [=list/item=] ’s [=sum value/value=]
820
+ by the [=sum value/value=] of |subvalue|.
821
+
822
+ 2. Otherwise, [=list/append=] |subvalue| to |values|.
823
+
824
+ 3. [=create a type from a unit map|Create a type=]
825
+ from the [=sum value/unit map=]
826
+ of each [=list/item=] of |values|,
827
+ and [=add=] all the types together.
828
+ If the result is failure,
829
+ return failure.
830
+
831
+ 4. Return |values|.
832
+ </div>
833
+
834
+ : {{CSSMathNegate}}
835
+ ::
836
+ <div algorithm="sum value from CSSMathNegate">
837
+ 1. Let |values| be the result of [=creating a sum value=]
838
+ from |this|’s {{CSSMathNegate/value}} internal slot.
839
+
840
+ 2. If |values| is failure,
841
+ return failure.
842
+
843
+ 3. Negate the [=sum value/value=] of each [=list/item=] of |values|.
844
+
845
+ 4. Return |values|.
846
+ </div>
847
+
848
+ : {{CSSMathProduct}}
849
+ ::
850
+ <div algorithm="sum value from CSSMathProduct">
851
+ 1. Let |values| initially be the [=sum value=] «(1, «»)».
852
+ (I.e. what you'd get from ''1'' .)
853
+
854
+ 2. [=list/For each=] |item| in |this|’s {{CSSMathProduct/values}} internal slot:
855
+
856
+ 1. Let |new values| be the result of [=creating a sum value=] from |item|.
857
+ Let |temp| initially be an empty [=list=] .
858
+
859
+ 2. [=list/For each=] |item1| in |values|:
860
+
861
+ 1. [=list/For each=] |item2| in |new values|:
862
+
863
+ 1. Let |item| be a [=tuple=] with its [=sum value/value=]
864
+ set to the product of the [=sum value/values=] of |item1| and |item2|,
865
+ and its [=sum value/unit map=]
866
+ set to the union of the [=sum value/unit maps=] of |item1| and |item2|,
867
+ with all [=map/entries=] with a zero value removed.
868
+
869
+ 2. Append |item| to |temp|.
870
+
871
+ 3. Set |values| to |temp|.
872
+
873
+ 3. Return |values|.
874
+ </div>
875
+
876
+ : {{CSSMathInvert}}
877
+ ::
878
+ <div algorithm="sum value from CSSMathInvert">
879
+ 1. Let |values| be the result of [=creating a sum value=]
880
+ from |this|’s {{CSSMathInvert/value}} internal slot.
881
+
882
+ 2. If |values| is failure,
883
+ return failure.
884
+
885
+ 3. If the length of [=values=] is more than one,
886
+ return failure.
887
+
888
+ 3. Invert (find the reciprocal of) the [=sum value/value=] of the [=list/item=] in |values|,
889
+ and negate the [=map/value=] of each [=map/entry=] in its [=sum value/unit map=] .
890
+
891
+ 4. Return |values|.
892
+ </div>
893
+
894
+ : {{CSSMathMin}}
895
+ ::
896
+ <div algorithm="sum value from CSSMathMin">
897
+ 1. Let |args| be the result of [=creating a sum value=]
898
+ [=list/for each=] [=list/item=] in |this|’s {{CSSMathMin/values}} internal slot.
899
+
900
+ 2. If any [=list/item=] of |args| has a length greater than one,
901
+ return failure.
902
+
903
+ 3. If not all of the [=sum value/unit maps=] among the [=list/items=] of |args| are identical,
904
+ return failure.
905
+
906
+ 4. Return the [=list/item=] of |args| whose sole [=list/item=] has the smallest [=sum value/value=] .
907
+ </div>
908
+
909
+ : {{CSSMathMax}}
910
+ ::
911
+ <div algorithm="sum value from CSSMathMax">
912
+ 1. Let |args| be the result of [=creating a sum value=]
913
+ [=list/for each=] [=list/item=] in |this|’s {{CSSMathMax/values}} internal slot.
914
+
915
+ 2. If any [=list/item=] of |args| has a length greater than one,
916
+ return failure.
917
+
918
+ 3. If not all of the [=sum value/unit maps=] among the [=list/items=] of |args| are identical,
919
+ return failure.
920
+
921
+ 4. Return the [=list/item=] of |args| whose sole [=list/item=] has the largest [=sum value/value=] .
922
+ </div>
923
+ </dl>
924
+
925
+ <div algorithm>
926
+ To <dfn>create a type from a unit map</dfn> |unit map|:
927
+
928
+ 1. Let |types| be an initially empty [=list=] .
929
+
930
+ 2. [=map/For each=] |unit| → |power| in |unit map|:
931
+
932
+ 1. Let |type| be the result of [=creating a type=] from |unit|.
933
+ 2. Set |type|’s sole [=map/value=] to |power|.
934
+ 3. [=list/Append=] |type| to |types|.
935
+
936
+ 3. Return the result of [=multiplying=] all the [=list/items=] of |types|.
937
+ </div>
746
938
</div>
747
939
748
940
The {{CSSNumericValue/parse()}} method allows a {{CSSNumericValue}}
0 commit comments