Changed Prop's cssMap from Map String Css to IntMap String.

The cssMap now contains the rendered css together with its hash. That
way there is no need to give a component a name, and css is rendered
along the way and carried as a string.
This commit is contained in:
Etienne Werly 2023-07-03 16:21:46 +02:00
parent fb23dd73d9
commit 1068b16a67
19 changed files with 34 additions and 43 deletions

View file

@ -2,16 +2,14 @@ module Main
( main
) where
import Data.Hashable
import Data.Hashable ( hash )
import Data.String
import Hakyll
import Text.Blaze.Html
import Components
import Core.Compilers
import Core.Render ( )
import Core.Rules
import Routes
import Utils.FileTree
import Utils.Routes
@ -30,7 +28,7 @@ assets :: [FilePath]
assets = map tail . getPaths . getAssets $ resources
allCss :: String
allCss = show . getCss $ resources
allCss = getCss resources
css :: Compiler (Item String)
css = makeItem allCss

View file

@ -1,6 +1,5 @@
module Components
( Prop(..)
, prop
, Component(..)
, new
, (<.>)
@ -12,21 +11,17 @@ module Components
, getAssets
) where
import Clay ( Css
, compact
, renderWith
)
import Clay ( Css )
import Core.Render ( )
import Core.Writer
import qualified Data.Map as Map
import Data.Text.Lazy ( unpack )
import Data.Hashable ( hash )
import qualified Data.IntMap as Map
import Routes
import Text.Blaze.Html
import Text.Blaze.Html.Renderer.String
import Utils.FileTree
-- |Props are data on top of a component's html. They are aggregated when components are combined. The choice of structures for Prop ensures that there is no duplicate at compile time (e.g. the css of a button used 5 times is only rendered once.)
data Prop = Prop
{ cssMap :: Map.Map String Css
{ cssMap :: Map.IntMap String
, assetsTree :: FileTree
}
@ -40,11 +35,12 @@ instance Monoid Prop where
type Component = Writer Prop
prop :: String -> Css -> Prop
prop name css = Prop (Map.singleton name css) mempty
-- |Add a name and css to a Prop.
addCss :: String -> Css -> Component ()
addCss name css = tell $ Prop (Map.singleton name css) mempty
addCss :: Css -> Component ()
addCss css = tell $ Prop (Map.singleton cssHash cssString) mempty
where
cssString = show css
cssHash = hash cssString
-- |Add an asset to the Prop's tree.
addAsset :: FilePath -> Component ()
@ -58,7 +54,7 @@ getBody :: Component a -> a
getBody = fst . runWriter
-- |Get a Component's Css
getCss :: Component a -> Css
getCss :: Component a -> String
getCss = mconcat . map snd . Map.toList . cssMap . snd . runWriter
-- |Get a Component's assets tree

View file

@ -15,5 +15,5 @@ css = C.button ? do
buttonWithText :: Component (Html -> Html)
buttonWithText = do
addCss "buttonWithText" css
addCss css
return H.button

View file

@ -33,5 +33,5 @@ css = C.a # byClass "button" ? do
buttonLink :: Route -> Component (Html -> Html)
buttonLink ref = do
addCss "buttonLink" css
addCss css
return $ buttonLinkHtml ref

View file

@ -14,5 +14,5 @@ css = element ".container" ? do
container :: Component (Html -> Html)
container = do
addCss "container" css
addCss css
return $ H.div H.! class_ "container"

View file

@ -21,5 +21,5 @@ css = C.header ? do
header' :: Component (Html -> Html)
header' = do
addCss "header" css
addCss css
return H.header

View file

@ -20,7 +20,7 @@ baseCss = C.img ? do
img' :: FilePath -> String -> Component Html
img' file description = do
addCss "img" baseCss
addCss baseCss
addAsset' $ Img file
return $ H.img H.! A.src (stringValue . path . Img $ file) H.! A.alt
(stringValue description)
@ -30,20 +30,17 @@ imgWithShape :: Shape -> FilePath -> String -> Component Html
imgWithShape Square file description = img' file description
imgWithShape Circle file description =
do
addCss "img circle"
(C.img # byClass "circle" ? uniform borderRadius (pct 50))
addCss (C.img # byClass "circle" ? uniform borderRadius (pct 50))
return (H.! class_ "circle")
<*> img' file description
imgWithShape Rounded file description =
do
addCss "img rounded"
(C.img # byClass "rounded" ? uniform borderRadius (pct 10))
addCss (C.img # byClass "rounded" ? uniform borderRadius (pct 10))
return (H.! class_ "rounded")
<*> img' file description
imgWithShape Drop file description =
do
addCss
"img drop"
(C.img # byClass "drop" ? borderRadius (pct 50) (pct 50) (pct 50) (pct 10)
)
return (H.! class_ "drop")

View file

@ -20,5 +20,5 @@ css = C.a ? do
a' :: Route -> Component (Html -> Html)
a' ref = do
addCss "link" css
addCss css
return $ H.a H.! A.href (stringValue . path $ ref)

View file

@ -22,7 +22,7 @@ css = do
section' :: Component (Html -> Html)
section' =
do
addCss "section" css
return $ H.section
addCss css
return H.section
<.> container
<.> pure (H.div H.! class_ "section-inner")

View file

@ -10,5 +10,5 @@ import Text.Blaze.Html5.Attributes
stylesheet :: Route -> Css -> Component Html
stylesheet route css = do
addCss (path route) css
addCss css
return $ link ! rel "stylesheet" ! (href . stringValue . path $ route)

View file

@ -21,5 +21,5 @@ css = element ".bricklayer" ? do
bricklayer :: Component (Html -> Html)
bricklayer = do
addCss "Bricklayer" css
addCss css
return $ H.div H.! class_ "bricklayer"

View file

@ -10,5 +10,5 @@ import Text.Blaze.Html5.Attributes as A
cardBody :: Component (Html -> Html)
cardBody = do
addCss "CardBody" (element ".card-body" ? C.width (pct 100))
addCss (element ".card-body" ? C.width (pct 100))
return $ H.div H.! class_ "card-body"

View file

@ -19,5 +19,5 @@ css = element ".card-footer" ? do
cardFooter :: Component (Html -> Html)
cardFooter = do
addCss "CardFooter" css
addCss css
return $ (H.div H.! class_ "card-footer") . H.p

View file

@ -22,6 +22,6 @@ css = element ".card-header" ? do
cardHeader :: Route -> Component (Html -> Html)
cardHeader route =
do
addCss "CardHeader" css
addCss css
return $ H.div H.! class_ "card-header"
<.> a' route

View file

@ -21,5 +21,5 @@ css = byClass "profile-bio" & do
profileBio :: String -> Component Html
profileBio bio = do
addCss "profileBio" css
addCss css
return $ H.div H.! class_ "profile-bio" $ H.p (toHtml bio)

View file

@ -17,7 +17,7 @@ css = byClass "profile-content" & do
profileContent :: String -> String -> Component Html
profileContent auth desc = do
addCss "profileContent" css
addCss css
return
$ H.div
H.! class_ "profile-content"

View file

@ -22,6 +22,6 @@ css = byClass "profile-pic" & do
profilePic :: FilePath -> String -> Component Html
profilePic file altText =
do
addCss "profilePic" css
addCss css
return $ H.div H.! class_ "profile-pic"
<*> imgWithShape Rounded file altText

View file

@ -31,12 +31,12 @@ linkCss = C.a # byClass "tag" # hover ? do
tagSpan :: String -> Component (Html -> Html)
tagSpan tag = do
addCss "tagSpan" css
addCss css
return $ H.span H.! class_ "tag" H.! A.id (stringValue tag)
tagLink :: Route -> Component (Html -> Html)
tagLink ref =
do
addCss "tagLink" linkCss
addCss linkCss
return (H.! class_ "tag")
<.> a' ref

View file

@ -42,7 +42,7 @@ css = C.article # byClass "card" ? do
blogCard :: PostProp -> Component Html
blogCard prop =
do
addCss "blogCard" css
addCss css
return $ H.article H.! class_ "card"
<*> mconcat
[ cardHeader (postRoute prop) <*> pure (postTitle prop)