-- | Defines all the types needed for "Stitch"'s internal CSS representation. You shouldn't need to import this module unless you're messing around with the 'Block' representation before outputting CSS. module Stitch.Types ( Selector(..) , Children(..) , Property(..) , Import(..) , Block(..) , InnerBlock(..) ) where import Stitch.Types.Selector import Data.Map (Map) import Data.Text (Text) import Data.Semigroup (Semigroup(..)) import qualified Data.Map as Map -- | Children is a simple specialized wrapper around 'Map' with a custom 'Monoid' instance. Instead of simply 'Data.Map.union'ing the two 'Map's, the 'Children' instance 'mappend's the two values together in case of a key clash. newtype Children = Children (Map Selector InnerBlock) deriving (Show, Read, Eq) instance Semigroup Children where Children x <> Children y = Children (Map.unionWith mappend x y) instance Monoid Children where mempty = Children mempty mappend = (<>) -- | Type for a CSS property or comment. The two are combined because we want to keep the ordering of comments and properties in the output CSS. data Property = Property Text Text | Comment Text deriving (Show, Read, Eq) -- | Basic newtype for handling css @@import@ statements. newtype Import = Import Text deriving (Show, Read, Eq) -- | Representation of a CSS inner block. Similar to a top-level 'Block', but doesn't allow 'Import's. data InnerBlock = InnerBlock [Property] Children deriving (Show, Read, Eq) instance Semigroup InnerBlock where InnerBlock p c <> InnerBlock q d = InnerBlock (p <> q) (c <> d) instance Monoid InnerBlock where mempty = InnerBlock [] mempty mappend = (<>) -- | Top-level representation of a CSS document. data Block = Block [Import] [Property] Children deriving (Show, Read, Eq) instance Semigroup Block where Block i p c <> Block j q d = Block (i <> j) (p <> q) (c <> d) instance Monoid Block where mempty = Block mempty mempty mempty mappend = (<>)