~alcinnz/amphiarao

e400209384796fa4599b6d4885dd4166e59a3b5c — Adrian Cochrane 3 years ago 3f48d0d
Attempted integration of XPath selectors.
3 files changed, 17 insertions(+), 13 deletions(-)

M src/Internal/Elements.hs
M src/Internal/Elements/XPath.hs
M src/UI/Search.hs
M src/Internal/Elements.hs => src/Internal/Elements.hs +3 -0
@@ 47,6 47,9 @@ find (Find "css selector" sel) root = case CSS.parsePath sel of
find (Find "link text" sel) root = Right $ allLinks (== pack sel) root
find (Find "partial link text" sel) root = Right $ allLinks (Txt.isInfixOf $ pack sel) root
find (Find "tag name" sel) root = Right (X.descendant root >>= X.checkName (== fromString sel))
find (Find "xpath" sel) root = case XPath.runXPath root $ Txt.pack sel of
    Right res -> Right res
    Left msgs -> Left (True, Prelude.unlines msgs)
find (Find type_ _) _ = Left (False, "Invalid selector type: " ++ Txt.unpack type_)

allLinks test = X.descendant X.>=>

M src/Internal/Elements/XPath.hs => src/Internal/Elements/XPath.hs +13 -13
@@ 20,19 20,7 @@ import Text.Read (readMaybe)
data Context = Context {
        item :: [Value],
        vars :: M.Map Name [Value],
        funcs :: M.Map (Name, Int) (Context -> [[Value]] -> [Value]),
        timestamp :: ZonedTime,
        timezone :: TimeZone,
        lang :: Text,
        calendar :: Text,
        place :: Text, -- Noop?
        docs :: M.Map Name Document,
        texts :: M.Map Text Text,
        collections :: M.Map Text [Value],
        collection :: [Value],
        uriCollections :: M.Map Text [Text],
        uriCollection :: [Text],
        environment :: M.Map Text Text
        funcs :: M.Map (Name, Int) (Context -> [[Value]] -> [Value])
    }

---- Typesystem/coercion


@@ 565,3 553,15 @@ fnMathATan _ [x'] | Right x <- num x' = [Number $ atan x]
fnMathATan _ _ = typeError
fnMathATan2 _ [y', x'] | Right x <- num x', Right y <- num y' = [Number $ atan2 y x]
fnMathATan2 _ _ = typeError

---- Public API
runXPath' node sel = case parseXPath sel of
    Right ast -> evals Context {
            item = [Node node],
            vars = M.empty,
            funcs = stdLib
        } ast
    Left err -> [Error "err:syntax" err ""]
runXPath node sel = let ret = runXPath' node sel
    in if any isErr ret then Left [msg | Error name msg _ <- ret]
    else Right [n | Node n <- ret]

M src/UI/Search.hs => src/UI/Search.hs +1 -0
@@ 28,6 28,7 @@ engines = [
    (const "CSS", queryEls "css selector"),
    (flip l LinkSearchExact, queryEls "link text"), -- Only useful if it promotes results higher.
    (flip l LinkSearch, queryEls "partial link text")
--    (const "XPath", queryEls "xpath") -- FIXME parser infinite loops...
  ]

result href' = a ! href (stringValue href') ! target "preview"