Skip to content

Instantly share code, notes, and snippets.

@crappygraphix
Created June 26, 2019 18:37
Show Gist options
  • Save crappygraphix/2455fd4896320608fe6e6bfa19d95b00 to your computer and use it in GitHub Desktop.
Save crappygraphix/2455fd4896320608fe6e6bfa19d95b00 to your computer and use it in GitHub Desktop.
Example of sequential javascript loading so dependent raw actions don't shit the bed.
name: frontend
version: 0.0.1
synopsis: Example of sequential loading of Javascript
homepage: https://github.com/crappygraphix
license: Apache-2.0
author: Chris Johnston
maintainer: crappygraphix@gmail.com
category: Web
build-type: Simple
cabal-version: >=1.10
executable frontend
main-is: Main.hs
build-depends: base >=4.11 && <4.12
, common
, containers >=0.5 && <0.6
, jsaddle >=0.9 && <0.10
, microlens-platform >=0.3 && <0.4
, reflex-dom >=0.5 && <0.6
, text >=1.2 && <1.3
hs-source-dirs: src
default-language: Haskell2010
ghc-options: -Wincomplete-patterns -Wincomplete-uni-patterns -Wunused-imports -Wunused-binds -Werror
default-extensions: OverloadedStrings
, MonoLocalBinds
{-# LANGUAGE CPP #-}
{-# LANGUAGE RankNTypes #-}
module Main where
import Control.Monad ( void )
import Control.Monad.IO.Class ( liftIO )
import Data.Map as Map
import Data.Text
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
performEvent_ (liftJSM onJavascriptLoaded <$ evJavascriptLoaded)
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