module Text.CSS3.Selectors.Syntax (
SelectorGroup (..),
Selector (..),
SimpleSelectorSequence (..),
HeadSimpleSelector (..),
TailSimpleSelector (..),
Combinator (..),
AttributeOperator (..),
PseudoClass (..),
PseudoClassParameter (..),
Specificity (..),
specificity
) where
import Data.List
data SelectorGroup = SelectorGroup Selector [Selector]
deriving (Show, Read, Eq)
data Selector = Selector SimpleSelectorSequence (Maybe (Combinator, Selector))
deriving (Show, Read, Eq)
data SimpleSelectorSequence = SimpleSelectorSequence HeadSimpleSelector [TailSimpleSelector]
deriving (Show, Read, Eq)
data HeadSimpleSelector = TypeSelector String
| UniversalSelector
deriving (Show, Read, Eq)
data TailSimpleSelector = AttributeSelector String (Maybe (AttributeOperator, String))
| ClassSelector String
| IDSelector String
| PseudoClass PseudoClass
deriving (Show, Read, Eq)
data Combinator = Descendant
| Child
| AdjacentSibling
| GeneralSibling
deriving (Show, Read, Eq)
data AttributeOperator = ExactMatch
| IncludesMatch
| DashMatch
| PrefixMatch
| SuffixMatch
| InfixMatch
deriving (Show, Read, Eq)
data PseudoClass = Root
| NthChild PseudoClassParameter
| NthLastChild PseudoClassParameter
| NthOfType PseudoClassParameter
| NthLastOfType PseudoClassParameter
| FirstChild
| LastChild
| FirstOfType
| LastOfType
| OnlyChild
| OnlyOfType
| Empty
| Not (Either HeadSimpleSelector TailSimpleSelector)
deriving (Show, Read, Eq)
data PseudoClassParameter = PseudoClassParameter Integer Integer
deriving (Show, Read, Eq)
data Specificity = Specificity !Int !Int !Int deriving (Show, Read, Eq, Ord)
specificity :: Selector -> Specificity
specificity (Selector (SimpleSelectorSequence hSel tSels) mbComb) =
maybe spec ((spec .+) . specificity . snd) mbComb
where
spec = foldl1' (.+) $ hSpec hSel : map tSpec tSels
hSpec h = case h of
TypeSelector _ -> Specificity 0 0 1
UniversalSelector -> Specificity 0 0 0
tSpec t = case t of
AttributeSelector _ _ -> Specificity 0 1 0
ClassSelector _ -> Specificity 0 1 0
IDSelector _ -> Specificity 1 0 0
PseudoClass (Not eSel) -> either hSpec tSpec eSel
PseudoClass _ -> Specificity 0 1 0
(.+) (Specificity a b c) (Specificity a' b' c') = Specificity (a + a') (b + b') (c + c')