{-# 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