{-# LANGUAGE CPP #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE ViewPatterns #-}
{-# LANGUAGE LambdaCase #-}
module Miso.FFI
( JSM
, forkJSM
, asyncCallback
, asyncCallback1
, callbackToJSVal
, objectToJSVal
, ghcjsPure
, syncPoint
, addEventListener
, windowAddEventListener
, windowInnerHeight
, windowInnerWidth
, eventPreventDefault
, eventStopPropagation
, now
, consoleLog
, consoleLogJSVal
, stringify
, parse
, clearBody
, objectToJSON
, set
, getBody
, getDoc
, getElementById
, diff'
, integralToJSString
, realFloatToJSString
, jsStringToDouble
, delegateEvent
, copyDOMIntoVTree
, swapCallbacks
, releaseCallbacks
, registerCallback
, focus
, blur
, scrollIntoView
, alert
) where
import Control.Concurrent
import Control.Monad.IO.Class
import Data.Aeson hiding (Object)
import qualified Data.JSString as JSS
import GHCJS.Marshal
import GHCJS.Types
import qualified JavaScript.Object.Internal as OI
#ifdef ghcjs_HOST_OS
import Language.Javascript.JSaddle hiding (obj, val)
#else
import Language.Javascript.JSaddle hiding (Success, obj, val)
#endif
import Miso.String hiding (show)
forkJSM :: JSM () -> JSM ()
forkJSM a = do
ctx <- askJSM
_ <- liftIO (forkIO (runJSM a ctx))
pure ()
asyncCallback :: JSM () -> JSM Function
asyncCallback a = asyncFunction (\_ _ _ -> a)
asyncCallback1 :: (JSVal -> JSM ()) -> JSM Function
asyncCallback1 f = asyncFunction (\_ _ [x] -> f x)
callbackToJSVal :: Function -> JSM JSVal
callbackToJSVal = toJSVal
objectToJSVal :: Object -> JSM JSVal
objectToJSVal = toJSVal
set :: ToJSVal v => MisoString -> v -> OI.Object -> JSM ()
set (unpack -> "class") v obj = do
classSet <- ((JSS.pack "class") `Prelude.elem`) <$> listProps obj
if classSet
then do
classStr <- fromJSValUnchecked =<< getProp (JSS.pack "class") obj
vStr <- fromJSValUnchecked =<< toJSVal v
v' <- toJSVal (classStr <> JSS.pack " " <> vStr)
setProp (JSS.pack "class") v' obj
else do
v' <- toJSVal v
setProp (JSS.pack "class") v' obj
set k v obj = do
v' <- toJSVal v
setProp (fromMisoString k) v' obj
addEventListener :: JSVal
-> MisoString
-> (JSVal -> JSM ())
-> JSM ()
addEventListener self name cb = do
_ <- self # "addEventListener" $ (name, asyncFunction (\_ _ [a] -> cb a))
pure ()
windowAddEventListener :: MisoString
-> (JSVal -> JSM ())
-> JSM ()
windowAddEventListener name cb = do
win <- jsg "window"
addEventListener win name cb
eventStopPropagation :: JSVal -> JSM ()
eventStopPropagation e = do
_ <- e # "stopPropagation" $ ()
pure ()
eventPreventDefault :: JSVal -> JSM ()
eventPreventDefault e = do
_ <- e # "preventDefault" $ ()
pure ()
windowInnerHeight :: JSM Int
windowInnerHeight =
fromJSValUnchecked =<< jsg "window" ! "innerHeight"
windowInnerWidth :: JSM Int
windowInnerWidth =
fromJSValUnchecked =<< jsg "window" ! "innerWidth"
now :: JSM Double
now = fromJSValUnchecked =<< (jsg "performance" # "now" $ ())
consoleLog :: MisoString -> JSM ()
consoleLog v = do
_ <- jsg "console" # "log" $ [toJSString v]
pure ()
consoleLogJSVal :: JSVal -> JSM ()
consoleLogJSVal v = do
_ <- jsg "console" # "log" $ [v]
pure ()
stringify :: ToJSON json => json -> JSM MisoString
{-# INLINE stringify #-}
stringify j = do
v <- toJSVal (toJSON j)
fromJSValUnchecked =<< (jsg "JSON" # "stringify" $ [v])
parse :: FromJSON json => JSVal -> JSM json
{-# INLINE parse #-}
parse jval = do
val <- fromJSValUnchecked =<< (jsg "JSON" # "parse" $ [jval])
case fromJSON val of
Success x -> pure x
Error y -> error y
clearBody :: JSM ()
clearBody =
(jsg "document" ! "body" <# "innerHtml") [""]
objectToJSON
:: JSVal
-> JSVal
-> JSM JSVal
objectToJSON = jsg2 "objectToJSON"
getBody :: JSM JSVal
getBody = jsg "document" ! "body"
getDoc :: JSM JSVal
getDoc = jsg "document"
getElementById :: MisoString -> JSM JSVal
getElementById e = getDoc # "getElementById" $ [e]
diff'
:: OI.Object
-> OI.Object
-> JSVal
-> JSVal
-> JSM ()
diff' a b c d = () <$ jsg4 "diff" a b c d
integralToJSString :: Integral a => a -> MisoString
integralToJSString = pack . show . toInteger
realFloatToJSString :: RealFloat a => a -> MisoString
realFloatToJSString x = (pack . show) (realToFrac x :: Double)
jsStringToDouble :: MisoString -> Double
jsStringToDouble = read . unpack
delegateEvent :: JSVal -> JSVal -> JSM JSVal -> JSM ()
delegateEvent mountPoint events getVTree = do
cb' <- function $ \_ _ [continuation] -> do
res <- getVTree
_ <- call continuation global res
pure ()
delegateEvent' mountPoint events cb'
delegateEvent' :: JSVal -> JSVal -> Function -> JSM ()
delegateEvent' mountPoint events cb = () <$ jsg3 "delegate" mountPoint events cb
copyDOMIntoVTree :: Bool -> JSVal -> JSVal -> JSM ()
copyDOMIntoVTree logLevel mountPoint a = () <$ jsg3 "copyDOMIntoVTree" logLevel mountPoint a
swapCallbacks :: JSM ()
swapCallbacks = pure ()
releaseCallbacks :: JSM ()
releaseCallbacks = pure ()
registerCallback :: JSVal -> JSM ()
registerCallback _ = pure ()
focus :: MisoString -> JSM ()
focus a = () <$ jsg1 "callFocus" a
blur :: MisoString -> JSM ()
blur a = () <$ jsg1 "callBlur" a
scrollIntoView :: MisoString -> JSM ()
scrollIntoView elId = do
el <- jsg "document" # "getElementById" $ [elId]
_ <- el # "scrollIntoView" $ ()
pure ()
alert :: MisoString -> JSM ()
alert a = () <$ jsg1 "alert" a