miso-css-0.0.1: src/Miso/Css/Style/E.hs
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE UndecidableInstances #-}
module Miso.Css.Style.E where
import Data.String ( IsString(..) )
import Data.Type.Bool ( If )
import Miso ( MisoString, ms, View )
import Miso.Css.Event (EventFactory)
import Miso.Css.List ( MergeUniq, Elem, PrependMb, Append )
import Miso.Css.Prelude
import Miso.Css.Segment
( ApplyClass,
ApplySubSegsToElem,
BRANCH,
MbSymToMbI,
SubSeg(C, R, I, T, A) )
import Miso.Css.Style.OrClass ( OrClass )
import Miso.Css.Style.PostAppend qualified as Post
import Miso.Css.Style.PreAppend qualified as Pre
import Miso.JSON ( ToJSON )
data ElementId (ei :: Symbol)
newtype ElAtr k v = ElAtr v deriving newtype (Eq, Ord, Show, ToJSON) deriving (Generic)
elAtrKey :: forall k v. KnownSymbol k => ElAtr k v -> MisoString
elAtrKey _ = ms $ symbolVal (Proxy @k)
elAtrVal :: forall {k1} {k2 :: k1} {v}. ElAtr k2 v -> v
elAtrVal (ElAtr v) = v
type family AppendChild children ceacs pcls peacs where
AppendChild children ceacs '[] peacs =
(Append (Post.MapMaybeFilterOutFullyMatchedHead children ceacs) peacs)
AppendChild children ceacs (pclsH : pcls') peacs =
AppendChild children (ApplyClass '[] pclsH ceacs) pcls' peacs
type family SymsToSubSeg l where
SymsToSubSeg '[] = '[]
SymsToSubSeg (h : l) = C h : SymsToSubSeg l
type family SymsToAtrs l where
SymsToAtrs '[] = '[]
SymsToAtrs (h : l) = A h : SymsToAtrs l
data ElementStructure = Atomic | Composite
newtype DuplicatedID = DuplicatedId Symbol
data KnownIDS = KnownIds { duplicatedIds :: [DuplicatedID], knownIds :: [Symbol] }
type family DuplicatedIds kids where
DuplicatedIds (KnownIds dids _) = dids
type family AddTagId x kids where
AddTagId x (KnownIds dids kids) =
If (Elem x kids)
(KnownIds (DuplicatedId x : dids) kids)
(KnownIds dids (x : kids))
type family MergeKidsCase r didsA didsB kidsA kidsB where
MergeKidsCase (Left e) didsA didsB kidsA kidsB =
KnownIds
(DuplicatedId e : Append didsA didsB)
(Append kidsA kidsB)
MergeKidsCase (Right kidsAB) didsA didsB _kidsA _kidsB =
KnownIds
(Append didsA didsB)
kidsAB
type family MergeKids a b where
MergeKids (KnownIds didsA kidsA) (KnownIds didsB kidsB) =
MergeKidsCase (MergeUniq kidsA kidsB '[]) didsA didsB kidsA kidsB
type EmptyKids = KnownIds '[] '[]
type CD = "CDATA"
type RMV = "RawMisoView"
type HTML = "html"
type BODY = "body"
data Root = Root deriving (Show, Eq)
type ConstraintsAfterAppend ::
[[SubSeg]] -> [[BRANCH]] ->
Maybe Symbol -> Symbol -> [Symbol] -> [Symbol] ->
[[BRANCH]] -> [[BRANCH]]
type family ConstraintsAfterAppend pchildren ceacs pi pe pAtrs pcls peacs where
ConstraintsAfterAppend pchildren ceacs pi pe pAtrs pcls peacs =
AppendChild
pchildren
(Pre.MapMaybeFilterOutFullyMatchedHead '[] ceacs)
(PrependMb
(MbSymToMbI pi)
(T pe : Append (SymsToAtrs pAtrs) (SymsToSubSeg pcls)))
peacs
type family ChildrenConstrAfterAppend ci ce ccls pchildren where
ChildrenConstrAfterAppend ci ce ccls pchildren =
PrependMb (MbSymToMbI ci) (T ce : SymsToSubSeg ccls) : pchildren
type family ConstraintsAfterClassApp ei en atrs cls p c eacs where
ConstraintsAfterClassApp ei en atrs cls p c eacs =
ApplyClass
(ApplySubSegsToElem
(PrependMb
(MbSymToMbI ei)
(T en : A "class" : Append (SymsToAtrs atrs) (SymsToSubSeg cls)))
p)
(C c)
eacs
type family ConstraintsAfteId ei eacs where
ConstraintsAfteId ei eacs = ApplyClass '[] (A "id") (ApplyClass '[] (I ei) eacs)
data E
model
action
(en :: Symbol)
(es :: ElementStructure)
(re :: Maybe Root)
(ei :: Maybe Symbol)
(atrs :: [Symbol])
(knownIds :: KnownIDS)
(cls :: [Symbol])
(l :: [[BRANCH]])
(children :: [[SubSeg]])
where
RawMisoView ::
View model action ->
E model action RMV Atomic Nothing Nothing '[] EmptyKids '[] '[] '[]
CDataE ::
MisoString ->
E model action CD Atomic Nothing Nothing '[] EmptyKids '[] '[] '[]
NilE :: KnownSymbol en =>
Proxy en ->
E model action en Composite Nothing Nothing '[] EmptyKids '[] '[] '[]
AddAtrE :: (KnownSymbol k, ToJSON v) =>
ElAtr k v ->
E model action en Composite r ei atrs kids cls eacs children ->
E model action en Composite r ei (k : atrs) kids cls
(ApplyClass '[] (A k) eacs)
children
IdE :: KnownSymbol ei =>
Proxy ei ->
E model action en Composite r Nothing atrs kids cls eacs children ->
E model action en Composite r (Just ei) ("id" : atrs)
(AddTagId ei kids)
cls
(ConstraintsAfteId ei eacs)
children
BindEventE :: EventFactory ef action =>
ef ->
E model action en es r ei atrs kids cls eacs children ->
E model action en es r ei atrs kids cls eacs children
AppClsE :: (KnownSymbol en, KnownSymbol c) =>
OrClass p c ->
E model action en Composite r ei atrs kIds cls eacs children ->
E model action en Composite r ei ("class" : atrs) kIds (c : cls)
(ConstraintsAfterClassApp ei en atrs cls p c eacs)
children
AppendChildE :: KnownSymbol ce =>
E model action ce cs Nothing ci cAtrs ckIds ccls ceacs cchildren ->
E model action pe Composite r pi pAtrs pkIds pcls peacs pchildren ->
E model action pe Composite r pi pAtrs
(MergeKids ckIds pkIds)
pcls
(ConstraintsAfterAppend pchildren ceacs pi pe pAtrs pcls peacs)
(ChildrenConstrAfterAppend ci ce ccls pchildren)
-- Miso can render view up to body to support :root the library provide
-- VirtualBodyE and SealDomE to emulate top DOM elements (body and html) without
-- generating them because the already exist
VirtualBodyE ::
E model action ce cs Nothing ci catrs ckids ccls ceacs cchildren ->
E model action BODY Composite Nothing Nothing catrs
ckids
'[]
(AppendChild
'[] -- pchildren
ceacs
'[ T BODY ]
'[])
'[ PrependMb (MbSymToMbI ci) (T ce : SymsToSubSeg ccls) ]
SealDomE ::
E model action ce cs Nothing ci catrs ckids ccls ceacs cchildren ->
E model action HTML Composite (Just 'Root) Nothing catrs
ckids
'[]
(Post.MapMaybeFilterOutFullyMatchedHead
'[]
(ApplyClass '[] (T HTML) (ApplyClass '[] R ceacs)))
'[ PrependMb (MbSymToMbI ci) (T ce : SymsToSubSeg ccls) ]
instance IsString (E model action CD Atomic Nothing Nothing '[] EmptyKids '[] '[] '[]) where
fromString = CDataE . ms