module Data.CSS.Syntax.Selector(
Selector(..), SimpleSelector(..), PropertyTest(..), PropertyFunc(..),
parseSelectors
) where
import Data.CSS.Syntax.Tokens
import Data.CSS.Syntax.StylishUtil
import Data.Text.Internal (Text(..))
data Selector = Element [SimpleSelector]
| Child Selector [SimpleSelector]
| Descendant Selector [SimpleSelector]
| Adjacent Selector [SimpleSelector]
| Sibling Selector [SimpleSelector]
deriving (Int -> Selector -> ShowS
[Selector] -> ShowS
Selector -> String
(Int -> Selector -> ShowS)
-> (Selector -> String) -> ([Selector] -> ShowS) -> Show Selector
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Selector] -> ShowS
$cshowList :: [Selector] -> ShowS
show :: Selector -> String
$cshow :: Selector -> String
showsPrec :: Int -> Selector -> ShowS
$cshowsPrec :: Int -> Selector -> ShowS
Show, Selector -> Selector -> Bool
(Selector -> Selector -> Bool)
-> (Selector -> Selector -> Bool) -> Eq Selector
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Selector -> Selector -> Bool
$c/= :: Selector -> Selector -> Bool
== :: Selector -> Selector -> Bool
$c== :: Selector -> Selector -> Bool
Eq)
data SimpleSelector = Tag Text
| Namespace Text
| Id Text
| Class Text
| Property (Maybe Text) Text PropertyTest
| Psuedoclass Text [Token]
deriving (Int -> SimpleSelector -> ShowS
[SimpleSelector] -> ShowS
SimpleSelector -> String
(Int -> SimpleSelector -> ShowS)
-> (SimpleSelector -> String)
-> ([SimpleSelector] -> ShowS)
-> Show SimpleSelector
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [SimpleSelector] -> ShowS
$cshowList :: [SimpleSelector] -> ShowS
show :: SimpleSelector -> String
$cshow :: SimpleSelector -> String
showsPrec :: Int -> SimpleSelector -> ShowS
$cshowsPrec :: Int -> SimpleSelector -> ShowS
Show, SimpleSelector -> SimpleSelector -> Bool
(SimpleSelector -> SimpleSelector -> Bool)
-> (SimpleSelector -> SimpleSelector -> Bool) -> Eq SimpleSelector
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: SimpleSelector -> SimpleSelector -> Bool
$c/= :: SimpleSelector -> SimpleSelector -> Bool
== :: SimpleSelector -> SimpleSelector -> Bool
$c== :: SimpleSelector -> SimpleSelector -> Bool
Eq)
data PropertyTest = Exists
| Equals Text
| Suffix Text
| Prefix Text
| Substring Text
| Include Text
| Dash Text
| Callback PropertyFunc
deriving (Int -> PropertyTest -> ShowS
[PropertyTest] -> ShowS
PropertyTest -> String
(Int -> PropertyTest -> ShowS)
-> (PropertyTest -> String)
-> ([PropertyTest] -> ShowS)
-> Show PropertyTest
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [PropertyTest] -> ShowS
$cshowList :: [PropertyTest] -> ShowS
show :: PropertyTest -> String
$cshow :: PropertyTest -> String
showsPrec :: Int -> PropertyTest -> ShowS
$cshowsPrec :: Int -> PropertyTest -> ShowS
Show, PropertyTest -> PropertyTest -> Bool
(PropertyTest -> PropertyTest -> Bool)
-> (PropertyTest -> PropertyTest -> Bool) -> Eq PropertyTest
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: PropertyTest -> PropertyTest -> Bool
$c/= :: PropertyTest -> PropertyTest -> Bool
== :: PropertyTest -> PropertyTest -> Bool
$c== :: PropertyTest -> PropertyTest -> Bool
Eq)
data PropertyFunc = PropertyFunc (String -> Bool)
instance Show PropertyFunc where
show :: PropertyFunc -> String
show PropertyFunc
_ = String
"xx"
instance Eq PropertyFunc where
PropertyFunc
_ == :: PropertyFunc -> PropertyFunc -> Bool
== PropertyFunc
_ = Bool
False
parseSelectors :: Parser [Selector]
parseSelectors :: Parser [Selector]
parseSelectors [Token]
tokens = (Selector -> [Selector] -> [Selector])
-> Parser Selector -> Parser [Selector] -> Parser [Selector]
forall a b c. (a -> b -> c) -> Parser a -> Parser b -> Parser c
concatP (:) Parser Selector
parseCompound Parser [Selector]
parseSelectorsTail Parser [Selector] -> Parser [Selector]
forall a b. (a -> b) -> a -> b
$ [Token] -> [Token]
skipSpace [Token]
tokens
parseSelectorsTail :: Parser [Selector]
parseSelectorsTail :: Parser [Selector]
parseSelectorsTail (Token
Comma:[Token]
tokens) = Parser [Selector]
parseSelectors [Token]
tokens
parseSelectorsTail [Token]
tokens = ([], [Token]
tokens)
parseCompound :: Parser Selector
parseCompound :: Parser Selector
parseCompound [Token]
tokens = Selector -> Parser Selector
parseCombinators ([SimpleSelector] -> Selector
Element [SimpleSelector]
selector) [Token]
tokens'
where ([SimpleSelector]
selector, [Token]
tokens') = Parser [SimpleSelector]
parseSelector [Token]
tokens
parseSelector' :: SimpleSelector -> Parser [SimpleSelector]
parseSelector' :: SimpleSelector -> Parser [SimpleSelector]
parseSelector' SimpleSelector
op [Token]
tokens = (SimpleSelector
opSimpleSelector -> [SimpleSelector] -> [SimpleSelector]
forall a. a -> [a] -> [a]
:[SimpleSelector]
selector, [Token]
tokens')
where ([SimpleSelector]
selector, [Token]
tokens') = Parser [SimpleSelector]
parseSelector [Token]
tokens
parseSelector :: Parser [SimpleSelector]
parseSelector :: Parser [SimpleSelector]
parseSelector (Ident Text
ns:Delim Char
'|':[Token]
tokens) = SimpleSelector -> Parser [SimpleSelector]
parseSelector' (Text -> SimpleSelector
Namespace Text
ns) [Token]
tokens
parseSelector (Delim Char
'*':[Token]
tokens) = Parser [SimpleSelector]
parseSelector [Token]
tokens
parseSelector (Ident Text
tag:[Token]
tokens) = SimpleSelector -> Parser [SimpleSelector]
parseSelector' (Text -> SimpleSelector
Tag Text
tag) [Token]
tokens
parseSelector (Hash HashFlag
_ Text
i:[Token]
tokens) = SimpleSelector -> Parser [SimpleSelector]
parseSelector' (Text -> SimpleSelector
Id Text
i) [Token]
tokens
parseSelector (Delim Char
'.':Ident Text
class_:[Token]
tokens) = SimpleSelector -> Parser [SimpleSelector]
parseSelector' (Text -> SimpleSelector
Class Text
class_) [Token]
tokens
parseSelector (Token
LeftSquareBracket:Ident Text
ns:Delim Char
'|':Ident Text
prop:[Token]
tokens) =
(PropertyTest -> [SimpleSelector] -> [SimpleSelector])
-> Parser PropertyTest
-> Parser [SimpleSelector]
-> Parser [SimpleSelector]
forall a b c. (a -> b -> c) -> Parser a -> Parser b -> Parser c
concatP PropertyTest -> [SimpleSelector] -> [SimpleSelector]
appendPropertySel Parser PropertyTest
parsePropertySel Parser [SimpleSelector]
parseSelector [Token]
tokens
where appendPropertySel :: PropertyTest -> [SimpleSelector] -> [SimpleSelector]
appendPropertySel PropertyTest
test [SimpleSelector]
selector = Maybe Text -> Text -> PropertyTest -> SimpleSelector
Property (Text -> Maybe Text
forall a. a -> Maybe a
Just Text
ns) Text
prop PropertyTest
test SimpleSelector -> [SimpleSelector] -> [SimpleSelector]
forall a. a -> [a] -> [a]
: [SimpleSelector]
selector
parseSelector (Token
LeftSquareBracket:Ident Text
prop:[Token]
tokens) =
(PropertyTest -> [SimpleSelector] -> [SimpleSelector])
-> Parser PropertyTest
-> Parser [SimpleSelector]
-> Parser [SimpleSelector]
forall a b c. (a -> b -> c) -> Parser a -> Parser b -> Parser c
concatP PropertyTest -> [SimpleSelector] -> [SimpleSelector]
appendPropertySel Parser PropertyTest
parsePropertySel Parser [SimpleSelector]
parseSelector [Token]
tokens
where appendPropertySel :: PropertyTest -> [SimpleSelector] -> [SimpleSelector]
appendPropertySel PropertyTest
test [SimpleSelector]
selector = Maybe Text -> Text -> PropertyTest -> SimpleSelector
Property Maybe Text
forall a. Maybe a
Nothing Text
prop PropertyTest
test SimpleSelector -> [SimpleSelector] -> [SimpleSelector]
forall a. a -> [a] -> [a]
: [SimpleSelector]
selector
parseSelector (Token
Colon:Ident Text
p:[Token]
ts) = SimpleSelector -> Parser [SimpleSelector]
parseSelector' (Text -> [Token] -> SimpleSelector
Psuedoclass Text
p []) [Token]
ts
parseSelector (Token
Colon:Function Text
fn:[Token]
tokens) =
([Token] -> [SimpleSelector] -> [SimpleSelector])
-> Parser [Token]
-> Parser [SimpleSelector]
-> Parser [SimpleSelector]
forall a b c. (a -> b -> c) -> Parser a -> Parser b -> Parser c
concatP [Token] -> [SimpleSelector] -> [SimpleSelector]
appendPseudo Parser [Token]
scanBlock Parser [SimpleSelector]
parseSelector [Token]
tokens
where appendPseudo :: [Token] -> [SimpleSelector] -> [SimpleSelector]
appendPseudo [Token]
args [SimpleSelector]
selector = Text -> [Token] -> SimpleSelector
Psuedoclass Text
fn [Token]
args SimpleSelector -> [SimpleSelector] -> [SimpleSelector]
forall a. a -> [a] -> [a]
: [SimpleSelector]
selector
parseSelector [Token]
tokens = ([], [Token]
tokens)
parseCombinators' :: Selector -> Parser Selector
parseCombinators' :: Selector -> Parser Selector
parseCombinators' Selector
selector [Token]
tokens = Selector -> Parser Selector
parseCombinators Selector
selector' [Token]
tokens'
where (Selector
selector', [Token]
tokens') = Selector -> Parser Selector
parseCombinator Selector
selector [Token]
tokens
parseCombinators :: Selector -> Parser Selector
parseCombinators :: Selector -> Parser Selector
parseCombinators Selector
selector (Token
Whitespace:[Token]
tokens) = Selector -> Parser Selector
parseCombinators' Selector
selector [Token]
tokens
parseCombinators Selector
selector tokens :: [Token]
tokens@(Delim Char
_:[Token]
_) = Selector -> Parser Selector
parseCombinators' Selector
selector [Token]
tokens
parseCombinators Selector
selector [Token]
tokens = (Selector
selector, [Token]
tokens)
parseCombinator' :: (Selector -> [SimpleSelector] -> Selector)
-> Selector -> Parser Selector
parseCombinator' :: (Selector -> [SimpleSelector] -> Selector)
-> Selector -> Parser Selector
parseCombinator' Selector -> [SimpleSelector] -> Selector
cb Selector
selector [Token]
tokens = (Selector -> [SimpleSelector] -> Selector
cb Selector
selector [SimpleSelector]
selector', [Token]
tokens')
where ([SimpleSelector]
selector', [Token]
tokens') = Parser [SimpleSelector]
parseSelector Parser [SimpleSelector] -> Parser [SimpleSelector]
forall a b. (a -> b) -> a -> b
$ [Token] -> [Token]
skipSpace [Token]
tokens
parseCombinator :: Selector -> [Token] -> (Selector, [Token])
parseCombinator :: Selector -> Parser Selector
parseCombinator Selector
selector (Token
Whitespace:[Token]
tokens) = Selector -> Parser Selector
parseCombinator Selector
selector [Token]
tokens
parseCombinator Selector
selector (Delim Char
'>':[Token]
tokens) = (Selector -> [SimpleSelector] -> Selector)
-> Selector -> Parser Selector
parseCombinator' Selector -> [SimpleSelector] -> Selector
Child Selector
selector [Token]
tokens
parseCombinator Selector
selector (Delim Char
'~':[Token]
tokens) = (Selector -> [SimpleSelector] -> Selector)
-> Selector -> Parser Selector
parseCombinator' Selector -> [SimpleSelector] -> Selector
Sibling Selector
selector [Token]
tokens
parseCombinator Selector
selector (Delim Char
'+':[Token]
tokens) = (Selector -> [SimpleSelector] -> Selector)
-> Selector -> Parser Selector
parseCombinator' Selector -> [SimpleSelector] -> Selector
Adjacent Selector
selector [Token]
tokens
parseCombinator Selector
selector tokens :: [Token]
tokens@(Token
LeftCurlyBracket:[Token]
_) = (Selector
selector, [Token]
tokens)
parseCombinator Selector
selector tokens :: [Token]
tokens@(Token
RightCurlyBracket:[Token]
_) = (Selector
selector, [Token]
tokens)
parseCombinator Selector
selector tokens :: [Token]
tokens@(Token
RightSquareBracket:[Token]
_) = (Selector
selector, [Token]
tokens)
parseCombinator Selector
selector tokens :: [Token]
tokens@(Token
Comma:[Token]
_) = (Selector
selector, [Token]
tokens)
parseCombinator Selector
selector tokens :: [Token]
tokens@(Token
RightParen:[Token]
_) = (Selector
selector, [Token]
tokens)
parseCombinator Selector
selector [] = (Selector
selector, [])
parseCombinator Selector
selector [Token]
tokens = (Selector -> [SimpleSelector] -> Selector)
-> Selector -> Parser Selector
parseCombinator' Selector -> [SimpleSelector] -> Selector
Descendant Selector
selector [Token]
tokens
parsePropertySel :: Parser PropertyTest
parsePropertySel :: Parser PropertyTest
parsePropertySel (Token
RightSquareBracket:[Token]
tokens) = (PropertyTest
Exists, [Token]
tokens)
parsePropertySel (Delim Char
'=':[Token]
tokens) = (Text -> PropertyTest) -> Parser PropertyTest
parsePropertyVal (Text -> PropertyTest
Equals) [Token]
tokens
parsePropertySel (Token
SuffixMatch:[Token]
tokens) = (Text -> PropertyTest) -> Parser PropertyTest
parsePropertyVal (Text -> PropertyTest
Suffix) [Token]
tokens
parsePropertySel (Token
PrefixMatch:[Token]
tokens) = (Text -> PropertyTest) -> Parser PropertyTest
parsePropertyVal (Text -> PropertyTest
Prefix) [Token]
tokens
parsePropertySel (Token
SubstringMatch:[Token]
tokens) = (Text -> PropertyTest) -> Parser PropertyTest
parsePropertyVal (Text -> PropertyTest
Substring) [Token]
tokens
parsePropertySel (Token
IncludeMatch:[Token]
tokens) = (Text -> PropertyTest) -> Parser PropertyTest
parsePropertyVal (Text -> PropertyTest
Include) [Token]
tokens
parsePropertySel (Token
DashMatch:[Token]
tokens) = (Text -> PropertyTest) -> Parser PropertyTest
parsePropertyVal (Text -> PropertyTest
Dash) [Token]
tokens
parsePropertySel [Token]
tokens = (PropertyTest
Exists, [Token] -> [Token]
skipBlock [Token]
tokens)
parsePropertyVal :: (Text -> PropertyTest) -> Parser PropertyTest
parsePropertyVal :: (Text -> PropertyTest) -> Parser PropertyTest
parsePropertyVal Text -> PropertyTest
wrapper (Ident Text
val:Token
RightSquareBracket:[Token]
tokens) = (Text -> PropertyTest
wrapper Text
val, [Token]
tokens)
parsePropertyVal Text -> PropertyTest
wrapper (String Text
val:Token
RightSquareBracket:[Token]
tokens) = (Text -> PropertyTest
wrapper Text
val, [Token]
tokens)
parsePropertyVal Text -> PropertyTest
_ [Token]
tokens = (PropertyTest
Exists, [Token] -> [Token]
skipBlock [Token]
tokens)