on decrease-android-validity help sign in
51 lines 2.1 kB history raw
1{-# LANGUAGE LambdaCase #-}
2{-# LANGUAGE OverloadedStrings #-}
3module Obelisk.ExecutableConfig.Lookup where
5import Data.ByteString (ByteString)
6import qualified Data.ByteString.Base64 as B64
7import Data.Map (Map)
8import qualified Data.Map as Map
9import Data.Maybe (catMaybes)
10import Data.Text (Text)
11import qualified Data.Text.Encoding as T
12import Data.Traversable (for)
13import GHCJS.DOM
14import GHCJS.DOM.Document (getHead)
15import GHCJS.DOM.DOMStringMap (get)
16import GHCJS.DOM.Element (getInnerHTML)
17import GHCJS.DOM.HTMLElement (HTMLElement(HTMLElement), getDataset)
18import GHCJS.DOM.NodeList (IsNodeList, item, getLength)
19import GHCJS.DOM.ParentNode (querySelectorAll)
20import GHCJS.DOM.Types (MonadJSM, Node(Node), castTo)
22getConfigs :: IO (Map Text ByteString)
23getConfigs = do
24 Just doc <- currentDocument
25 Just hd <- getHead doc
26 nodes <- nodeListNodes =<< querySelectorAll hd ("[data-obelisk-executable-config-inject-key]" :: Text)
27 fmap Map.fromList $ for nodes $ \node -> do
28 e <- castTo HTMLElement node >>= \case
29 Nothing -> error "Found node with data attribute obelisk-executable-config-inject-key that is not an HTMLElement."
30 Just htmlE -> return htmlE
31 dataset <- getDataset e
32 (,)
33 -- the key is camelCased: https://html.spec.whatwg.org/multipage/dom.html#dom-dataset
34 <$> get dataset ("obeliskExecutableConfigInjectKey" :: Text)
35 <*> (fmap decodeOrFail (getInnerHTML e))
36 where
37 decodeOrFail x = case B64.decode (T.encodeUtf8 x) of
38 Left e -> error ("Obelisk.ExecutableConfig.Lookup.getConfigs: error when decoding base64: " ++ e)
39 Right x' -> x'
41-- | Collect all nodes in the node list.
42--
43-- TODO: this and the version in obelisk-frontend should be
44-- upstreamed to jsaddle.
45nodeListNodes :: (IsNodeList l, MonadJSM m) => l -> m [Node]
46nodeListNodes es = do
47 len <- getLength es
48 -- Warning! len is unsigned. If the NodeList is empty, we must avoid
49 -- accidentally traversing over [0..maxBound::Word]
50 nodes <- traverse (item es) $ if len == 0 then [] else [0..len-1]
51 pure $ catMaybes nodes