css-parser-0.0.1: src/CssParser/At/MediaQuery.hs
module CssParser.At.MediaQuery where
import CssParser.Ident ( PropertyName )
import CssParser.Prelude
import CssParser.Rule.Value
import CssParser.Show
( CssShow(..), ShowParenthesis(..), ShowSpaceBetween(..) )
import Expression.Reorder
data MediaType
= AllMt
| Print
| Screen
| Tty
| Tv
| Projection
| Handheld
| Braille
| Embossed
| Aural
| Speech
deriving (Eq, Show, Ord, Enum, Bounded, Generic)
instance CssShow MediaType where
toCssText = \case
AllMt -> "all"
Print -> "print"
Screen -> "screen"
Tty -> "tty"
Tv -> "tv"
Projection -> "projection"
Handheld -> "handheld"
Braille -> "braille"
Embossed -> "embossed"
Aural -> "aural"
Speech -> "speech"
data MtModifier = MtNot | MtOnly deriving (Show, Eq, Ord, Enum, Bounded, Generic)
instance CssShow MtModifier where
toCssText = \case
MtNot -> "not "
MtOnly -> "only "
newtype MediaQueryList = MediaQueryList [MediaQuery] deriving (Show, Eq, Ord, Generic)
instance ShowSpaceBetween MediaQuery MediaQuery where
cssSpace _ _ = ", "
instance CssShow MediaQueryList where
toCssText (MediaQueryList mqs) = toCssText mqs
data MediaQuery
= MediaQueryConditionOnly MediaCondition
| MediaQueryWithMt (Maybe MtModifier) MediaType (Maybe MediaCondition)
deriving (Show, Eq, Ord, Generic)
instance CssShow MediaQuery where
toCssText = \case
MediaQueryConditionOnly mbe -> toCssText mbe
MediaQueryWithMt mtMod mt mbe ->
toCssText mtMod <>
toCssText mt <>
maybe "" ((" and " <>) . toCssText) mbe
data BinOp = Or | And deriving (Show, Eq, Ord, Generic)
instance CssShow BinOp where
toCssText = \case
And -> " and "
Or -> " or "
data Not p a = Not a | AsIs a deriving (Show, Eq, Ord, Generic)
instance (ShowParenthesis p a, CssShow a) => CssShow (Not p a) where
toCssText = \case
Not x -> "not " <> left p a <> toCssText x <> right p a
AsIs x -> left p a <> toCssText x <> right p a
data MediaCondition where
NotMc :: MediaCondition -> MediaCondition
BopMc :: MediaCondition ->
BinOp ->
MediaCondition ->
MediaCondition
ParenMc :: MediaCondition -> MediaCondition
FeatureMc :: MediaFeature -> MediaCondition
deriving (Show, Eq, Ord, Generic)
mkBopMcTree :: BinOp -> NonEmpty MediaCondition -> MediaCondition
mkBopMcTree bop = \case
x :| [] -> x
x :| [y] -> BopMc x bop y
x :| y : l -> BopMc x bop (mkBopMcTree bop $ y :| l)
instance HasFixity BinOp where
fixityOf = \case
Or -> Fixity AssocLeft 1
And -> Fixity AssocLeft 2
instance SyntaxTree MediaCondition String where
reorderChildren = \case
BopMc l op r -> BopMc <$> reorder l <*> pure op <*> reorder r
ParenMc x -> ParenMc <$> reorder x
NotMc x -> NotMc <$> reorder x
o -> pure o
structureOf = \case
BopMc l op r -> NodeInfix (fixityOf op) l r (`BopMc` op)
NotMc x -> NodePrefix 3 x NotMc
_ -> NodeLeaf
makeError err _ = show err
instance CssShow MediaCondition where
toCssText = \case
NotMc mc@FeatureMc {} -> "not " <> toCssText mc
NotMc mc@ParenMc {} -> "not " <> toCssText mc
NotMc mc -> "not (" <> toCssText mc <> ")"
BopMc l op r -> showBopOperand op l <> toCssText op <> showBopOperandR r
ParenMc mc -> "(" <> toCssText mc <> ")"
FeatureMc mf -> "(" <> toCssText mf <> ")"
showBopOperand :: BinOp -> MediaCondition -> LText
showBopOperand pop = \case
BopMc l cop r
| cop /= pop -> "(" <> showBopOperand cop l <> toCssText cop <> showBopOperandR r <> ")"
| otherwise -> showBopOperand cop l <> toCssText cop <> showBopOperandR r
o -> toCssText o
showBopOperandR :: MediaCondition -> LText
showBopOperandR = \case
BopMc l cop r -> "(" <> showBopOperand cop l <> toCssText cop <> showBopOperandR r <> ")"
o -> toCssText o
instance HasParens MediaCondition where
stripParens = \case
x@FeatureMc {} -> x
ParenMc x -> stripParens x
BopMc l op r -> BopMc (stripParens l) op (stripParens r)
NotMc x -> NotMc $ stripParens x
data MediaFeature
= PlainMf PropertyName PropVals
| BooleanMf PropertyName
| OpenRangeFeature PropertyName MfRelation PropVal
| OpenRangeFeatureFlipped PropVal MfRelation PropertyName
| MfClosedRange PropVal MfRelation PropertyName MfRelation PropVal
deriving (Show, Eq, Ord, Generic)
toPlainMf :: PropVals -> MediaFeature -> MediaFeature
toPlainMf pvs = \case
BooleanMf pn -> PlainMf pn pvs
OpenRangeFeature pn _ pv -> PlainMf pn $ PropVals (pure pv) Nothing
OpenRangeFeatureFlipped pv _ pn -> PlainMf pn $ PropVals (pure pv) Nothing
MfClosedRange pv _ pn _ _ -> PlainMf pn $ PropVals (pure pv) Nothing
o -> o
instance CssShow MediaFeature where
toCssText = \case
PlainMf i v -> toCssText i <> ": " <> toCssText v
BooleanMf i -> toCssText i
OpenRangeFeature i r v ->
toCssText i <> toCssText r <> toCssText v
OpenRangeFeatureFlipped v r i ->
toCssText v <> toCssText r <> toCssText i
MfClosedRange lv lr i rr rv ->
toCssText lv <> toCssText lr <> toCssText i <> toCssText rr <> toCssText rv
data MfRelation
= MfEq
| MfGt
| MfLt
| MfGe
| MfLe
deriving (Show, Eq, Ord, Enum, Bounded, Generic)
instance CssShow MfRelation where
toCssText = \case
MfEq -> " = "
MfGt -> " > "
MfLt -> " < "
MfGe -> " >= "
MfLe -> " <= "