{-# LANGUAGE OverloadedStrings #-} module Graphics.Rendering.Rect.CSS.Backgrounds (Backgrounds(..)) where import Stylist (PropertyParser(..), parseUnorderedShorthand) import Data.CSS.Syntax.Tokens (Token(..)) import Data.Maybe (isJust, catMaybes) import Graphics.Rendering.Rect.CSS.Colour (ColourPallet, parseColour) import Data.Colour (AlphaColour, transparent) import Graphics.Rendering.Rect.Types (Rects(..), Rect(..)) data Backgrounds = Backgrounds { pallet :: ColourPallet, background :: AlphaColour Float, clip :: [Rects -> Rect] } instance PropertyParser Backgrounds where temp = Backgrounds { pallet = temp, background = transparent, clip = [borderBox] } inherit _ = temp priority _ = [] longhand _ self@Backgrounds{ pallet = c } "background-color" toks | Just ([], val) <- parseColour c toks = Just self { background = val } longhand _ self "background-clip" t | val@(_:_) <- parseCSSList inner t = Just self { clip = val } where inner [Ident "content-box"] = Just contentBox inner [Ident "padding-box"] = Just paddingBox inner [Ident "border-box"] = Just borderBox inner [Ident "initial"] = Just borderBox -- To aid shorthand implementation. inner _ = Nothing longhand _ _ _ _ = Nothing -- The multi-layered shorthand is one source of parsing complexity. shorthand self "background" t = catProps $ reverse $ parseCSSList inner t where catProps [] = [] catProps (props:pss) | Just [Ident "initial"] <- "background-color" `lookup` catProps pss = map (catProp $ catProps pss) props | otherwise = [] -- Only allow background-color in bottommost layer. catProp _ ret@("background-color", _) = ret catProp bases (key, val) | Just base <- key `lookup` bases = (key, val ++ Comma:base) -- Shouldn't happen, `inner` expands all props at least to "initial"! | otherwise = (key, val) inner toks | ret@(_:_) <- parseUnorderedShorthand self [ "background-color", "background-clip" ] toks = Just ret | otherwise = Nothing shorthand self key val | Just _ <- longhand self self key val = [(key, val)] | otherwise = [] parseCSSList cb toks | all isJust ret = catMaybes ret | otherwise = [] where ret = map cb $ splitList Comma toks ------ --- Utils taken from HappStack ------ -- | Repeadly splits a list by the provided separator and collects the results splitList :: Eq a => a -> [a] -> [[a]] splitList _ [] = [] splitList sep list = h:splitList sep t where (h,t)=split (==sep) list -- | Split is like break, but the matching element is dropped. split :: (a -> Bool) -> [a] -> ([a], [a]) split f s = (left,right) where (left,right')=break f s right = if null right' then [] else tail right'