{-# LANGUAGE OverloadedStrings #-} module Graphics.Rendering.Rect.CSS.Border(Border(..), BorderStyle(..), topColour, rightColour, bottomColour, leftColour) where import Stylist (PropertyParser(..), parseUnorderedShorthand, parseOperands) import Data.CSS.Syntax.Tokens (Token(..)) import Graphics.Rendering.Rect.CSS.Colour (ColourPallet(foreground), parseColour) import Data.Colour (AlphaColour) import Data.Maybe (fromMaybe, isJust) import Data.Text (Text) data Border = Border { borderPallet :: ColourPallet, topStyle :: BorderStyle, topColour' :: Maybe (AlphaColour Float), rightStyle :: BorderStyle, rightColour' :: Maybe (AlphaColour Float), bottomStyle :: BorderStyle, bottomColour' :: Maybe (AlphaColour Float), leftStyle :: BorderStyle, leftColour' :: Maybe (AlphaColour Float) } deriving (Eq, Show, Read) resolveColour :: Border -> Maybe (AlphaColour Float) -> AlphaColour Float resolveColour self = fromMaybe $ foreground $ borderPallet self topColour, rightColour, bottomColour, leftColour :: Border -> AlphaColour Float topColour self = resolveColour self $ topColour' self rightColour self = resolveColour self $ rightColour' self bottomColour self = resolveColour self $ bottomColour' self leftColour self = resolveColour self $ leftColour' self data BorderStyle = NoBorder | Solid | Dashed | Dotted | Double | Groove | Ridge | Inset | Outset deriving (Eq, Show, Read, Enum) style :: Token -> Maybe BorderStyle style (Ident "initial") = Just NoBorder style (Ident "none") = Just NoBorder style (Ident "hidden") = Just NoBorder style (Ident "solid") = Just Solid style (Ident "dashed") = Just Dashed style (Ident "dotted") = Just Dotted style (Ident "double") = Just Double style (Ident "groove") = Just Groove style (Ident "ridge") = Just Ridge style (Ident "inset") = Just Inset style (Ident "outset") = Just Outset style _ = Nothing instance PropertyParser Border where temp = Border { borderPallet = temp, topStyle = NoBorder, topColour' = Nothing, rightStyle = NoBorder, rightColour' = Nothing, bottomStyle = NoBorder, bottomColour' = Nothing, leftStyle = NoBorder, leftColour' = Nothing } inherit = const temp priority = const [] longhand _ s "border-top-style" [t] | Just v <- style t = Just s {topStyle=v} longhand _ s "border-right-style" [t] | Just v<-style t=Just s {rightStyle=v} longhand _ s "border-bottom-style" [t]|Just v<-style t=Just s {bottomStyle=v} longhand _ s "border-left-style" [t] | Just v<-style t = Just s {leftStyle=v} longhand _ self@Border { borderPallet = cc } "border-top-color" ts | Just ([], v) <- parseColour cc ts = Just self { topColour' = Just v } longhand _ self@Border { borderPallet = cc } "border-right-color" ts | Just ([], v) <- parseColour cc ts = Just self { rightColour' = Just v } longhand _ self@Border { borderPallet = cc } "border-bottom-color" ts | Just ([], v) <- parseColour cc ts = Just self { bottomColour' = Just v } longhand _ self@Border { borderPallet = cc } "border-left-color" ts | Just ([], v) <- parseColour cc ts = Just self { bottomColour' = Just v } -- Should be handled by caller, but for the sake of shorthands... longhand _ self "border-top-width" [Dimension _ _ "px"] = Just self longhand _ self "border-right-width" [Dimension _ _ "px"] = Just self longhand _ self "border-bottom-width" [Dimension _ _ "px"] = Just self longhand _ self "border-left-width" [Dimension _ _ "px"] = Just self longhand _ _ _ _ = Nothing shorthand self "border-width" toks | length x > 0 && length x <= 4, (top:right:bottom:left:_) <- cycle x, all (validProp self "border-top-width") x = [("border-top-width", top), ("border-right-width", right), ("border-bottom-width", bottom), ("border-left-width", left)] where x = parseOperands toks -- Define other border shorthands here to properly handle border-widths shorthand self "border" toks = parseUnorderedShorthand self [ "border-color", "border-style", "border-width"] toks shorthand self "border-top" toks = parseUnorderedShorthand self [ "border-top-color", "border-top-style", "border-top-width"] toks shorthand self "border-right" toks = parseUnorderedShorthand self [ "border-right-color", "border-right-style", "border-right-width"] toks shorthand self "border-bottom" toks = parseUnorderedShorthand self [ "border-bottom-color", "border-bottom-style", "border-bottom-width"] toks shorthand self "border-left" toks = parseUnorderedShorthand self [ "border-left-color", "border-left-style", "border-left-width"] toks shorthand self "border-inline" toks = parseUnorderedShorthand self [ "border-inline-color", "border-inline-style", "border-inline-width"] toks shorthand self "border-inline-start" toks = parseUnorderedShorthand self [ "border-inline-start-color", "border-inline-start-style", "border-inline-start-width"] toks shorthand self "border-inline-end" toks = parseUnorderedShorthand self [ "border-inline-end-color", "border-inline-end-style", "border-inline-end-width"] toks shorthand self "border-block" toks = parseUnorderedShorthand self [ "border-block-color", "border-block-style", "border-block-width"] toks shorthand self "border-block-start" toks = parseUnorderedShorthand self [ "border-block-start-color", "border-block-start-style", "border-block-start-width"] toks shorthand self "border-block-end" toks = parseUnorderedShorthand self [ "border-block-end-color", "border-block-end-style", "border-block-end-width"] toks shorthand self "border-color" toks | length x > 0 && length x <= 4, (top:right:bottom:left:_) <- cycle x, all (validProp self "border-top-color") x = [("border-top-color", top), ("border-right-color", right), ("border-bottom-color", bottom), ("border-left-color", left)] where x = parseOperands toks shorthand self "border-style" toks | length x > 0 && length x <= 4, (top:right:bottom:left:_) <- cycle x, all (validProp self "border-top-style") x = [("border-top-style", top), ("border-right-style", right), ("border-bottom-style", bottom), ("border-left-style", left)] where x = parseOperands toks shorthand self "border-width" toks | length x > 0 && length x <= 4, (top:right:bottom:left:_) <- cycle x, all (validProp self "border-top-width") x = [("border-top-width", top), ("border-right-width", right), ("border-bottom-width", bottom), ("border-left-width", left)] where x = parseOperands toks shorthand self "border-inline-color" toks | length x > 0 && length x <= 2, (s:e:_) <- cycle x, all (validProp self "border-inline-start-color") x = [("border-inline-start-color", s), ("border-inline-end-color", e)] where x = parseOperands toks shorthand self "border-inline-style" toks | length x > 0 && length x <= 2, (s:e:_) <- cycle x, all (validProp self "border-inline-start-style") x = [("border-inline-start-style", s), ("border-inline-end-style", e)] where x = parseOperands toks shorthand self "border-inline-width" toks | length x > 0 && length x <= 2, (s:e:_) <- cycle x, all (validProp self "border-inline-start-width") x = [("border-inline-start-width", s), ("border-inline-end-style", e)] where x = parseOperands toks shorthand self "border-block-color" toks | length x > 0 && length x <= 2, (s:e:_) <- cycle x, all (validProp self "border-block-start-color") x = [("border-block-start-color", s), ("border-block-end-color", e)] where x = parseOperands toks shorthand self "border-block-style" toks | length x > 0 && length x <= 2, (s:e:_) <- cycle x, all (validProp self "border-block-start-style") x = [("border-block-start-style", s), ("border-block-end-style", e)] where x = parseOperands toks shorthand self "border-block-width" toks | length x > 0 && length x <= 2, (s:e:_) <- cycle x, all (validProp self "border-block-start-width") x = [("border-block-start-width", s), ("border-block-end-width", e)] where x = parseOperands toks shorthand self k v | Just _ <- longhand self self k v = [(k, v)] | otherwise = [] validProp :: PropertyParser a => a -> Text -> [Token] -> Bool validProp self key value = isJust $ longhand self self key value