DoctorRynerNew

Untitled

Sep 13th, 2019
84
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. {-# OPTIONS_GHC -Wno-orphans #-}
  2. {-# LANGUAGE TupleSections #-}
  3.  
  4. module Miso.Styled where
  5.  
  6. import           Clay                (Css, element, render, (?))
  7. import           Data.Coerce         (coerce)
  8. import qualified Data.HashMap.Strict as HMap
  9. import           Data.List           (nub)
  10. import qualified Data.Text           as T
  11. import qualified Data.Text.Lazy      as TL
  12. import qualified Miso
  13. import           Miso.String         (MisoString, ms)
  14. import           System.IO.Unsafe    (unsafePerformIO)
  15. import           System.Random
  16.  
  17. instance Eq Css where
  18.     s1 == s2 = render s1 == render s2
  19.     s1 /= s2 = render s1 /= render s2
  20.  
  21. type View a = VTree a
  22.  
  23. newtype Attribute a = Attribute (Miso.Attribute a)
  24.  
  25. data VTree a
  26.     = VNode MisoString Css [Attribute a] [VTree a]
  27.     | VText MisoString
  28.  
  29. node :: MisoString -> [Miso.Attribute a] -> [View a] -> View a
  30. node tag attrs = VNode tag mempty (coerce attrs)
  31.  
  32. generateHtml :: HMap.HashMap TL.Text Int -> MisoString -> View a -> Miso.View a
  33. generateHtml _ _            (VText str)                  = Miso.text str
  34. generateHtml cssHash uniqId (VNode tag css attrs childs) = Miso.nodeHtml
  35.     tag
  36.     (coerce attrs ++ case HMap.lookup (render css) cssHash of
  37.         Just className -> [ Miso.class_ $ "_" <> uniqId <> ms className ]
  38.         Nothing        -> []
  39.     )
  40.     $ map (generateHtml cssHash uniqId) childs
  41.  
  42. collectCss :: View a -> [Css]
  43. collectCss (VText _             ) = mempty
  44. collectCss (VNode _ css _ childs) = css : mconcat (map collectCss childs)
  45.  
  46. rnd :: () -> Int
  47. rnd _ = unsafePerformIO $ randomRIO (0, 9999999)
  48.  
  49. toUnstyled :: View a -> Miso.View a
  50. toUnstyled tree = Miso.div_ []
  51.     [ Miso.nodeHtml "style" [] [ Miso.text $ ms $ mconcat $ map render renderCss ]
  52.     , generateHtml cssHash (ms uniqId) tree
  53.     ]
  54.   where
  55.     uniqId    = T.pack $ show $ rnd ()
  56.     renderCss = map (\(css, id') -> element ("._" <> uniqId <> T.pack (show id')) ? css) cssKeyed
  57.     cssHash   = HMap.fromList (map (\(css, id') -> (render css, id')) cssKeyed)
  58.     cssKeyed  = map (, rnd ()) css
  59.     css       = nub $ collectCss tree
  60.    
  61. toUnstyled' :: View a -> [Miso.View a]
  62. toUnstyled' tree = [ Miso.nodeHtml "style" [] [ Miso.text $ ms $ mconcat $ map render renderCss ]
  63.                    , generateHtml cssHash (ms uniqId) tree
  64.                    ]
  65.   where
  66.     uniqId    = T.pack $ show $ rnd ()
  67.     renderCss = map (\(css, id') -> element ("._" <> uniqId <> T.pack (show id')) ? css) cssKeyed
  68.     cssHash   = HMap.fromList (map (\(css, id') -> (render css, id')) cssKeyed)
  69.     cssKeyed  = map (, rnd ()) css
  70.     css       = nub $ collectCss tree
  71.  
  72. text :: MisoString -> VTree a
  73. text = VText
  74.  
  75. styled :: MisoString -> Css -> [Miso.Attribute a] -> [View a] -> View a
  76. styled tag css attrs = VNode tag css (coerce attrs)
Add Comment
Please, Sign In to add comment