@@ -16,6 +16,7 @@ module Internal.Model exposing
1616 , LayoutContext(..)
1717 , Length(..)
1818 , Location(..)
19+ , NearbyChildren(..)
1920 , NodeName(..)
2021 , Option(..)
2122 , OptionRecord
@@ -29,6 +30,7 @@ module Internal.Model exposing
2930 , TransformComponent(..)
3031 , Transformation(..)
3132 , VAlign(..)
33+ , Variant(..)
3234 , XYZ
3335 , addNodeName
3436 , addWhen
@@ -40,7 +42,7 @@ module Internal.Model exposing
4042 , asParagraph
4143 , asRow
4244 , asTextColumn
43− , boxShadowName
45+ , boxShadowClass
4446 , columnClass
4547 , composeTransformation
4648 , contextClasses
@@ -77,40 +79,30 @@ module Internal.Model exposing
7779 , onlyStyles
7880 , optionsToRecord
7981 , paddingName
82+ , paddingNameFloat
8083 , pageClass
8184 , paragraphClass
8285 , reduceRecursive
83− , reduceRecursiveCalcName
8486 , reduceStyles
8587 , reduceStylesRecursive
8688 , removeNever
87− , renderFocusStyle
88− , renderFont
8989 , renderFontClassName
9090 , renderHeight
9191 , renderRoot
92+ , renderVariant
9293 , renderWidth
9394 , rootStyle
9495 , rowClass
9596 , singleClass
96− , skippable
97− , sortedReduce
9897 , spacingName
99− , staticRoot
10098 , tag
101− , textElement
102− , textElementFill
103− , textShadowName
99+ , textShadowClass
104100 , toHtml
105101 , toStyleSheet
106− , toStyleSheetString
107102 , transformClass
108− , transformValue
109− , unit
110103 , unstyled
111− , untransformed
112104 , unwrapDecorations
113− , unwrapDecsHelper
105+ , variantName
114106 )
115107
116108{-| -}
@@ -120,7 +112,7 @@ import Html.Attributes
120112import Html.Keyed
121113import Internal.Flag as Flag exposing (Flag)
122114import Internal.Style exposing (classes, dot)
123−import Json.Encode as Json
115+import Json.Encode as Encode
124116import Set exposing (Set)
125117import VirtualDom
126118
@@ -182,7 +174,7 @@ type Style
182174 | Colored String String Color
183175 | SpacingStyle String Int Int
184176 | BorderWidth String Int Int Int Int
185− | PaddingStyle String Int Int Int Int
177+ | PaddingStyle String Float Float Float Float
186178 | GridTemplateStyle
187179 { spacing : ( Length, Length )
188180 , columns : List Length
@@ -213,12 +205,86 @@ type PseudoClass
213205 | Active
214206
215207
208+{-| -}
209+type alias Adjustment =
210+ { capital : Float
211+ , lowercase : Float
212+ , baseline : Float
213+ , descender : Float
214+ }
215+
216+
216217type Font
217218 = Serif
218219 | SansSerif
219220 | Monospace
220221 | Typeface String
221222 | ImportFont String String
223+ | FontWith
224+ { name : String
225+ , adjustment : Maybe Adjustment
226+ , variants : List Variant
227+ }
228+
229+
230+type Variant
231+ = VariantActive String
232+ | VariantOff String
233+ | VariantIndexed String Int
234+
235+
236+renderVariant var =
237+ case var of
238+ VariantActive name ->
239+ "\"" ++ name ++ "\""
240+
241+ VariantOff name ->
242+ "\"" ++ name ++ "\" 0"
243+
244+ VariantIndexed name index ->
245+ "\"" ++ name ++ "\" " ++ String.fromInt index
246+
247+
248+variantName var =
249+ case var of
250+ VariantActive name ->
251+ name
252+
253+ VariantOff name ->
254+ name ++ "-0"
255+
256+ VariantIndexed name index ->
257+ name ++ "-" ++ String.fromInt index
258+
259+
260+renderVariants typeface =
261+ case typeface of
262+ FontWith font ->
263+ Just (String.join ", " (List.map renderVariant font.variants))
264+
265+ _ ->
266+ Nothing
267+
268+
269+isSmallCaps var =
270+ case var of
271+ VariantActive name ->
272+ name == "smcp"
273+
274+ VariantOff name ->
275+ False
276+
277+ VariantIndexed name index ->
278+ name == "smcp" && index == 1
279+
280+
281+hasSmallCaps typeface =
282+ case typeface of
283+ FontWith font ->
284+ List.any isSmallCaps font.variants
285+
286+ _ ->
287+ False
222288
223289
224290type Property
@@ -306,6 +372,13 @@ type NodeName
306372 | Embedded String String
307373
308374
375+type NearbyChildren msg
376+ = NoNearbyChildren
377+ | ChildrenBehind (List (Html.Html msg))
378+ | ChildrenInFront (List (Html.Html msg))
379+ | ChildrenBehindAndInFront (List (Html.Html msg)) (List (Html.Html msg))
380+
381+
309382div =
310383 Generic
311384
@@ -314,7 +387,7 @@ type alias Gathered msg =
314387 { node : NodeName
315388 , attributes : List (VirtualDom.Attribute msg)
316389 , styles : List Style
317− , children : List (VirtualDom.Node msg)
390+ , children : NearbyChildren msg
318391 , has : Flag.Field
319392 }
320393
@@ -382,7 +455,10 @@ finalizeNode has node attributes children embedMode parentContext =
382455 Embedded nodeName internal ->
383456 VirtualDom.node nodeName
384457 attributes
385− [ createNode internal [ Html.Attributes.class (classes.any ++ " " ++ classes.single) ]
458+ [ createNode internal
459+ [ Html.Attributes.class
460+ (classes.any ++ " " ++ classes.single)
461+ ]
386462 ]
387463 in
388464 case parentContext of
@@ -459,49 +535,45 @@ finalizeNode has node attributes children embedMode parentContext =
459535
460536
461537embedWith static opts styles children =
538+ let
539+ dynamicStyleSheet =
540+ styles
541+ |> List.foldl reduceStyles ( Set.empty, renderFocusStyle opts.focus )
542+ |> Tuple.second
543+ -- |> reduceStylesRecursive Set.empty [ ]) --renderFocusStyle opts.focus ]
544+ -- |> sortedReduce
545+ |> toStyleSheet opts
546+ in
462547 if static then
463− staticRoot
464− :: (styles
465− |> List.foldl reduceStyles ( Set.empty, [ renderFocusStyle opts.focus ] )
466− |> Tuple.second
467− -- |> reduceStylesRecursive Set.empty [ ]) --renderFocusStyle opts.focus ]
468− -- |> sortedReduce
469− |> toStyleSheet opts
470− )
548+ staticRoot opts
549+ :: dynamicStyleSheet
471550 :: children
472551
473552 else
474− (styles
475− |> List.foldl reduceStyles ( Set.empty, [ renderFocusStyle opts.focus ] )
476− |> Tuple.second
477− -- |> reduceStylesRecursive Set.empty [ ]) --renderFocusStyle opts.focus ]
478− -- |> sortedReduce
479− |> toStyleSheet opts
480− )
553+ dynamicStyleSheet
481554 :: children
482555
483556
484557embedKeyed static opts styles children =
558+ let
559+ dynamicStyleSheet =
560+ styles
561+ |> List.foldl reduceStyles ( Set.empty, renderFocusStyle opts.focus )
562+ |> Tuple.second
563+ -- |> reduceStylesRecursive Set.empty [ ]) --renderFocusStyle opts.focus ]
564+ -- |> sortedReduce
565+ |> toStyleSheet opts
566+ in
485567 if static then
486− ( "static-stylesheet", staticRoot )
568+ ( "static-stylesheet", staticRoot opts )
487569 :: ( "dynamic-stylesheet"
488− , styles
489− |> List.foldl reduceStyles ( Set.empty, [ renderFocusStyle opts.focus ] )
490− |> Tuple.second
491− -- |> reduceStylesRecursive Set.empty [ ]) --renderFocusStyle opts.focus ]
492− -- |> sortedReduce
493− |> toStyleSheet opts
570+ , dynamicStyleSheet
494571 )
495572 :: children
496573
497574 else
498575 ( "dynamic-stylesheet"
499− , styles
500− |> List.foldl reduceStyles ( Set.empty, [ renderFocusStyle opts.focus ] )
501− |> Tuple.second
502− -- |> reduceStylesRecursive Set.empty [ ]) --renderFocusStyle opts.focus ]
503− -- |> sortedReduce
504− |> toStyleSheet opts
576+ , dynamicStyleSheet
505577 )
506578 :: children
507579
@@ -817,7 +889,16 @@ skippable flag style =
817889 False
818890
819891
820−gatherAttrRecursive : String -> NodeName -> Flag.Field -> Transformation -> List Style -> List (VirtualDom.Attribute msg) -> List (VirtualDom.Node msg) -> List (Attribute aligned msg) -> Gathered msg
892+gatherAttrRecursive :
893+ String
894+ -> NodeName
895+ -> Flag.Field
896+ -> Transformation
897+ -> List Style
898+ -> List (VirtualDom.Attribute msg)
899+ -> NearbyChildren msg
900+ -> List (Attribute aligned msg)
901+ -> Gathered msg
821902gatherAttrRecursive classes node has transform styles attrs children elementAttrs =
822903 case elementAttrs of
823904 [] ->
@@ -951,7 +1032,7 @@ gatherAttrRecursive classes node has transform styles attrs children elementAttr
9511032 in
9521033 gatherAttrRecursive (classes ++ " " ++ newClass)
9531034 node
954− (Flag.merge addToFlags has)
1035+ (Flag.merge addToFlags (Flag.add Flag.width has))
9551036 transform
9561037 (newStyles ++ styles)
9571038 attrs
@@ -972,7 +1053,7 @@ gatherAttrRecursive classes node has transform styles attrs children elementAttr
9721053 name =
9731054 "height-px-" ++ val
9741055 in
975− gatherAttrRecursive (name ++ " " ++ classes)
1056+ gatherAttrRecursive (Internal.Style.classes.heightExact ++ " " ++ name ++ " " ++ classes)
9761057 node
9771058 (Flag.add Flag.height has)
9781059 transform
@@ -1029,7 +1110,7 @@ gatherAttrRecursive classes node has transform styles attrs children elementAttr
10291110 in
10301111 gatherAttrRecursive (classes ++ " " ++ newClass)
10311112 node
1032− (Flag.merge addToFlags has)
1113+ (Flag.merge addToFlags (Flag.add Flag.height has))
10331114 transform
10341115 (newStyles ++ styles)
10351116 attrs
@@ -1061,20 +1142,15 @@ gatherAttrRecursive classes node has transform styles attrs children elementAttr
10611142 gatherAttrRecursive classes (addNodeName "h6" node) has transform styles attrs children remaining
10621143
10631144 Paragraph ->
1064− let
1065− newNode =
1066− case node of
1067− Generic ->
1068− NodeName "p"
1069−
1070− NodeName name ->
1071− NodeName name
1072−
1073− Embedded x y ->
1074− Embedded x y
1075− in
1076− gatherAttrRecursive classes
1077− newNode
1145+ -- previously we rendered a <p> tag, though apparently this invalidates the html if it has <div>s inside.
1146+ -- Since we can't guaranteee that there are no divs, we need another strategy.
1147+ -- While it's not documented in many places, there apparently is a paragraph aria role
1148+ -- https://github.com/w3c/aria/blob/11f85f41a5b621fdbe85fc9bcdcd270e653a48ba/common/script/roleInfo.js
1149+ -- Though we'll need to wait till it gets released in an official wai-aria spec to use it.
1150+ -- If it's used at the moment, then Lighthouse complains (likely rightfully) that role paragraph is not recognized.
1151+ gatherAttrRecursive
1152+ classes
1153+ node
10781154 has
10791155 transform
10801156 styles
@@ -1109,75 +1185,16 @@ gatherAttrRecursive classes node has transform styles attrs children elementAttr
11091185
11101186 Styled styled ->
11111187 styles ++ styled.styles
1112−
1113− nearbyElement =
1114− Html.div
1115− [ Html.Attributes.class <|
1116− case location of
1117− Above ->
1118− String.join " "
1119− [ Internal.Style.classes.nearby
1120− , Internal.Style.classes.single
1121− , Internal.Style.classes.above
1122− ]
1123−
1124− Below ->
1125− String.join " "
1126− [ Internal.Style.classes.nearby
1127− , Internal.Style.classes.single
1128− , Internal.Style.classes.below
1129− ]
1130−
1131− OnRight ->
1132− String.join " "
1133− [ Internal.Style.classes.nearby
1134− , Internal.Style.classes.single
1135− , Internal.Style.classes.onRight
1136− ]
1137−
1138− OnLeft ->
1139− String.join " "
1140− [ Internal.Style.classes.nearby
1141− , Internal.Style.classes.single
1142− , Internal.Style.classes.onLeft
1143− ]
1144−
1145− InFront ->
1146− String.join " "
1147− [ Internal.Style.classes.nearby
1148− , Internal.Style.classes.single
1149− , Internal.Style.classes.inFront
1150− ]
1151−
1152− Behind ->
1153− String.join " "
1154− [ Internal.Style.classes.nearby
1155− , Internal.Style.classes.single
1156− , Internal.Style.classes.behind
1157− ]
1158− ]
1159− [ case elem of
1160− Empty ->
1161− VirtualDom.text ""
1162−
1163− Text str ->
1164− textElement str
1165−
1166− Unstyled html ->
1167− html asEl
1168−
1169− Styled styled ->
1170− styled.html NoStyleSheet asEl
1171− ]
1172−
1173− newClasses =
1174− if location == Behind then
1175− Internal.Style.classes.hasBehind ++ " " ++ classes
1176−
1177− else
1178− classes
11791188 in
1180− gatherAttrRecursive newClasses node has transform newStyles attrs (nearbyElement :: children) remaining
1189+ gatherAttrRecursive
1190+ classes
1191+ node
1192+ has
1193+ transform
1194+ newStyles
1195+ attrs
1196+ (addNearbyElement location elem children)
1197+ remaining
11811198
11821199 AlignX x ->
11831200 if Flag.present Flag.xAlign has then
@@ -1233,6 +1250,106 @@ gatherAttrRecursive classes node has transform styles attrs children elementAttr
12331250 remaining
12341251
12351252
1253+addNearbyElement location elem existing =
1254+ let
1255+ nearby =
1256+ nearbyElement location elem
1257+ in
1258+ case existing of
1259+ NoNearbyChildren ->
1260+ case location of
1261+ Behind ->
1262+ ChildrenBehind [ nearby ]
1263+
1264+ _ ->
1265+ ChildrenInFront [ nearby ]
1266+
1267+ ChildrenBehind existingBehind ->
1268+ case location of
1269+ Behind ->
1270+ ChildrenBehind (nearby :: existingBehind)
1271+
1272+ _ ->
1273+ ChildrenBehindAndInFront existingBehind [ nearby ]
1274+
1275+ ChildrenInFront existingInFront ->
1276+ case location of
1277+ Behind ->
1278+ ChildrenBehindAndInFront [ nearby ] existingInFront
1279+
1280+ _ ->
1281+ ChildrenInFront (nearby :: existingInFront)
1282+
1283+ ChildrenBehindAndInFront existingBehind existingInFront ->
1284+ case location of
1285+ Behind ->
1286+ ChildrenBehindAndInFront (nearby :: existingBehind) existingInFront
1287+
1288+ _ ->
1289+ ChildrenBehindAndInFront existingBehind (nearby :: existingInFront)
1290+
1291+
1292+nearbyElement location elem =
1293+ Html.div
1294+ [ Html.Attributes.class <|
1295+ case location of
1296+ Above ->
1297+ String.join " "
1298+ [ Internal.Style.classes.nearby
1299+ , Internal.Style.classes.single
1300+ , Internal.Style.classes.above
1301+ ]
1302+
1303+ Below ->
1304+ String.join " "
1305+ [ Internal.Style.classes.nearby
1306+ , Internal.Style.classes.single
1307+ , Internal.Style.classes.below
1308+ ]
1309+
1310+ OnRight ->
1311+ String.join " "
1312+ [ Internal.Style.classes.nearby
1313+ , Internal.Style.classes.single
1314+ , Internal.Style.classes.onRight
1315+ ]
1316+
1317+ OnLeft ->
1318+ String.join " "
1319+ [ Internal.Style.classes.nearby
1320+ , Internal.Style.classes.single
1321+ , Internal.Style.classes.onLeft
1322+ ]
1323+
1324+ InFront ->
1325+ String.join " "
1326+ [ Internal.Style.classes.nearby
1327+ , Internal.Style.classes.single
1328+ , Internal.Style.classes.inFront
1329+ ]
1330+
1331+ Behind ->
1332+ String.join " "
1333+ [ Internal.Style.classes.nearby
1334+ , Internal.Style.classes.single
1335+ , Internal.Style.classes.behind
1336+ ]
1337+ ]
1338+ [ case elem of
1339+ Empty ->
1340+ VirtualDom.text ""
1341+
1342+ Text str ->
1343+ textElement str
1344+
1345+ Unstyled html ->
1346+ html asEl
1347+
1348+ Styled styled ->
1349+ styled.html NoStyleSheet asEl
1350+ ]
1351+
1352+
12361353renderWidth w =
12371354 case w of
12381355 Px px ->
@@ -1319,7 +1436,7 @@ renderHeight h =
13191436 "height-px-" ++ val
13201437 in
13211438 ( Flag.none
1322− , name
1439+ , Internal.Style.classes.heightExact ++ " " ++ name
13231440 , [ Single name "height" (val ++ "px") ]
13241441 )
13251442
@@ -1342,7 +1459,7 @@ renderHeight h =
13421459 , [ Single
13431460 (Internal.Style.classes.any
13441461 ++ "."
1345− ++ Internal.Style.classes.row
1462+ ++ Internal.Style.classes.column
13461463 ++ " > "
13471464 ++ (Internal.Style.dot <| "height-fill-" ++ String.fromInt portion)
13481465 )
@@ -1361,7 +1478,9 @@ renderHeight h =
13611478 Single
13621479 cls
13631480 "min-height"
1364− (String.fromInt minSize ++ "px")
1481+ -- This needs to be !important because we're using `min-height: min-content`
1482+ -- to correct for safari's incorrect implementation of flexbox.
1483+ (String.fromInt minSize ++ "px !important")
13651484
13661485 ( newFlag, newAttrs, newStyle ) =
13671486 renderHeight len
@@ -1439,7 +1558,7 @@ element : LayoutContext -> NodeName -> List (Attribute aligned msg) -> Children
14391558element context node attributes children =
14401559 attributes
14411560 |> List.reverse
1442− |> gatherAttrRecursive (contextClasses context) node Flag.none untransformed [] [] []
1561+ |> gatherAttrRecursive (contextClasses context) node Flag.none untransformed [] [] NoNearbyChildren
14431562 |> createElement context children
14441563
14451564
@@ -1488,36 +1607,33 @@ createElement context children rendered =
14881607 -- Same if it's a column or row with one child and width-content, height-content
14891608 -- interferes with css grid
14901609 -- Maybe we could unpack text elements in a paragraph as well,
1491− -- however embedded style elements that are larger than the line height will overlap with exisitng text.
1610+ -- however, embedded elements that are larger than the line height will overlap with exisitng text.
14921611 -- I don't think that's what we want.
1493− if
1494− context
1495− == asEl
1496− || context
1497− == asParagraph
1498− then
1499− ( VirtualDom.text
1500− (if context == asParagraph then
1501− str ++ " "
1502−
1503− else
1504− str
1505− )
1506− :: htmls
1507− , existingStyles
1508− )
1509−
1510− else
1511− ( textElement
1512− (if context == asParagraph then
1513− str ++ " "
1514−
1515− else
1516− str
1517− )
1518− :: htmls
1519− , existingStyles
1520− )
1612+ -- if
1613+ -- context
1614+ -- == asEl
1615+ -- || context
1616+ -- == asParagraph
1617+ -- then
1618+ -- ( VirtualDom.text
1619+ -- (if context == asParagraph then
1620+ -- str
1621+ -- else
1622+ -- str
1623+ -- )
1624+ -- :: htmls
1625+ -- , existingStyles
1626+ -- )
1627+ -- else
1628+ ( (if context == asEl then
1629+ textElementFill str
1630+
1631+ else
1632+ textElement str
1633+ )
1634+ :: htmls
1635+ , existingStyles
1636+ )
15211637
15221638 Empty ->
15231639 ( htmls, existingStyles )
@@ -1559,38 +1675,30 @@ createElement context children rendered =
15591675 -- TEXT OPTIMIZATION
15601676 -- You can have raw text if the element is an el, and has `width-content` and `height-content`
15611677 -- Same if it's a column or row with one child and width-content, height-content
1562− if
1563− context
1564− == asEl
1565− || context
1566− == asParagraph
1567− then
1568− ( ( key
1569− , VirtualDom.text
1570− (if context == asParagraph then
1571− str ++ " "
1572−
1573− else
1574− str
1575− )
1576− )
1577− :: htmls
1578− , existingStyles
1579− )
1678+ -- if
1679+ -- context
1680+ -- == asEl
1681+ -- || context
1682+ -- == asParagraph
1683+ -- then
1684+ -- ( ( key
1685+ -- , VirtualDom.text
1686+ -- str
1687+ -- )
1688+ -- :: htmls
1689+ -- , existingStyles
1690+ -- )
1691+ -- else
1692+ ( ( key
1693+ , if context == asEl then
1694+ textElementFill str
15801695
1581− else
1582− ( ( key
1583− , textElement
1584− (if context == asParagraph then
1585− str ++ " "
1586−
1587− else
1588− str
1589− )
1590− )
1591− :: htmls
1592− , existingStyles
1593− )
1696+ else
1697+ textElement str
1698+ )
1699+ :: htmls
1700+ , existingStyles
1701+ )
15941702
15951703 Empty ->
15961704 ( htmls, existingStyles )
@@ -1613,13 +1721,8 @@ createElement context children rendered =
16131721 (finalizeNode rendered.has
16141722 rendered.node
16151723 rendered.attributes
1616− (Keyed <|
1617− keyed
1618− ++ List.map
1619− (\x ->
1620− ( "nearby-elements-pls", x )
1621− )
1622− rendered.children
1724+ (Keyed
1725+ (addKeyedChildren "nearby-element-pls" keyed rendered.children)
16231726 )
16241727 NoStyleSheet
16251728 )
@@ -1633,13 +1736,7 @@ createElement context children rendered =
16331736 rendered.node
16341737 rendered.attributes
16351738 (Keyed
1636− (keyed
1637− ++ List.map
1638− (\x ->
1639− ( "nearby-elements-pls", x )
1640− )
1641− rendered.children
1642− )
1739+ (addKeyedChildren "nearby-element-pls" keyed rendered.children)
16431740 )
16441741 }
16451742
@@ -1661,7 +1758,7 @@ createElement context children rendered =
16611758 rendered.has
16621759 rendered.node
16631760 rendered.attributes
1664− (Unkeyed <| unkeyed ++ rendered.children)
1761+ (Unkeyed (addChildren unkeyed rendered.children))
16651762 NoStyleSheet
16661763 )
16671764
@@ -1673,10 +1770,42 @@ createElement context children rendered =
16731770 rendered.has
16741771 rendered.node
16751772 rendered.attributes
1676− (Unkeyed (unkeyed ++ rendered.children))
1773+ (Unkeyed (addChildren unkeyed rendered.children))
16771774 }
16781775
16791776
1777+addChildren existing nearbyChildren =
1778+ case nearbyChildren of
1779+ NoNearbyChildren ->
1780+ existing
1781+
1782+ ChildrenBehind behind ->
1783+ behind ++ existing
1784+
1785+ ChildrenInFront inFront ->
1786+ existing ++ inFront
1787+
1788+ ChildrenBehindAndInFront behind inFront ->
1789+ behind ++ existing ++ inFront
1790+
1791+
1792+addKeyedChildren key existing nearbyChildren =
1793+ case nearbyChildren of
1794+ NoNearbyChildren ->
1795+ existing
1796+
1797+ ChildrenBehind behind ->
1798+ List.map (\x -> ( key, x )) behind ++ existing
1799+
1800+ ChildrenInFront inFront ->
1801+ existing ++ List.map (\x -> ( key, x )) inFront
1802+
1803+ ChildrenBehindAndInFront behind inFront ->
1804+ List.map (\x -> ( key, x )) behind
1805+ ++ existing
1806+ ++ List.map (\x -> ( key, x )) inFront
1807+
1808+
16801809unit =
16811810 0
16821811
@@ -1688,8 +1817,20 @@ defaultOptions =
16881817 }
16891818
16901819
1691−staticRoot =
1692− VirtualDom.node "style" [] [ VirtualDom.text Internal.Style.rules ]
1820+staticRoot : OptionRecord -> VirtualDom.Node msg
1821+staticRoot opts =
1822+ case opts.mode of
1823+ Layout ->
1824+ -- wrap the style node in a div to prevent `Dark Reader` from blowin up the dom.
1825+ VirtualDom.node "div"
1826+ []
1827+ [ VirtualDom.node "style" [] [ VirtualDom.text Internal.Style.rules ] ]
1828+
1829+ NoStaticStyleSheet ->
1830+ VirtualDom.text ""
1831+
1832+ WithVirtualCss ->
1833+ VirtualDom.node "elm-ui-static-rules" [ VirtualDom.property "rules" (Encode.string Internal.Style.rules) ] []
16931834
16941835
16951836addWhen ifThis x to =
@@ -1807,7 +1948,7 @@ type Spacing
18071948
18081949
18091950type Padding
1810− = Padding String Int Int Int Int
1951+ = Padding String Float Float Float Float
18111952
18121953
18131954extractSpacingAndPadding : List (Attribute aligned msg) -> ( Maybe Padding, Maybe Spacing )
@@ -1903,35 +2044,44 @@ getHeight attrs =
19032044 Nothing
19042045
19052046
2047+textElementClasses : String
2048+textElementClasses =
2049+ classes.any
2050+ ++ " "
2051+ ++ classes.text
2052+ ++ " "
2053+ ++ classes.widthContent
2054+ ++ " "
2055+ ++ classes.heightContent
2056+
2057+
19062058textElement : String -> VirtualDom.Node msg
19072059textElement str =
19082060 Html.div
19092061 [ Html.Attributes.class
1910− (String.join " "
1911− [ classes.any
1912− , classes.text
1913− , classes.widthContent
1914− , classes.heightContent
1915− ]
1916− )
2062+ textElementClasses
19172063 ]
19182064 [ Html.text str ]
19192065
19202066
2067+textElementFillClasses : String
2068+textElementFillClasses =
2069+ classes.any
2070+ ++ " "
2071+ ++ classes.text
2072+ ++ " "
2073+ ++ classes.widthFill
2074+ ++ " "
2075+ ++ classes.heightFill
2076+
2077+
19212078textElementFill : String -> VirtualDom.Node msg
19222079textElementFill str =
1923− VirtualDom.node "div"
1924− [ VirtualDom.property "className"
1925− (Json.string <|
1926− String.join " "
1927− [ classes.any
1928− , classes.text
1929− , classes.widthFill
1930− , classes.heightFill
1931− ]
1932− )
2080+ Html.div
2081+ [ Html.Attributes.class
2082+ textElementFillClasses
19332083 ]
1934− [ VirtualDom.text str ]
2084+ [ Html.text str ]
19352085
19362086
19372087type Children x
@@ -1939,10 +2089,6 @@ type Children x
19392089 | Keyed (List ( String, x ))
19402090
19412091
1942−
1943−-- toHtml : OptionRecord -> Element msg -> VirtualDom.Node msg
1944−
1945−
19462092toHtml mode el =
19472093 case el of
19482094 Unstyled html ->
@@ -1978,8 +2124,7 @@ renderRoot optionList attributes child =
19782124
19792125
19802126type RenderMode
1981− = Viewport
1982− | Layout
2127+ = Layout
19832128 | NoStaticStyleSheet
19842129 | WithVirtualCss
19852130
@@ -2028,8 +2173,8 @@ rootStyle =
20282173 , SansSerif
20292174 ]
20302175 in
2031− [ StyleClass Flag.bgColor (Colored ("bg-color-" ++ formatColorClass (Rgba 1 1 1 0)) "background-color" (Rgba 1 1 1 0))
2032− , StyleClass Flag.fontColor (Colored ("font-color-" ++ formatColorClass (Rgba 0 0 0 1)) "color" (Rgba 0 0 0 1))
2176+ [ StyleClass Flag.bgColor (Colored ("bg-" ++ formatColorClass (Rgba 1 1 1 0)) "background-color" (Rgba 1 1 1 0))
2177+ , StyleClass Flag.fontColor (Colored ("fc-" ++ formatColorClass (Rgba 0 0 0 1)) "color" (Rgba 0 0 0 1))
20332178 , StyleClass Flag.fontSize (FontSize 20)
20342179 , StyleClass Flag.fontFamily <|
20352180 FontFamily (List.foldl renderFontClassName "font-" families)
@@ -2061,14 +2206,49 @@ renderFontClassName font current =
20612206 |> String.toLower
20622207 |> String.words
20632208 |> String.join "-"
2209+
2210+ FontWith { name } ->
2211+ name
2212+ |> String.toLower
2213+ |> String.words
2214+ |> String.join "-"
20642215 )
20652216
20662217
20672218renderFocusStyle :
20682219 FocusStyle
2069− -> Style
2220+ -> List Style
20702221renderFocusStyle focus =
2071− Style (Internal.Style.dot classes.any ++ ":focus .focusable, " ++ Internal.Style.dot classes.any ++ ".focusable:focus")
2222+ [ Style (Internal.Style.dot classes.focusedWithin ++ ":focus-within")
2223+ (List.filterMap identity
2224+ [ Maybe.map (\color -> Property "border-color" (formatColor color)) focus.borderColor
2225+ , Maybe.map (\color -> Property "background-color" (formatColor color)) focus.backgroundColor
2226+ , Maybe.map
2227+ (\shadow ->
2228+ Property "box-shadow"
2229+ (formatBoxShadow
2230+ { color = shadow.color
2231+ , offset =
2232+ shadow.offset
2233+ |> Tuple.mapFirst toFloat
2234+ |> Tuple.mapSecond toFloat
2235+ , inset = False
2236+ , blur =
2237+ toFloat shadow.blur
2238+ , size =
2239+ toFloat shadow.size
2240+ }
2241+ )
2242+ )
2243+ focus.shadow
2244+ , Just <| Property "outline" "none"
2245+ ]
2246+ )
2247+ , Style
2248+ ((Internal.Style.dot classes.any ++ ":focus .focusable, ")
2249+ ++ (Internal.Style.dot classes.any ++ ".focusable:focus, ")
2250+ ++ (".ui-slide-bar:focus + " ++ Internal.Style.dot classes.any ++ " .focusable-thumb")
2251+ )
20722252 (List.filterMap identity
20732253 [ Maybe.map (\color -> Property "border-color" (formatColor color)) focus.borderColor
20742254 , Maybe.map (\color -> Property "background-color" (formatColor color)) focus.backgroundColor
@@ -2091,6 +2271,7 @@ renderFocusStyle focus =
20912271 , Just <| Property "outline" "none"
20922272 ]
20932273 )
2274+ ]
20942275
20952276
20962277focusDefaultStyle : { backgroundColor : Maybe Color, borderColor : Maybe Color, shadow : Maybe Shadow }
@@ -2102,7 +2283,7 @@ focusDefaultStyle =
21022283 { color =
21032284 Rgba (155 / 255) (203 / 255) 1 1
21042285 , offset = ( 0, 0 )
2105− , blur = 3
2286+ , blur = 0
21062287 , size = 3
21072288 }
21082289 }
@@ -2170,519 +2351,734 @@ optionsToRecord options =
21702351 options
21712352
21722353
2173−renderFont : List Font -> String
2174−renderFont families =
2354+toStyleSheet : OptionRecord -> List Style -> VirtualDom.Node msg
2355+toStyleSheet options styleSheet =
2356+ case options.mode of
2357+ Layout ->
2358+ -- wrap the style node in a div to prevent `Dark Reader` from blowin up the dom.
2359+ VirtualDom.node "div"
2360+ []
2361+ [ VirtualDom.node "style"
2362+ []
2363+ [ VirtualDom.text (toStyleSheetString options styleSheet) ]
2364+ ]
2365+
2366+ NoStaticStyleSheet ->
2367+ -- wrap the style node in a div to prevent `Dark Reader` from blowin up the dom.
2368+ VirtualDom.node "div"
2369+ []
2370+ [ VirtualDom.node "style"
2371+ []
2372+ [ VirtualDom.text (toStyleSheetString options styleSheet) ]
2373+ ]
2374+
2375+ WithVirtualCss ->
2376+ VirtualDom.node "elm-ui-rules"
2377+ [ VirtualDom.property "rules"
2378+ (encodeStyles options styleSheet)
2379+ ]
2380+ []
2381+
2382+
2383+renderTopLevelValues rules =
21752384 let
2176− fontName font =
2385+ withImport font =
21772386 case font of
2178− Serif ->
2179− "serif"
2387+ ImportFont _ url ->
2388+ Just ("@import url('" ++ url ++ "');")
2389+
2390+ -- FontWith with ->
2391+ -- case with.url of
2392+ -- Just x ->
2393+ -- Just ("@import url('" ++ x ++ "');")
2394+ -- Nothing ->
2395+ -- Nothing
2396+ _ ->
2397+ Nothing
21802398
2181− SansSerif ->
2182− "sans-serif"
2399+ allNames =
2400+ List.map Tuple.first rules
21832401
2184− Monospace ->
2185− "monospace"
2402+ fontImports ( name, typefaces ) =
2403+ let
2404+ imports =
2405+ String.join "\n" (List.filterMap withImport typefaces)
2406+ in
2407+ imports
21862408
2187− Typeface name ->
2188− "\"" ++ name ++ "\""
2409+ fontAdjustments ( name, typefaces ) =
2410+ case typefaceAdjustment typefaces of
2411+ Nothing ->
2412+ String.join ""
2413+ (List.map (renderNullAdjustmentRule name) allNames)
21892414
2190− ImportFont name url ->
2191− "\"" ++ name ++ "\""
2415+ Just adjustment ->
2416+ String.join ""
2417+ (List.map (renderFontAdjustmentRule name adjustment) allNames)
21922418 in
2193− families
2194− |> List.map fontName
2195− |> String.join ", "
2419+ String.join "\n" (List.map fontImports rules)
2420+ ++ String.join "\n" (List.map fontAdjustments rules)
21962421
21972422
2198−toStyleSheet : OptionRecord -> List Style -> VirtualDom.Node msg
2199−toStyleSheet options styleSheet =
2200− VirtualDom.node "style" [] [ VirtualDom.text (toStyleSheetString options styleSheet) ]
2423+renderNullAdjustmentRule fontToAdjust otherFontName =
2424+ let
2425+ name =
2426+ if fontToAdjust == otherFontName then
2427+ fontToAdjust
22012428
2429+ else
2430+ otherFontName ++ " ." ++ fontToAdjust
2431+ in
2432+ String.join " "
2433+ [ bracket
2434+ ("."
2435+ ++ name
2436+ ++ "."
2437+ ++ classes.sizeByCapital
2438+ ++ ", "
2439+ ++ "."
2440+ ++ name
2441+ ++ " ."
2442+ ++ classes.sizeByCapital
2443+ )
2444+ [ ( "line-height", "1" )
2445+ ]
2446+ , bracket
2447+ ("."
2448+ ++ name
2449+ ++ "."
2450+ ++ classes.sizeByCapital
2451+ ++ "> ."
2452+ ++ Internal.Style.classes.text
2453+ ++ ", ."
2454+ ++ name
2455+ ++ " ."
2456+ ++ classes.sizeByCapital
2457+ ++ " > ."
2458+ ++ Internal.Style.classes.text
2459+ )
2460+ [ ( "vertical-align", "0" )
2461+ , ( "line-height", "1" )
2462+ ]
2463+ ]
22022464
2203−toStyleSheetString : OptionRecord -> List Style -> String
2204−toStyleSheetString options stylesheet =
2205− let
2206− renderTopLevels rule =
2207− case rule of
2208− FontFamily name typefaces ->
2209− let
2210− getImports font =
2211− case font of
2212− ImportFont _ url ->
2213− Just ("@import url('" ++ url ++ "');")
22142465
2215− _ ->
2216− Nothing
2217− in
2218− typefaces
2219− |> List.filterMap getImports
2220− |> String.join "\n"
2221− |> Just
2466+fontRule name modifier ( parentAdj, textAdjustment ) =
2467+ [ bracket
2468+ ("."
2469+ ++ name
2470+ ++ "."
2471+ ++ modifier
2472+ ++ ", "
2473+ ++ "."
2474+ ++ name
2475+ ++ " ."
2476+ ++ modifier
2477+ )
2478+ parentAdj
2479+ , bracket
2480+ ("."
2481+ ++ name
2482+ ++ "."
2483+ ++ modifier
2484+ ++ "> ."
2485+ ++ Internal.Style.classes.text
2486+ ++ ", ."
2487+ ++ name
2488+ ++ " ."
2489+ ++ modifier
2490+ ++ " > ."
2491+ ++ Internal.Style.classes.text
2492+ )
2493+ textAdjustment
2494+ ]
22222495
2223− _ ->
2224− Nothing
22252496
2226− renderProps force (Property key val) existing =
2227− if force then
2228− existing ++ "\n " ++ key ++ ": " ++ val ++ " !important;"
2497+renderFontAdjustmentRule fontToAdjust ( full, capital ) otherFontName =
2498+ let
2499+ name =
2500+ if fontToAdjust == otherFontName then
2501+ fontToAdjust
22292502
22302503 else
2231− existing ++ "\n " ++ key ++ ": " ++ val ++ ";"
2504+ otherFontName ++ " ." ++ fontToAdjust
2505+ in
2506+ String.join " "
2507+ (fontRule name classes.sizeByCapital capital ++ fontRule name classes.fullSize full)
2508+
2509+
2510+bracket selector rules =
2511+ let
2512+ renderPair ( name, val ) =
2513+ name ++ ": " ++ val ++ ";"
2514+ in
2515+ selector ++ " {" ++ String.join "" (List.map renderPair rules) ++ "}"
2516+
22322517
2233− renderStyle maybePseudo selector props =
2234− case maybePseudo of
2518+fontAdjustmentRules converted =
2519+ ( [ ( "display", "block" )
2520+ ]
2521+ , [ ( "display", "inline-block" )
2522+ , ( "line-height", String.fromFloat converted.height )
2523+ , ( "vertical-align", String.fromFloat converted.vertical ++ "em" )
2524+ , ( "font-size", String.fromFloat converted.size ++ "em" )
2525+ ]
2526+ )
2527+
2528+
2529+typefaceAdjustment typefaces =
2530+ List.foldl
2531+ (\face found ->
2532+ case found of
22352533 Nothing ->
2236− selector ++ "{" ++ List.foldl (renderProps False) "" props ++ "\n}"
2534+ case face of
2535+ FontWith with ->
2536+ case with.adjustment of
2537+ Nothing ->
2538+ found
2539+
2540+ Just adjustment ->
2541+ Just
2542+ ( fontAdjustmentRules
2543+ (.full (convertAdjustment adjustment))
2544+ , fontAdjustmentRules
2545+ (.capital (convertAdjustment adjustment))
2546+ )
22372547
2238− Just pseudo ->
2239− case pseudo of
2240− Hover ->
2241− case options.hover of
2242− NoHover ->
2243− ""
2548+ _ ->
2549+ found
22442550
2245− ForceHover ->
2246− selector ++ "-hv {" ++ List.foldl (renderProps True) "" props ++ "\n}"
2551+ Just _ ->
2552+ found
2553+ )
2554+ Nothing
2555+ typefaces
22472556
2248− AllowHover ->
2249− selector ++ "-hv:hover {" ++ List.foldl (renderProps False) "" props ++ "\n}"
22502557
2251− Focus ->
2252− let
2253− renderedProps =
2254− List.foldl (renderProps False) "" props
2255− in
2256− String.join "\n"
2257− [ selector
2258− ++ "-fs:focus {"
2259− ++ renderedProps
2260− ++ "\n}"
2261− , "."
2262− ++ classes.any
2263− ++ ":focus ~ "
2264− ++ selector
2265− ++ "-fs:not(.focus) {"
2266− ++ renderedProps
2267− ++ "\n}"
2268− , "."
2269− ++ classes.any
2270− ++ ":focus "
2271− ++ selector
2272− ++ "-fs {"
2273− ++ renderedProps
2274− ++ "\n}"
2275− , ".focusable-parent:focus ~ "
2276− ++ "."
2277− ++ classes.any
2278− ++ " "
2279− ++ selector
2280− ++ "-fs {"
2281− ++ renderedProps
2282− ++ "\n}"
2283− ]
2558+fontName font =
2559+ case font of
2560+ Serif ->
2561+ "serif"
22842562
2285− Active ->
2286− selector ++ "-act:active {" ++ List.foldl (renderProps False) "" props ++ "\n}"
2563+ SansSerif ->
2564+ "sans-serif"
22872565
2288− renderStyleRule rule maybePseudo =
2289− case rule of
2290− Style selector props ->
2291− renderStyle maybePseudo selector props
2566+ Monospace ->
2567+ "monospace"
22922568
2293− Shadows name prop ->
2294− renderStyle
2295− maybePseudo
2296− ("." ++ name)
2297− [ Property "box-shadow" prop
2298− ]
2569+ Typeface name ->
2570+ "\"" ++ name ++ "\""
2571+
2572+ ImportFont name url ->
2573+ "\"" ++ name ++ "\""
2574+
2575+ FontWith { name } ->
2576+ "\"" ++ name ++ "\""
2577+
2578+
2579+topLevelValue rule =
2580+ case rule of
2581+ FontFamily name typefaces ->
2582+ Just ( name, typefaces )
2583+
2584+ _ ->
2585+ Nothing
2586+
2587+
2588+renderProps force (Property key val) existing =
2589+ if force then
2590+ existing ++ "\n " ++ key ++ ": " ++ val ++ " !important;"
2591+
2592+ else
2593+ existing ++ "\n " ++ key ++ ": " ++ val ++ ";"
2594+
2595+
2596+encodeStyles options stylesheet =
2597+ stylesheet
2598+ |> List.map
2599+ (\style ->
2600+ let
2601+ styled =
2602+ renderStyleRule options style Nothing
2603+ in
2604+ ( getStyleName style, Encode.list Encode.string styled )
2605+ )
2606+ |> Encode.object
2607+
2608+
2609+toStyleSheetString : OptionRecord -> List Style -> String
2610+toStyleSheetString options stylesheet =
2611+ let
2612+ combine style rendered =
2613+ { rules = rendered.rules ++ renderStyleRule options style Nothing
2614+ , topLevel =
2615+ case topLevelValue style of
2616+ Nothing ->
2617+ rendered.topLevel
2618+
2619+ Just topLevel ->
2620+ topLevel :: rendered.topLevel
2621+ }
2622+ in
2623+ case List.foldl combine { topLevel = [], rules = [] } stylesheet of
2624+ { topLevel, rules } ->
2625+ renderTopLevelValues topLevel ++ String.concat rules
2626+
2627+
2628+renderStyle : OptionRecord -> Maybe PseudoClass -> String -> List Property -> List String
2629+renderStyle options maybePseudo selector props =
2630+ case maybePseudo of
2631+ Nothing ->
2632+ [ selector ++ "{" ++ List.foldl (renderProps False) "" props ++ "\n}" ]
2633+
2634+ Just pseudo ->
2635+ case pseudo of
2636+ Hover ->
2637+ case options.hover of
2638+ NoHover ->
2639+ []
22992640
2300− Transparency name transparency ->
2641+ ForceHover ->
2642+ [ selector ++ "-hv {" ++ List.foldl (renderProps True) "" props ++ "\n}" ]
2643+
2644+ AllowHover ->
2645+ [ selector ++ "-hv:hover {" ++ List.foldl (renderProps False) "" props ++ "\n}" ]
2646+
2647+ Focus ->
23012648 let
2302− opacity =
2303− (1 - transparency)
2304− |> min 1
2305− |> max 0
2649+ renderedProps =
2650+ List.foldl (renderProps False) "" props
23062651 in
2307− renderStyle
2308− maybePseudo
2309− ("." ++ name)
2310− [ Property "opacity" (String.fromFloat opacity)
2311− ]
2652+ [ selector ++ "-fs:focus {" ++ renderedProps ++ "\n}"
2653+ , ("." ++ classes.any ++ ":focus " ++ selector ++ "-fs {")
2654+ ++ renderedProps
2655+ ++ "\n}"
2656+ , (selector ++ "-fs:focus-within {")
2657+ ++ renderedProps
2658+ ++ "\n}"
2659+ , (".ui-slide-bar:focus + " ++ Internal.Style.dot classes.any ++ " .focusable-thumb" ++ selector ++ "-fs {")
2660+ ++ renderedProps
2661+ ++ "\n}"
2662+ ]
23122663
2313− FontSize i ->
2314− renderStyle
2315− maybePseudo
2316− (".font-size-" ++ String.fromInt i)
2317− [ Property "font-size" (String.fromInt i ++ "px")
2318− ]
2664+ Active ->
2665+ [ selector ++ "-act:active {" ++ List.foldl (renderProps False) "" props ++ "\n}" ]
23192666
2320− FontFamily name typefaces ->
2321− renderStyle
2322− maybePseudo
2323− ("." ++ name)
2324− [ Property "font-family" (renderFont typefaces)
2325− ]
23262667
2327− Single class prop val ->
2328− renderStyle
2329− maybePseudo
2330− ("." ++ class)
2331− [ Property prop val
2332− ]
2668+renderStyleRule : OptionRecord -> Style -> Maybe PseudoClass -> List String
2669+renderStyleRule options rule maybePseudo =
2670+ case rule of
2671+ Style selector props ->
2672+ renderStyle options maybePseudo selector props
23332673
2334− Colored class prop color ->
2335− renderStyle
2336− maybePseudo
2337− ("." ++ class)
2338− [ Property prop (formatColor color)
2339− ]
2674+ Shadows name prop ->
2675+ renderStyle options
2676+ maybePseudo
2677+ ("." ++ name)
2678+ [ Property "box-shadow" prop
2679+ ]
23402680
2341− SpacingStyle cls x y ->
2342− let
2343− class =
2344− "." ++ cls
2681+ Transparency name transparency ->
2682+ let
2683+ opacity =
2684+ (1 - transparency)
2685+ |> min 1
2686+ |> max 0
2687+ in
2688+ renderStyle options
2689+ maybePseudo
2690+ ("." ++ name)
2691+ [ Property "opacity" (String.fromFloat opacity)
2692+ ]
23452693
2346− xPx =
2347− String.fromInt x ++ "px"
2694+ FontSize i ->
2695+ renderStyle options
2696+ maybePseudo
2697+ (".font-size-" ++ String.fromInt i)
2698+ [ Property "font-size" (String.fromInt i ++ "px")
2699+ ]
23482700
2349− yPx =
2350− String.fromInt y ++ "px"
2701+ FontFamily name typefaces ->
2702+ let
2703+ features =
2704+ typefaces
2705+ |> List.filterMap renderVariants
2706+ |> String.join ", "
2707+
2708+ families =
2709+ [ Property "font-family"
2710+ (typefaces
2711+ |> List.map fontName
2712+ |> String.join ", "
2713+ )
2714+ , Property "font-feature-settings" features
2715+ , Property "font-variant"
2716+ (if List.any hasSmallCaps typefaces then
2717+ "small-caps"
23512718
2352− row =
2353− "." ++ Internal.Style.classes.row
2719+ else
2720+ "normal"
2721+ )
2722+ ]
2723+ in
2724+ renderStyle options
2725+ maybePseudo
2726+ ("." ++ name)
2727+ families
23542728
2355− wrappedRow =
2356− "." ++ Internal.Style.classes.wrapped ++ row
2729+ Single class prop val ->
2730+ renderStyle options
2731+ maybePseudo
2732+ ("." ++ class)
2733+ [ Property prop val
2734+ ]
23572735
2358− column =
2359− "." ++ Internal.Style.classes.column
2736+ Colored class prop color ->
2737+ renderStyle options
2738+ maybePseudo
2739+ ("." ++ class)
2740+ [ Property prop (formatColor color)
2741+ ]
23602742
2361− page =
2362− "." ++ Internal.Style.classes.page
2743+ SpacingStyle cls x y ->
2744+ let
2745+ class =
2746+ "." ++ cls
23632747
2364− paragraph =
2365− "." ++ Internal.Style.classes.paragraph
2748+ halfX =
2749+ String.fromFloat (toFloat x / 2) ++ "px"
23662750
2367− left =
2368− "." ++ Internal.Style.classes.alignLeft
2751+ halfY =
2752+ String.fromFloat (toFloat y / 2) ++ "px"
23692753
2370− right =
2371− "." ++ Internal.Style.classes.alignRight
2754+ xPx =
2755+ String.fromInt x ++ "px"
23722756
2373− any =
2374− "." ++ Internal.Style.classes.any
2757+ yPx =
2758+ String.fromInt y ++ "px"
23752759
2376− single =
2377− "." ++ Internal.Style.classes.single
2378− in
2379− String.concat
2380− [ renderStyle maybePseudo (class ++ row ++ " > " ++ any) [ Property "margin-right" xPx ]
2760+ row =
2761+ "." ++ Internal.Style.classes.row
23812762
2382− -- margins don't apply to last element of normal, unwrapped rows
2383− , renderStyle maybePseudo (class ++ row ++ " > " ++ any ++ ":last-child") [ Property "margin" "0" ]
2763+ wrappedRow =
2764+ "." ++ Internal.Style.classes.wrapped ++ row
23842765
2385− -- For wrapped rows, margins always apply because we handle "canceling out" the other margins manually in the element.
2386− , renderStyle maybePseudo
2387− (class ++ wrappedRow ++ " > " ++ any)
2388− [ Property "margin" ("0 " ++ xPx ++ " " ++ yPx ++ " 0")
2389− ]
2390− , renderStyle maybePseudo
2391− (class ++ wrappedRow ++ " > " ++ any ++ ":last-child")
2392− [ Property "margin-right" "0"
2393− ]
2766+ column =
2767+ "." ++ Internal.Style.classes.column
23942768
2395− -- columns
2396− , renderStyle maybePseudo (class ++ column ++ " > " ++ any ++ " + " ++ any) [ Property "margin-top" yPx ]
2397− , renderStyle maybePseudo (class ++ page ++ " > " ++ any ++ " + " ++ any) [ Property "margin-top" yPx ]
2398− , renderStyle maybePseudo (class ++ page ++ " > " ++ left) [ Property "margin-right" xPx ]
2399− , renderStyle maybePseudo (class ++ page ++ " > " ++ right) [ Property "margin-left" xPx ]
2400− , renderStyle
2401− maybePseudo
2402− (class ++ paragraph)
2403− [ Property "line-height" ("calc(1em + " ++ String.fromInt y ++ "px)")
2404− ]
2405− , renderStyle
2406− maybePseudo
2407− ("textarea" ++ class)
2408− [ Property "line-height" ("calc(1em + " ++ String.fromInt y ++ "px)")
2409− ]
2769+ page =
2770+ "." ++ Internal.Style.classes.page
24102771
2411− -- , renderStyle
2412− -- maybePseudo
2413− -- (class ++ paragraph ++ " > " ++ any)
2414− -- [ Property "margin-right" xPx
2415− -- , Property "margin-bottom" yPx
2416− -- ]
2417− , renderStyle
2418− maybePseudo
2419− (class ++ paragraph ++ " > " ++ left)
2420− [ Property "margin-right" xPx
2421− ]
2422− , renderStyle
2423− maybePseudo
2424− (class ++ paragraph ++ " > " ++ right)
2425− [ Property "margin-left" xPx
2426− ]
2427− , renderStyle
2428− maybePseudo
2429− (class ++ paragraph ++ "::after")
2430− [ Property "content" "''"
2431− , Property "display" "block"
2432− , Property "height" "0"
2433− , Property "width" "0"
2434− , Property "margin-top" (String.fromInt (-1 * (y // 2)) ++ "px")
2435− ]
2436− , renderStyle
2437− maybePseudo
2438− (class ++ paragraph ++ "::before")
2439− [ Property "content" "''"
2440− , Property "display" "block"
2441− , Property "height" "0"
2442− , Property "width" "0"
2443− , Property "margin-bottom" (String.fromInt (-1 * (y // 2)) ++ "px")
2444− ]
2445− ]
2772+ paragraph =
2773+ "." ++ Internal.Style.classes.paragraph
24462774
2447− PaddingStyle cls top right bottom left ->
2448− let
2449− class =
2450− "."
2451− ++ cls
2452− in
2453− renderStyle
2454− maybePseudo
2455− class
2456− [ Property "padding"
2457− (String.fromInt top
2458− ++ "px "
2459− ++ String.fromInt right
2460− ++ "px "
2461− ++ String.fromInt bottom
2462− ++ "px "
2463− ++ String.fromInt left
2464− ++ "px"
2465− )
2466− ]
2775+ left =
2776+ "." ++ Internal.Style.classes.alignLeft
24672777
2468− BorderWidth cls top right bottom left ->
2469− let
2470− class =
2471− "."
2472− ++ cls
2473− in
2474− renderStyle
2475− maybePseudo
2476− class
2477− [ Property "border-width"
2478− (String.fromInt top
2479− ++ "px "
2480− ++ String.fromInt right
2481− ++ "px "
2482− ++ String.fromInt bottom
2483− ++ "px "
2484− ++ String.fromInt left
2485− ++ "px"
2486− )
2487− ]
2778+ right =
2779+ "." ++ Internal.Style.classes.alignRight
24882780
2489− GridTemplateStyle template ->
2490− let
2491− class =
2492− ".grid-rows-"
2493− ++ String.join "-" (List.map lengthClassName template.rows)
2494− ++ "-cols-"
2495− ++ String.join "-" (List.map lengthClassName template.columns)
2496− ++ "-space-x-"
2497− ++ lengthClassName (Tuple.first template.spacing)
2498− ++ "-space-y-"
2499− ++ lengthClassName (Tuple.second template.spacing)
2500−
2501− ySpacing =
2502− toGridLength (Tuple.second template.spacing)
2503−
2504− xSpacing =
2505− toGridLength (Tuple.first template.spacing)
2506−
2507− toGridLength x =
2508− toGridLengthHelper Nothing Nothing x
2509−
2510− toGridLengthHelper minimum maximum x =
2511− case x of
2512− Px px ->
2513− String.fromInt px ++ "px"
2514−
2515− Content ->
2516− case ( minimum, maximum ) of
2517− ( Nothing, Nothing ) ->
2518− "max-content"
2519−
2520− ( Just minSize, Nothing ) ->
2521− "minmax(" ++ String.fromInt minSize ++ "px, " ++ "max-content)"
2522−
2523− ( Nothing, Just maxSize ) ->
2524− "minmax(max-content, " ++ String.fromInt maxSize ++ "px)"
2525−
2526− ( Just minSize, Just maxSize ) ->
2527− "minmax(" ++ String.fromInt minSize ++ "px, " ++ String.fromInt maxSize ++ "px)"
2528−
2529− Fill i ->
2530− case ( minimum, maximum ) of
2531− ( Nothing, Nothing ) ->
2532− String.fromInt i ++ "fr"
2533−
2534− ( Just minSize, Nothing ) ->
2535− "minmax(" ++ String.fromInt minSize ++ "px, " ++ String.fromInt i ++ "fr" ++ "fr)"
2536−
2537− ( Nothing, Just maxSize ) ->
2538− "minmax(max-content, " ++ String.fromInt maxSize ++ "px)"
2539−
2540− ( Just minSize, Just maxSize ) ->
2541− "minmax(" ++ String.fromInt minSize ++ "px, " ++ String.fromInt maxSize ++ "px)"
2542−
2543− Min m len ->
2544− toGridLengthHelper (Just m) maximum len
2545−
2546− Max m len ->
2547− toGridLengthHelper minimum (Just m) len
2548−
2549− msColumns =
2550− template.columns
2551− |> List.map toGridLength
2552− |> String.join ySpacing
2553− |> (\x -> "-ms-grid-columns: " ++ x ++ ";")
2554−
2555− msRows =
2556− template.columns
2557− |> List.map toGridLength
2558− |> String.join ySpacing
2559− |> (\x -> "-ms-grid-rows: " ++ x ++ ";")
2560−
2561− base =
2562− class ++ "{" ++ msColumns ++ msRows ++ "}"
2563−
2564− columns =
2565− template.columns
2566− |> List.map toGridLength
2567− |> String.join " "
2568− |> (\x -> "grid-template-columns: " ++ x ++ ";")
2569−
2570− rows =
2571− template.rows
2572− |> List.map toGridLength
2573− |> String.join " "
2574− |> (\x -> "grid-template-rows: " ++ x ++ ";")
2575−
2576− gapX =
2577− "grid-column-gap:" ++ toGridLength (Tuple.first template.spacing) ++ ";"
2578−
2579− gapY =
2580− "grid-row-gap:" ++ toGridLength (Tuple.second template.spacing) ++ ";"
2581−
2582− modernGrid =
2583− class ++ "{" ++ columns ++ rows ++ gapX ++ gapY ++ "}"
2584−
2585− supports =
2586− "@supports (display:grid) {" ++ modernGrid ++ "}"
2587− in
2588− base ++ supports
2781+ any =
2782+ "." ++ Internal.Style.classes.any
25892783
2590− GridPosition position ->
2591− let
2592− class =
2593− ".grid-pos-"
2594− ++ String.fromInt position.row
2595− ++ "-"
2596− ++ String.fromInt position.col
2597− ++ "-"
2598− ++ String.fromInt position.width
2599− ++ "-"
2600− ++ String.fromInt position.height
2601−
2602− msPosition =
2603− String.join " "
2604− [ "-ms-grid-row: "
2605− ++ String.fromInt position.row
2606− ++ ";"
2607− , "-ms-grid-row-span: "
2608− ++ String.fromInt position.height
2609− ++ ";"
2610− , "-ms-grid-column: "
2611− ++ String.fromInt position.col
2612− ++ ";"
2613− , "-ms-grid-column-span: "
2614− ++ String.fromInt position.width
2615− ++ ";"
2616− ]
2617−
2618− base =
2619− class ++ "{" ++ msPosition ++ "}"
2620−
2621− modernPosition =
2622− String.join " "
2623− [ "grid-row: "
2624− ++ String.fromInt position.row
2625− ++ " / "
2626− ++ String.fromInt (position.row + position.height)
2627− ++ ";"
2628− , "grid-column: "
2629− ++ String.fromInt position.col
2630− ++ " / "
2631− ++ String.fromInt (position.col + position.width)
2632− ++ ";"
2633− ]
2634−
2635− modernGrid =
2636− class ++ "{" ++ modernPosition ++ "}"
2637−
2638− supports =
2639− "@supports (display:grid) {" ++ modernGrid ++ "}"
2640− in
2641− base ++ supports
2784+ single =
2785+ "." ++ Internal.Style.classes.single
2786+ in
2787+ List.concat
2788+ [ renderStyle options maybePseudo (class ++ row ++ " > " ++ any ++ " + " ++ any) [ Property "margin-left" xPx ]
2789+
2790+ -- margins don't apply to last element of normal, unwrapped rows
2791+ -- , renderStyle options maybePseudo (class ++ row ++ " > " ++ any ++ ":first-child") [ Property "margin" "0" ]
2792+ -- For wrapped rows, margins always apply because we handle "canceling out" the other margins manually in the element.
2793+ , renderStyle options
2794+ maybePseudo
2795+ (class ++ wrappedRow ++ " > " ++ any)
2796+ [ Property "margin" (halfY ++ " " ++ halfX)
2797+ ]
26422798
2643− PseudoSelector class styles ->
2644− let
2645− renderPseudoRule style =
2646− renderStyleRule style (Just class)
2647− in
2648− List.map renderPseudoRule styles
2799+ -- , renderStyle options maybePseudo
2800+ -- (class ++ wrappedRow ++ " > " ++ any ++ ":last-child")
2801+ -- [ Property "margin-right" "0"
2802+ -- ]
2803+ -- columns
2804+ , renderStyle options maybePseudo (class ++ column ++ " > " ++ any ++ " + " ++ any) [ Property "margin-top" yPx ]
2805+ , renderStyle options maybePseudo (class ++ page ++ " > " ++ any ++ " + " ++ any) [ Property "margin-top" yPx ]
2806+ , renderStyle options maybePseudo (class ++ page ++ " > " ++ left) [ Property "margin-right" xPx ]
2807+ , renderStyle options maybePseudo (class ++ page ++ " > " ++ right) [ Property "margin-left" xPx ]
2808+ , renderStyle options
2809+ maybePseudo
2810+ (class ++ paragraph)
2811+ [ Property "line-height" ("calc(1em + " ++ String.fromInt y ++ "px)")
2812+ ]
2813+ , renderStyle options
2814+ maybePseudo
2815+ ("textarea" ++ any ++ class)
2816+ [ Property "line-height" ("calc(1em + " ++ String.fromInt y ++ "px)")
2817+ , Property "height" ("calc(100% + " ++ String.fromInt y ++ "px)")
2818+ ]
2819+
2820+ -- , renderStyle options
2821+ -- maybePseudo
2822+ -- (class ++ paragraph ++ " > " ++ any)
2823+ -- [ Property "margin-right" xPx
2824+ -- , Property "margin-bottom" yPx
2825+ -- ]
2826+ , renderStyle options
2827+ maybePseudo
2828+ (class ++ paragraph ++ " > " ++ left)
2829+ [ Property "margin-right" xPx
2830+ ]
2831+ , renderStyle options
2832+ maybePseudo
2833+ (class ++ paragraph ++ " > " ++ right)
2834+ [ Property "margin-left" xPx
2835+ ]
2836+ , renderStyle options
2837+ maybePseudo
2838+ (class ++ paragraph ++ "::after")
2839+ [ Property "content" "''"
2840+ , Property "display" "block"
2841+ , Property "height" "0"
2842+ , Property "width" "0"
2843+ , Property "margin-top" (String.fromInt (-1 * (y // 2)) ++ "px")
2844+ ]
2845+ , renderStyle options
2846+ maybePseudo
2847+ (class ++ paragraph ++ "::before")
2848+ [ Property "content" "''"
2849+ , Property "display" "block"
2850+ , Property "height" "0"
2851+ , Property "width" "0"
2852+ , Property "margin-bottom" (String.fromInt (-1 * (y // 2)) ++ "px")
2853+ ]
2854+ ]
2855+
2856+ PaddingStyle cls top right bottom left ->
2857+ let
2858+ class =
2859+ "."
2860+ ++ cls
2861+ in
2862+ renderStyle options
2863+ maybePseudo
2864+ class
2865+ [ Property "padding"
2866+ (String.fromFloat top
2867+ ++ "px "
2868+ ++ String.fromFloat right
2869+ ++ "px "
2870+ ++ String.fromFloat bottom
2871+ ++ "px "
2872+ ++ String.fromFloat left
2873+ ++ "px"
2874+ )
2875+ ]
2876+
2877+ BorderWidth cls top right bottom left ->
2878+ let
2879+ class =
2880+ "."
2881+ ++ cls
2882+ in
2883+ renderStyle options
2884+ maybePseudo
2885+ class
2886+ [ Property "border-width"
2887+ (String.fromInt top
2888+ ++ "px "
2889+ ++ String.fromInt right
2890+ ++ "px "
2891+ ++ String.fromInt bottom
2892+ ++ "px "
2893+ ++ String.fromInt left
2894+ ++ "px"
2895+ )
2896+ ]
2897+
2898+ GridTemplateStyle template ->
2899+ let
2900+ class =
2901+ ".grid-rows-"
2902+ ++ String.join "-" (List.map lengthClassName template.rows)
2903+ ++ "-cols-"
2904+ ++ String.join "-" (List.map lengthClassName template.columns)
2905+ ++ "-space-x-"
2906+ ++ lengthClassName (Tuple.first template.spacing)
2907+ ++ "-space-y-"
2908+ ++ lengthClassName (Tuple.second template.spacing)
2909+
2910+ ySpacing =
2911+ toGridLength (Tuple.second template.spacing)
2912+
2913+ xSpacing =
2914+ toGridLength (Tuple.first template.spacing)
2915+
2916+ toGridLength x =
2917+ toGridLengthHelper Nothing Nothing x
2918+
2919+ toGridLengthHelper minimum maximum x =
2920+ case x of
2921+ Px px ->
2922+ String.fromInt px ++ "px"
2923+
2924+ Content ->
2925+ case ( minimum, maximum ) of
2926+ ( Nothing, Nothing ) ->
2927+ "max-content"
2928+
2929+ ( Just minSize, Nothing ) ->
2930+ "minmax(" ++ String.fromInt minSize ++ "px, " ++ "max-content)"
2931+
2932+ ( Nothing, Just maxSize ) ->
2933+ "minmax(max-content, " ++ String.fromInt maxSize ++ "px)"
2934+
2935+ ( Just minSize, Just maxSize ) ->
2936+ "minmax(" ++ String.fromInt minSize ++ "px, " ++ String.fromInt maxSize ++ "px)"
2937+
2938+ Fill i ->
2939+ case ( minimum, maximum ) of
2940+ ( Nothing, Nothing ) ->
2941+ String.fromInt i ++ "fr"
2942+
2943+ ( Just minSize, Nothing ) ->
2944+ "minmax(" ++ String.fromInt minSize ++ "px, " ++ String.fromInt i ++ "fr" ++ "fr)"
2945+
2946+ ( Nothing, Just maxSize ) ->
2947+ "minmax(max-content, " ++ String.fromInt maxSize ++ "px)"
2948+
2949+ ( Just minSize, Just maxSize ) ->
2950+ "minmax(" ++ String.fromInt minSize ++ "px, " ++ String.fromInt maxSize ++ "px)"
2951+
2952+ Min m len ->
2953+ toGridLengthHelper (Just m) maximum len
2954+
2955+ Max m len ->
2956+ toGridLengthHelper minimum (Just m) len
2957+
2958+ msColumns =
2959+ template.columns
2960+ |> List.map toGridLength
2961+ |> String.join ySpacing
2962+ |> (\x -> "-ms-grid-columns: " ++ x ++ ";")
2963+
2964+ msRows =
2965+ template.columns
2966+ |> List.map toGridLength
2967+ |> String.join ySpacing
2968+ |> (\x -> "-ms-grid-rows: " ++ x ++ ";")
2969+
2970+ base =
2971+ class ++ "{" ++ msColumns ++ msRows ++ "}"
2972+
2973+ columns =
2974+ template.columns
2975+ |> List.map toGridLength
26492976 |> String.join " "
2977+ |> (\x -> "grid-template-columns: " ++ x ++ ";")
26502978
2651− Transform transform ->
2652− let
2653− val =
2654− transformValue transform
2979+ rows =
2980+ template.rows
2981+ |> List.map toGridLength
2982+ |> String.join " "
2983+ |> (\x -> "grid-template-rows: " ++ x ++ ";")
26552984
2656− class =
2657− transformClass transform
2658− in
2659− case ( class, val ) of
2660− ( Just cls, Just v ) ->
2661− renderStyle
2662− maybePseudo
2663− ("." ++ cls)
2664− [ Property "transform"
2665− v
2666− ]
2985+ gapX =
2986+ "grid-column-gap:" ++ toGridLength (Tuple.first template.spacing) ++ ";"
26672987
2668− _ ->
2669− ""
2988+ gapY =
2989+ "grid-row-gap:" ++ toGridLength (Tuple.second template.spacing) ++ ";"
26702990
2671− combine style rendered =
2672− { rendered
2673− | rules = rendered.rules ++ renderStyleRule style Nothing
2674− , topLevel =
2675− case renderTopLevels style of
2676− Nothing ->
2677− rendered.topLevel
2991+ modernGrid =
2992+ class ++ "{" ++ columns ++ rows ++ gapX ++ gapY ++ "}"
26782993
2679− Just topLevel ->
2680− rendered.topLevel ++ topLevel
2681− }
2682− in
2683− case List.foldl combine { rules = "", topLevel = "" } stylesheet of
2684− { topLevel, rules } ->
2685− topLevel ++ rules
2994+ supports =
2995+ "@supports (display:grid) {" ++ modernGrid ++ "}"
2996+ in
2997+ [ base
2998+ , supports
2999+ ]
3000+
3001+ GridPosition position ->
3002+ let
3003+ class =
3004+ ".grid-pos-"
3005+ ++ String.fromInt position.row
3006+ ++ "-"
3007+ ++ String.fromInt position.col
3008+ ++ "-"
3009+ ++ String.fromInt position.width
3010+ ++ "-"
3011+ ++ String.fromInt position.height
3012+
3013+ msPosition =
3014+ String.join " "
3015+ [ "-ms-grid-row: "
3016+ ++ String.fromInt position.row
3017+ ++ ";"
3018+ , "-ms-grid-row-span: "
3019+ ++ String.fromInt position.height
3020+ ++ ";"
3021+ , "-ms-grid-column: "
3022+ ++ String.fromInt position.col
3023+ ++ ";"
3024+ , "-ms-grid-column-span: "
3025+ ++ String.fromInt position.width
3026+ ++ ";"
3027+ ]
3028+
3029+ base =
3030+ class ++ "{" ++ msPosition ++ "}"
3031+
3032+ modernPosition =
3033+ String.join " "
3034+ [ "grid-row: "
3035+ ++ String.fromInt position.row
3036+ ++ " / "
3037+ ++ String.fromInt (position.row + position.height)
3038+ ++ ";"
3039+ , "grid-column: "
3040+ ++ String.fromInt position.col
3041+ ++ " / "
3042+ ++ String.fromInt (position.col + position.width)
3043+ ++ ";"
3044+ ]
3045+
3046+ modernGrid =
3047+ class ++ "{" ++ modernPosition ++ "}"
3048+
3049+ supports =
3050+ "@supports (display:grid) {" ++ modernGrid ++ "}"
3051+ in
3052+ [ base
3053+ , supports
3054+ ]
3055+
3056+ PseudoSelector class styles ->
3057+ let
3058+ renderPseudoRule style =
3059+ renderStyleRule options style (Just class)
3060+ in
3061+ List.concatMap renderPseudoRule styles
3062+
3063+ Transform transform ->
3064+ let
3065+ val =
3066+ transformValue transform
3067+
3068+ class =
3069+ transformClass transform
3070+ in
3071+ case ( class, val ) of
3072+ ( Just cls, Just v ) ->
3073+ renderStyle options
3074+ maybePseudo
3075+ ("." ++ cls)
3076+ [ Property "transform"
3077+ v
3078+ ]
3079+
3080+ _ ->
3081+ []
26863082
26873083
26883084lengthClassName : Length -> String
@@ -2722,12 +3118,12 @@ formatTextShadow shadow =
27223118 ]
27233119
27243120
2725−textShadowName shadow =
3121+textShadowClass shadow =
27263122 String.concat
27273123 [ "txt"
2728− , String.fromFloat (Tuple.first shadow.offset) ++ "px"
2729− , String.fromFloat (Tuple.second shadow.offset) ++ "px"
2730− , String.fromFloat shadow.blur ++ "px"
3124+ , floatClass (Tuple.first shadow.offset) ++ "px"
3125+ , floatClass (Tuple.second shadow.offset) ++ "px"
3126+ , floatClass shadow.blur ++ "px"
27313127 , formatColorClass shadow.color
27323128 ]
27333129
@@ -2748,17 +3144,17 @@ formatBoxShadow shadow =
27483144 ]
27493145
27503146
2751−boxShadowName shadow =
3147+boxShadowClass shadow =
27523148 String.concat <|
27533149 [ if shadow.inset then
27543150 "box-inset"
27553151
27563152 else
27573153 "box-"
2758− , String.fromFloat (Tuple.first shadow.offset) ++ "px"
2759− , String.fromFloat (Tuple.second shadow.offset) ++ "px"
2760− , String.fromFloat shadow.blur ++ "px"
2761− , String.fromFloat shadow.size ++ "px"
3154+ , floatClass (Tuple.first shadow.offset) ++ "px"
3155+ , floatClass (Tuple.second shadow.offset) ++ "px"
3156+ , floatClass shadow.blur ++ "px"
3157+ , floatClass shadow.size ++ "px"
27623158 , formatColorClass shadow.color
27633159 ]
27643160
@@ -2803,6 +3199,17 @@ paddingName top right bottom left =
28033199 ++ String.fromInt left
28043200
28053201
3202+paddingNameFloat top right bottom left =
3203+ "pad-"
3204+ ++ floatClass top
3205+ ++ "-"
3206+ ++ floatClass right
3207+ ++ "-"
3208+ ++ floatClass bottom
3209+ ++ "-"
3210+ ++ floatClass left
3211+
3212+
28063213getStyleName : Style -> String
28073214getStyleName style =
28083215 case style of
@@ -3068,3 +3475,76 @@ onlyStyles attr =
30683475
30693476 _ ->
30703477 Nothing
3478+
3479+
3480+
3481+{- Font Adjustments -}
3482+
3483+
3484+convertAdjustment adjustment =
3485+ let
3486+ lineHeight =
3487+ 1.5
3488+
3489+ base =
3490+ lineHeight
3491+
3492+ normalDescender =
3493+ (lineHeight - 1)
3494+ / 2
3495+
3496+ oldMiddle =
3497+ lineHeight / 2
3498+
3499+ newCapitalMiddle =
3500+ ((ascender - newBaseline) / 2) + newBaseline
3501+
3502+ newFullMiddle =
3503+ ((ascender - descender) / 2) + descender
3504+
3505+ lines =
3506+ [ adjustment.capital
3507+ , adjustment.baseline
3508+ , adjustment.descender
3509+ , adjustment.lowercase
3510+ ]
3511+
3512+ ascender =
3513+ Maybe.withDefault adjustment.capital (List.maximum lines)
3514+
3515+ descender =
3516+ Maybe.withDefault adjustment.descender (List.minimum lines)
3517+
3518+ newBaseline =
3519+ lines
3520+ |> List.filter (\x -> x /= descender)
3521+ |> List.minimum
3522+ |> Maybe.withDefault adjustment.baseline
3523+
3524+ capitalVertical =
3525+ 1 - ascender
3526+
3527+ capitalSize =
3528+ 1 / (ascender - newBaseline)
3529+
3530+ fullSize =
3531+ 1 / (ascender - descender)
3532+
3533+ fullVertical =
3534+ 1 - ascender
3535+
3536+ -- (oldMiddle - newFullMiddle) * 2
3537+ in
3538+ { full =
3539+ adjust fullSize (ascender - descender) fullVertical
3540+ , capital =
3541+ adjust capitalSize (ascender - newBaseline) capitalVertical
3542+ }
3543+
3544+
3545+adjust size height vertical =
3546+ { vertical = vertical
3547+ , height =
3548+ height / size
3549+ , size = size
3550+ }