@@ -5,35 +5,71 @@ module Web.DOM.DOMParser
55 , parseHTMLFromString
66 , parseSVGFromString
77 , parseXMLFromString
8+ , _getParserError
89 ) where
910
10- -- import Prelude
11+ import Prelude (($), bind , join , map , pure )
1112
13+ import Data.Array (head )
14+ import Data.Either (Either (..))
15+ import Data.Maybe (Maybe (..))
1216import Effect (Effect )
13- import Web.DOM.Document (Document )
17+ import Web.DOM.Document (Document , getElementsByTagName )
18+ import Web.DOM.Element (Element , toNode )
19+ import Web.DOM.HTMLCollection (toArray )
20+ import Web.DOM.Node (textContent )
1421
1522foreign import data DOMParser ∷ Type
1623
1724-- | Create a new `DOMParser`
1825foreign import makeDOMParser ∷ Effect DOMParser
1926
20- -- | Parse a string with the first argumet being a string for a doctype
21- foreign import parseFromString ∷ String → String → DOMParser → Effect Document
27+ -- | Parse a string with the first argumet being a string for a doctype.
28+ -- | Does not capture errors; consider using other wrapper functions,
29+ -- | e.g. parseXMLFromString.
30+ foreign import parseFromString ∷ String -> String -> DOMParser -> Effect Document
2231
2332-- | Convience function to parse HTML from a string, partially applying
2433-- | `parseFromString` with "text/html"
25- parseHTMLFromString ∷ String → DOMParser → Effect Document
26- parseHTMLFromString s d =
27- parseFromString " text/html" s d
34+ parseHTMLFromString ∷ String -> DOMParser -> Effect (Either String Document )
35+ parseHTMLFromString s d = do
36+ doc <- parseFromString " text/html" s d
37+ errMay <- _getParserError doc
38+ pure $ returnIfNothing errMay doc
2839
2940-- | Convience function to parse SVG from a string, partially applying
3041-- | `parseFromString` with "image/svg+xml"
31- parseSVGFromString ∷ String → DOMParser → Effect Document
32- parseSVGFromString s d =
33- parseFromString " image/svg+xml" s d
42+ parseSVGFromString ∷ String -> DOMParser -> Effect (Either String Document )
43+ parseSVGFromString s d = do
44+ doc <- parseFromString " image/svg+xml" s d
45+ errMay <- _getParserError doc
46+ pure $ returnIfNothing errMay doc
3447
3548-- | Convience function to parse XML from a string, partially applying
3649-- | `parseFromString` with "application/xml"
37- parseXMLFromString ∷ String → DOMParser → Effect Document
38- parseXMLFromString s d =
39- parseFromString " application/xml" s d
50+ parseXMLFromString ∷ String -> DOMParser -> Effect (Either String Document )
51+ parseXMLFromString s d = do
52+ doc <- parseFromString " application/xml" s d
53+ errMay <- _getParserError doc
54+ pure $ returnIfNothing errMay doc
55+
56+ -- | Utility method for extracting Dom Parser errors from document;
57+ -- | should only need to be used if calling `parseFromString` directly.
58+ _getParserError :: Document -> Effect (Maybe String )
59+ _getParserError doc = do
60+ peElems :: Array Element <- join $ map toArray $ getElementsByTagName " parsererror" doc
61+ peEleMay :: Maybe Element <- pure $ head $ peElems
62+ getText peEleMay
63+ where
64+ getText :: Maybe Element -> Effect (Maybe String )
65+ getText elMay = case map toNode elMay of
66+ Nothing -> pure $ Nothing
67+ Just nd -> map Just $ textContent nd
68+
69+ -- | Like [Data.Either.note](https://pursuit.purescript.org/packages/purescript-either/docs/Data.Either#v:note),
70+ -- | but with the logic reversed. Used internally for converting the
71+ -- | result of `_getParserError` to an `Either`.
72+ returnIfNothing :: forall a b . Maybe a -> b -> Either a b
73+ returnIfNothing errMay val = case errMay of
74+ Nothing -> Right val
75+ Just er -> Left er
0 commit comments