~alcinnz/haskell-stylist

ee89bcfdbf10f2759cf3b618a5fa3f2b0bbafa6c — Adrian Cochrane 5 years ago 768a480
Abstract away RuleStore construction.
M src/Stylish/Style/Selector.hs => src/Stylish/Style/Selector.hs +13 -7
@@ 11,24 11,30 @@ import Stylish.Style.Selector.Common

import Stylish.Parse (StyleSheet(..))

-- TODO do performance tests to decide beside between strict/lazy.
-- TODO do performance tests to decide beside between strict/lazy,
--      or is another Map implementation better?
import Data.HashMap.Strict
import Data.Text.Internal (Text(..))
import Data.CSS.Syntax.Tokens

ruleStore = ImportanceSplitter $ OrderedRuleStore (InterpretedRuleStore styleIndex) 0
type QueryableStyleSheet = QueryableStyleSheet' (ImportanceSplitter (
        OrderedRuleStore (InterpretedRuleStore StyleIndex)
    ))

data QueryableStyleSheet store = QueryableStyleSheet {
data QueryableStyleSheet' store = QueryableStyleSheet' {
    store :: store,
    priority :: Int -- author vs user agent vs user styles
}

queryableStyleSheet = QueryableStyleSheet {store = ruleStore, priority = 0}
queryableStyleSheet :: QueryableStyleSheet
queryableStyleSheet = QueryableStyleSheet' {store = new, priority = 0}

instance RuleStore s => StyleSheet (QueryableStyleSheet s) where
    addRule self@(QueryableStyleSheet store priority) rule = self {
instance RuleStore s => StyleSheet (QueryableStyleSheet' s) where
    addRule self@(QueryableStyleSheet' store priority) rule = self {
            store = addStyleRule store priority $ styleRule' rule
        }

queryRules (QueryableStyleSheet store _) el = lookupRules store el
queryRules (QueryableStyleSheet' store _) el = lookupRules store el

--------
---- Cascade

M src/Stylish/Style/Selector/Common.hs => src/Stylish/Style/Selector/Common.hs +1 -0
@@ 6,6 6,7 @@ import Stylish.Element
import Stylish.Parse

class RuleStore a where
    new :: a
    addStyleRule :: a -> Int -> StyleRule' -> a
    lookupRules :: a -> Element -> [StyleRule']


M src/Stylish/Style/Selector/Importance.hs => src/Stylish/Style/Selector/Importance.hs +1 -0
@@ 18,6 18,7 @@ splitProperties (prop@(name, value):rest)

data ImportanceSplitter a = ImportanceSplitter a
instance RuleStore inner => RuleStore (ImportanceSplitter inner) where
    new = ImportanceSplitter new
    addStyleRule (ImportanceSplitter self) priority rule =
            ImportanceSplitter $ addStyleRule (
                addStyleRule self (negate priority) $ buildRule important

M src/Stylish/Style/Selector/Index.hs => src/Stylish/Style/Selector/Index.hs +2 -3
@@ 1,6 1,6 @@
{-# LANGUAGE OverloadedStrings #-}
module Stylish.Style.Selector.Index (
        StyleIndex(..), styleIndex,
        StyleIndex(..),
        rulesForElement
    ) where



@@ 20,12 20,11 @@ data StyleIndex = StyleIndex {
    unindexed :: [StyleRule']
}

styleIndex = StyleIndex {indexed = empty, unindexed = []}

lookup' :: SimpleSelector -> HashMap SimpleSelector [a] -> [a]
lookup' = lookupDefault []

instance RuleStore StyleIndex where
    new = StyleIndex {indexed = empty, unindexed = []}
    addStyleRule self _ rule | [] == properties rule = self
        | otherwise = addRuleForSelector self rule $ simpleSelector $ selector rule
    lookupRules self element = nub $ Prelude.foldr (++) [] rules

M src/Stylish/Style/Selector/Interpret.hs => src/Stylish/Style/Selector/Interpret.hs +1 -0
@@ 83,6 83,7 @@ hasLang expected value = expected == value || isPrefixOf (expected ++ "-") value
--------
data InterpretedRuleStore inner = InterpretedRuleStore inner
instance RuleStore inner => RuleStore (InterpretedRuleStore inner) where
    new = InterpretedRuleStore new
    addStyleRule (InterpretedRuleStore self) priority rule =
        InterpretedRuleStore $ addStyleRule self priority $ rule {
            compiledSelector = compile $ selector rule

M src/Stylish/Style/Selector/Specificity.hs => src/Stylish/Style/Selector/Specificity.hs +1 -0
@@ 27,6 27,7 @@ add (a, b, c) (x, y, z) = (a + x, b + y, c + z)
data OrderedRuleStore inner = OrderedRuleStore inner Int

instance RuleStore inner => RuleStore (OrderedRuleStore inner) where
    new = OrderedRuleStore new 0
    addStyleRule (OrderedRuleStore self count) priority rule = OrderedRuleStore (
            addStyleRule self priority $ rule {
                rank = (priority, computeSpecificity $ selector rule, count)

M test/Test.hs => test/Test.hs +3 -0
@@ 12,6 12,7 @@ import Stylish.Style.Selector.Interpret
import Stylish.Style.Selector.Common
import Stylish.Style.Selector

main :: IO ()
main = hspec spec

spec = do


@@ 210,6 211,8 @@ spec = do
            selector sibling `shouldBe` False
            selector child `shouldBe` True

styleIndex :: StyleIndex
styleIndex = new
emptyStyle = TrivialStyleSheet []
linkStyle = TrivialStyleSheet [sampleRule]
sampleRule = StyleRule (Element [Tag "a"]) [("color", [Ident "green"])]