@@ 33,7 33,7 @@ compile (Sibling up sel) = indirect previous (compile up) $ compileInner sel
compileInner :: [SimpleSelector] -> SelectorFunc
compileInner sel = compileInner' $ lowerInner sel
-compileInner' :: ([IL], [(Text, String -> Bool)]) -> SelectorFunc
+compileInner' :: ([IL], [(Text, Maybe Text, String -> Bool)]) -> SelectorFunc
compileInner' ((Tagname tag:tests), attrs) = testTag tag $ compileInner' (tests, attrs)
compileInner' ((NS ns:tests), attrs) = testNS ns $ compileInner' (tests, attrs)
compileInner' ((Fail:_), _) = \_ -> False
@@ 44,16 44,17 @@ compileInner' ((Nth ofType n 0:tests), attrs) =
compileInner' ((Nth ofType a b:tests), attrs) =
nthChild' ofType (fromInteger a) (fromInteger b) $ compileInner' (tests, attrs)
compileInner' ([], attrs) = testAttrs (compileAttrs $ sortAttrs attrs) matched
-compileAttrs :: [(Text, String -> Bool)] -> AttrsFunc
-compileAttrs ((tag, test):attrs) = testAttr tag test $ compileAttrs attrs
+compileAttrs :: [(Text, Maybe Text, String -> Bool)] -> AttrsFunc
+compileAttrs ((tag, Nothing, test):attrs) = testAttr tag test $ compileAttrs attrs
+compileAttrs ((tag, Just ns, test):attrs) = testAttrNS ns tag test $ compileAttrs attrs
compileAttrs [] = matched
-lowerInner :: [SimpleSelector] -> ([IL], [(Text, String -> Bool)])
+lowerInner :: [SimpleSelector] -> ([IL], [(Text, Maybe Text, String -> Bool)])
lowerInner (Namespace ns:sel) = (NS ns:tests, attrs) where (tests, attrs) = lowerInner sel
lowerInner (Tag tag:sel) = (Tagname tag:tests, attrs) where (tests, attrs) = lowerInner sel
-lowerInner (Id i:s) = (tests, ("id", hasWord $ unpack i):attrs) where (tests, attrs) = lowerInner s
-lowerInner (Class c:s) = (tests, ("class", hasWord $ unpack c):attrs) where (tests, attrs) = lowerInner s
-lowerInner (Property _ prop test:s) = (tests, (prop, compileAttrTest test):attrs)
+lowerInner (Id i:s) = (tests, ("id", Nothing, hasWord $ unpack i):attrs) where (tests, attrs) = lowerInner s
+lowerInner (Class c:s) = (tests, ("class", Nothing, hasWord $ unpack c):attrs) where (tests, attrs) = lowerInner s
+lowerInner (Property ns prop test:s) = (tests, (prop, ns, compileAttrTest test):attrs)
where (tests, attrs) = lowerInner s
-- psuedos, TODO handle argumented psuedoclasses.
lowerInner (Psuedoclass c args:s)
@@ 66,7 67,7 @@ lowerInner (Psuedoclass "nth-child" args:s) =
lowerInner (Psuedoclass "nth-of-type" args:s) =
(parseNth True (filter (== Whitespace) args):tests, attrs) where (tests, attrs) = lowerInner s
lowerInner (Psuedoclass c []:s) =
- (tests, ("", hasWord $ unpack c):attrs) where (tests, attrs) = lowerInner s
+ (tests, ("", Nothing, hasWord $ unpack c):attrs) where (tests, attrs) = lowerInner s
lowerInner (Psuedoclass _ _:_) = ([Fail], [])
lowerInner [] = ([], [])
@@ 79,8 80,8 @@ compileAttrTest (Substring val) = isInfixOf $ unpack val
compileAttrTest (Include val) = hasWord $ unpack val
compileAttrTest (Dash val) = hasLang $ unpack val
-sortAttrs :: [(Text, b)] -> [(Text, b)]
-sortAttrs = sortBy compareAttrs where compareAttrs x y = fst x `compare` fst y
+sortAttrs :: [(Text, Maybe Text, b)] -> [(Text, Maybe Text, b)]
+sortAttrs = sortBy compareAttrs where compareAttrs (x, x', _) (y, y', _) = (x, x') `compare` (y, y')
--------
---- Runtime
@@ 88,6 89,7 @@ sortAttrs = sortBy compareAttrs where compareAttrs x y = fst x `compare` fst y
testTag :: Text -> SelectorFunc -> SelectorFunc
testTag tag success el | name el == tag = success el
| otherwise = False
+testNS :: Text -> SelectorFunc -> SelectorFunc
testNS ns success el | namespace el == ns = success el
| otherwise = False
testAttrs :: AttrsFunc -> SelectorFunc -> SelectorFunc
@@ 105,12 107,19 @@ matched :: t -> Bool
matched _ = True
testAttr :: Text -> (String -> Bool) -> AttrsFunc -> AttrsFunc
-testAttr expected test next attrs@(Attribute attr value : attrs')
+testAttr expected test next attrs@(Attribute attr _ value : attrs')
| attr < expected = testAttr expected test next attrs'
| attr > expected = False
| attr == expected && test value = next attrs
| otherwise = False
testAttr _ _ _ [] = False
+testAttrNS :: Text -> Text -> (String -> Bool) -> AttrsFunc -> AttrsFunc
+testAttrNS expectedNS expected test next attrs@(Attribute attr ns value : attrs')
+ | (attr, ns) < (expected, expectedNS) = testAttrNS expectedNS expected test next attrs'
+ | (attr, ns) > (expected, expectedNS) = False
+ | (attr, ns) == (expected, expectedNS) && test value = next attrs
+ | otherwise = False
+testAttrNS _ _ _ _ [] = False
hasWord :: String -> String -> Bool
hasWord expected value = expected `elem` words value
@@ 103,9 103,9 @@ spec = do
parent = Nothing,
previous = Nothing,
attributes = [
- Attribute "class" "external",
- Attribute "href" "https://adrian.geek.nz/",
- Attribute "id" "mysite"
+ Attribute "class" "" "external",
+ Attribute "href" "" "https://adrian.geek.nz/",
+ Attribute "id" "" "mysite"
]
}
let element2 = ElementNode {
@@ 140,10 140,10 @@ spec = do
parent = Nothing,
previous = Nothing,
attributes = [
- Attribute "class" "external secure link",
- Attribute "href" "https://adrian.geek.nz/index.html",
- Attribute "id" "mysite",
- Attribute "lang" "en-US"
+ Attribute "class" "" "external secure link",
+ Attribute "href" "" "https://adrian.geek.nz/index.html",
+ Attribute "id" "" "mysite",
+ Attribute "lang" "" "en-US"
]
}
let sibling = ElementNode {
@@ 244,7 244,7 @@ spec = do
namespace = "",
parent = Nothing,
previous = Nothing,
- attributes = [Attribute "class" "link"]
+ attributes = [Attribute "class" "" "link"]
}
let rules = parse queryable "a.link {color: green} a {color: red}"
let VarParser _ (TrivialPropertyParser style) = cascade rules el [] temp::(VarParser TrivialPropertyParser)
@@ 255,7 255,7 @@ spec = do
namespace = "",
parent = Nothing,
previous = Nothing,
- attributes = [Attribute "class" "link"]
+ attributes = [Attribute "class" "" "link"]
}
let rules = parse queryable "a {color: red; color: green}"
let VarParser _ (TrivialPropertyParser style) = cascade rules el [] temp::(VarParser TrivialPropertyParser)
@@ 270,7 270,7 @@ spec = do
namespace = "",
parent = Nothing,
previous = Nothing,
- attributes = [Attribute "class" "link"]
+ attributes = [Attribute "class" "" "link"]
}
let rules = parse (queryable {priority = 1}) "a {color: green}"
let rules2 = parse (rules {priority = 2}) "a {color: red}" :: QueryableStyleSheet (VarParser TrivialPropertyParser)
@@ 282,7 282,7 @@ spec = do
namespace = "",
parent = Nothing,
previous = Nothing,
- attributes = [Attribute "class" "link"]
+ attributes = [Attribute "class" "" "link"]
}
let rules' = parse (queryable {priority = 1}) "a {color: red}"
let rules2' = parse (rules' {priority = 2}) "a {color: green !important}" :: QueryableStyleSheet (VarParser TrivialPropertyParser)
@@ 294,7 294,7 @@ spec = do
namespace = "",
parent = Nothing,
previous = Nothing,
- attributes = [Attribute "class" "link"]
+ attributes = [Attribute "class" "" "link"]
}
let rules = parse queryable "a {color: red;}"
let VarParser _ (TrivialPropertyParser style) = cascade rules el [("color", [Ident "green"])] temp::(VarParser TrivialPropertyParser)