on master help sign in
exe-config/frontend: make NodeList utility functions match

plus a note that they should be upstreamed

commit69cfb452441e86d28ea28142ebd6d81cd0e875ff authorTom Smalley <tfsmalley@gmail.com> dateFri 9 Aug 2019, 15:58 (7 years ago) parente9b5df4
2 files changed+31−16
lib/executable-config/lookup/src-ghcjs/Obelisk/ExecutableConfig/Lookup.hs+15−7 lib/frontend/src/Obelisk/Frontend.hs+16−9
lib/executable-config/lookup/src-ghcjs/Obelisk/ExecutableConfig/Lookup.hs+15−7
@@ -15,15 +15,15 @@ import GHCJS.DOM.Document (getHead)
1515import GHCJS.DOM.DOMStringMap (get)
1616import GHCJS.DOM.Element (getInnerHTML)
1717import GHCJS.DOM.HTMLElement (HTMLElement(HTMLElement), getDataset)
18−import GHCJS.DOM.NodeList (item, getLength)
18+import GHCJS.DOM.NodeList (IsNodeList, item, getLength)
1919import GHCJS.DOM.ParentNode (querySelectorAll)
20−import GHCJS.DOM.Types (Node(Node), castTo)
20+import GHCJS.DOM.Types (MonadJSM, Node(Node), castTo)
2121
2222getConfigs :: IO (Map Text ByteString)
2323getConfigs = do
2424 Just doc <- currentDocument
2525 Just hd <- getHead doc
26− nodes <- collToList =<< querySelectorAll hd ("[data-obelisk-executable-config-inject-key]" :: Text)
26+ nodes <- nodeListNodes =<< querySelectorAll hd ("[data-obelisk-executable-config-inject-key]" :: Text)
2727 fmap Map.fromList $ for nodes $ \node -> do
2828 e <- castTo HTMLElement node >>= \case
2929 Nothing -> error "Found node with data attribute obelisk-executable-config-inject-key that is not an HTMLElement."
@@ -33,10 +33,18 @@ getConfigs = do
3333 <$> get dataset ("obelisk-executable-config-inject-key" :: Text)
3434 <*> (fmap decodeOrFail (getInnerHTML e))
3535 where
36− collToList es = do
37− len <- getLength es
38− list <- traverse (item es) $ if len == 0 then [] else [0..len-1]
39− pure $ catMaybes list
4036 decodeOrFail x = case B64.decode (T.encodeUtf8 x) of
4137 Left e -> error ("Obelisk.ExecutableConfig.Lookup.getConfigs: error when decoding base64: " ++ e)
4238 Right x' -> x'
39+
40+-- | Collect all nodes in the node list.
41+--
42+-- TODO: this and the version in obelisk-frontend should be
43+-- upstreamed to jsaddle.
44+nodeListNodes :: (IsNodeList l, MonadJSM m) => l -> m [Node]
45+nodeListNodes es = do
46+ len <- getLength es
47+ -- Warning! len is unsigned. If the NodeList is empty, we must avoid
48+ -- accidentally traversing over [0..maxBound::Word]
49+ nodes <- traverse (item es) $ if len == 0 then [] else [0..len-1]
50+ pure $ catMaybes nodes
lib/frontend/src/Obelisk/Frontend.hs+16−9
@@ -43,11 +43,11 @@ import qualified GHCJS.DOM as DOM
4343import qualified GHCJS.DOM.Types as DOM
4444import qualified GHCJS.DOM.History as DOM
4545import qualified GHCJS.DOM.Window as DOM
46−import Language.Javascript.JSaddle (JSM, jsNull)
46+import Language.Javascript.JSaddle (MonadJSM, JSM, jsNull)
4747import GHCJS.DOM (currentDocument)
4848import GHCJS.DOM.Document (getHead)
49−import GHCJS.DOM.Node (removeChild_)
50−import GHCJS.DOM.NodeList (item, getLength)
49+import GHCJS.DOM.Node (Node, removeChild_)
50+import GHCJS.DOM.NodeList (IsNodeList, item, getLength)
5151import GHCJS.DOM.ParentNode (querySelectorAll)
5252import Obelisk.Frontend.Cookie
5353import Obelisk.Route.Frontend
@@ -105,13 +105,20 @@ removeHTMLConfigs :: JSM ()
105105removeHTMLConfigs = void $ runMaybeT $ do
106106 doc <- MaybeT currentDocument
107107 hd <- MaybeT $ getHead doc
108− es <- collToList =<< querySelectorAll hd ("[data-obelisk-executable-config-inject-key]" :: Text)
108+ es <- nodeListNodes =<< querySelectorAll hd ("[data-obelisk-executable-config-inject-key]" :: Text)
109109 for_ es $ removeChild_ hd
110− where
111− collToList es = do
112− len <- getLength es
113− lst <- traverse (item es) $ take (fromIntegral len) $ [0..] -- fun with unsigned types ...
114− pure $ catMaybes lst
110+
111+-- | Collect all nodes in the node list.
112+--
113+-- TODO: this and the version in exe-config/ghcjs/lookup should be
114+-- upstreamed to jsaddle.
115+nodeListNodes :: (IsNodeList l, MonadJSM m) => l -> m [Node]
116+nodeListNodes es = do
117+ len <- getLength es
118+ -- Warning! len is unsigned. If the NodeList is empty, we must avoid
119+ -- accidentally traversing over [0..maxBound::Word]
120+ nodes <- traverse (item es) $ if len == 0 then [] else [0..len-1]
121+ pure $ catMaybes nodes
115122
116123setInitialRoute :: Bool -> JSM ()
117124setInitialRoute useHash = do