Skip to content

Instantly share code, notes, and snippets.

@crappygraphix
Created June 27, 2019 00:09
Show Gist options
  • Save crappygraphix/9c6a8957717bcadea5471a98f0e4aaf5 to your computer and use it in GitHub Desktop.
Save crappygraphix/9c6a8957717bcadea5471a98f0e4aaf5 to your computer and use it in GitHub Desktop.
Call Materialize AutoInit when the dom changes. WIP lots of room for improvement.
{-# LANGUAGE CPP #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
module Main where
import Control.Monad ( void )
import Control.Monad.IO.Class ( liftIO )
import Data.Map as Map
import Data.Text as T
import Language.Javascript.JSaddle
import Lens.Micro.Platform
import Reflex.Dom
main :: IO ()
main = mainWidgetWithHead header body
header :: MonadWidget t m => m ()
header = do
(ev, fire) <- newTriggerEvent
liftIO $ fire ()
meta
dyEvMT <- widgetHold (return never) $ cssFile "https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css" <$ ev
_ <- widgetHold (return never) $ cssFile "https://fonts.googleapis.com/icon?family=Material+Icons" <$ switchPromptlyDyn dyEvMT
return ()
body :: MonadWidget t m => m ()
body = do
evJavascriptLoaded <- injectJavascript
dyT <- holdDyn "Loading Javascript..." $ "Javascript Loaded." <$ evJavascriptLoaded
el "h1" $ dynText dyT
evPb <- delay 3 =<< getPostBuild
_ <- widgetHold blank (el "h6" (text "I'm late to the party.") <$ evPb)
performEvent_ (liftJSM onJavascriptLoaded <$ evJavascriptLoaded)
performEvent_ (liftJSM configureObserver <$ evJavascriptLoaded)
configureObserver :: JSM ()
configureObserver = do
void $ eval (T.unlines
["var bodyObserver = new MutationObserver(function(mutations) {"
," mutations.forEach(function(mutation) {"
," if (mutation.addedNodes.length > 0) {"
," console.log('Node added');"
," M.AutoInit();"
," }"
," });"
,"});"
]::Text)
void $ eval ("bodyObserver.observe(document.querySelector('body'), { childList: true, subtree: true });"::Text)
injectJavascript :: MonadWidget t m => m (Event t ())
injectJavascript = do
(ev, fire) <- newTriggerEvent
liftIO $ fire ()
dyEvJQuery <- widgetHold (return never) $ jsFile "https://code.jquery.com/jquery-3.2.1.slim.min.js" <$ ev
dyEvMat <- widgetHold (return never) $ jsFile "https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js" <$ switchPromptlyDyn dyEvJQuery
return $ switchPromptlyDyn dyEvMat
onJavascriptLoaded :: JSM ()
onJavascriptLoaded = do
m <- jsg ("M"::Text)
void $ m ^. js0 ("AutoInit"::Text)
console <- jsg ("console"::Text)
void $ console ^. js1 ("log"::Text) ("MaterializeCSS Initialized"::Text)
meta :: MonadWidget t m => m ()
meta = elAttr "meta" (Map.fromList [
("name", "viewport")
, ("content", "width=device-width,initial-scale=1")
, ("charset", "UTF-8")
]) $ return ()
cssFile :: MonadWidget t m => Text -> m (Event t ())
cssFile r = do
(e, _) <- elAttr' "link" (Map.fromList [
("rel", "stylesheet")
, ("type", "text/css")
, ("href", r)]) $ return ()
return $ domEvent Load e
jsFile :: MonadWidget t m => Text -> m (Event t ())
jsFile file = do
(e, _) <- elAttr' "script" (Map.fromList
[ ("language", "javascript")
, ("src", file)]) $ return ()
return $ domEvent Load e
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment