{-| Module : Web.Framework.Plzwrk.Asterius Description : Asterius bindings for plzwrk Copyright : (c) Mike Solomon 2020 License : GPL-3 Maintainer : mike@meeshkan.com Stability : experimental Portability : POSIX, Windows This module exports a single function called @asteriusBrowser@ that you can use to build your DOM with asterius (see the examples in the README.md). Unfortunately, due to the way cabal compiles this documentation, it does not appear on this page. Instead, a dummy function called @ignoreMe@ appears. This is because @asteriusBrowser@ can only be created by using `ahc-cabal`, and haddock uses `cabal` as a default. -} {-# LANGUAGE CPP #-} #if defined(PLZWRK_ENABLE_ASTERIUS) {-# LANGUAGE InterruptibleFFI #-} module Web.Framework.Plzwrk.Asterius (asteriusBrowser) where import Asterius.Aeson import Asterius.ByteString import Asterius.Types import qualified Data.ByteString as BS import Data.ByteString.Unsafe import Data.Coerce import Foreign.Ptr import Web.Framework.Plzwrk.Browserful asteriusBrowser :: IO (Browserful JSVal) asteriusBrowser = return Browserful { eventTargetAddEventListener = _eventTargetAddEventListener , nodeAppendChild = _nodeAppendChild , htmlElemenetClick = _htmlElemenetClick , consoleLog = _consoleLog , consoleLog' = _consoleLog' , documentCreateElement = _documentCreateElement , documentCreateTextNode = _documentCreateTextNode , documentBody = _documentBody , documentGetElementById = _documentGetElementById , documentHead = _documentHead , _freeCallback = __freeCallback , getPropertyAsBool = _getPropertyAsBool , getPropertyAsDouble = _getPropertyAsDouble , getPropertyAsInt = _getPropertyAsInt , getPropertyAsOpaque = _getPropertyAsOpaque , getPropertyAsString = _getString , elementTagName = _elementTagName , nodeInsertBefore = _nodeInsertBefore , invokeOn0 = _invokeOn0 , _makeHaskellCallback = __makeHaskellCallback , nodeChildNodes = _nodeChildNodes , mathRandom = _mathRandom , nodeRemoveChild = _nodeRemoveChild , eventTargetRemoveEventListener = _eventTargetRemoveEventListener , elementSetAttribute = _elementSetAttribute , nodeTextContent = _nodeTextContent } _documentCreateElement :: String -> IO JSVal _documentCreateElement = js_documentCreateElement . toJSString _elementTagName :: JSVal -> IO String _elementTagName x = do v <- js_elementTagName x return $ fromJSString v _nodeTextContent :: JSVal -> IO String _nodeTextContent x = do v <- js_nodeTextContent x return $ fromJSString v _elementSetAttribute :: JSVal -> String -> String -> IO () _elementSetAttribute e k v = js_elementSetAttribute e (toJSString k) (toJSString v) _getPropertyAsOpaque :: JSVal -> String -> IO (Maybe JSVal) _getPropertyAsOpaque n k = do isUndef <- js_null_or_undef n if isUndef then pure Nothing else (do v <- _js_getPropertyAsOpaque n (toJSString k) isUndef' <- js_null_or_undef v if isUndef' then pure Nothing else pure (Just v) ) _getString :: JSVal -> String -> IO (Maybe String) _getString n k = _getGeneric (\v -> (jsonFromJSVal v) :: Either String String) n k _getPropertyAsBool :: JSVal -> String -> IO (Maybe Bool) _getPropertyAsBool n k = _getGeneric (\v -> (jsonFromJSVal v) :: Either String Bool) n k _getPropertyAsInt :: JSVal -> String -> IO (Maybe Int) _getPropertyAsInt n k = _getGeneric (\v -> (jsonFromJSVal v) :: Either String Int) n k _getPropertyAsDouble :: JSVal -> String -> IO (Maybe Double) _getPropertyAsDouble n k = _getGeneric (\v -> (jsonFromJSVal v) :: Either String Double) n k _getGeneric :: (JSVal -> Either String a) -> JSVal -> String -> IO (Maybe a) _getGeneric f n k = do isUndef <- js_null_or_undef n if isUndef then pure Nothing else (do v <- _js_getPropertyAsOpaque n (toJSString k) isUndef' <- js_null_or_undef v if isUndef' then pure Nothing else (let q = f v in either (\_ -> pure Nothing) (pure . Just) q) ) _consoleLog :: String -> IO () _consoleLog t = _js_consoleLog (toJSString t) _consoleLog' :: JSVal -> IO () _consoleLog' v = _js_consoleLog' v _eventTargetAddEventListener :: JSVal -> String -> JSVal -> IO () _eventTargetAddEventListener target event callback = js_eventTargetAddEventListener target (toJSString event) callback _eventTargetRemoveEventListener :: JSVal -> String -> JSVal -> IO () _eventTargetRemoveEventListener target event callback = js_eventTargetRemoveEventListener target (toJSString event) callback _documentCreateTextNode :: String -> IO JSVal _documentCreateTextNode = js_documentCreateTextNode . toJSString _invokeOn0 :: JSVal -> String -> IO JSVal _invokeOn0 e s = _js_invokeOn0 e (toJSString s) _documentGetElementById :: String -> IO (Maybe JSVal) _documentGetElementById k = do v <- js_documentGetElementById (toJSString k) u <- js_null_or_undef v return $ if u then Nothing else Just v getJSVal :: JSFunction -> JSVal getJSVal (JSFunction x) = x __makeHaskellCallback :: (JSVal -> IO ()) -> IO JSVal __makeHaskellCallback a = do x <- makeHaskellCallback1 a return $ getJSVal x __freeCallback :: JSVal -> IO () __freeCallback v = freeHaskellCallback (JSFunction v) _nodeChildNodes :: JSVal -> IO [JSVal] _nodeChildNodes x = do v <- _js_nodeChildNodes x return $ fromJSArray v foreign import javascript "console.log($1)" _js_consoleLog :: JSString -> IO () foreign import javascript "console.log($1)" _js_consoleLog' :: JSVal -> IO () foreign import javascript "$1[$2]()" _js_invokeOn0 :: JSVal -> JSString -> IO JSVal foreign import javascript "$1[$2]" _js_getPropertyAsOpaque :: JSVal -> JSString -> IO JSVal foreign import javascript "document.createElement($1)" js_documentCreateElement :: JSString -> IO JSVal foreign import javascript "Math.random()" _mathRandom :: IO Double foreign import javascript "document.body" _documentBody :: IO JSVal foreign import javascript "document.head" _documentHead :: IO JSVal foreign import javascript "$1.tagName" js_elementTagName :: JSVal -> IO JSString foreign import javascript "$1.textContent" js_nodeTextContent :: JSVal -> IO JSString foreign import javascript "$1.setAttribute($2,$3)" js_elementSetAttribute :: JSVal -> JSString -> JSString -> IO () foreign import javascript "$1.appendChild($2)" _nodeAppendChild :: JSVal -> JSVal -> IO () foreign import javascript "($1 == null) || ($1 == undefined)" js_null_or_undef :: JSVal -> IO Bool foreign import javascript "$1.childNodes" _js_nodeChildNodes :: JSVal -> IO JSArray foreign import javascript "$1.click()" _htmlElemenetClick :: JSVal -> IO () foreign import javascript "$1.insertBefore($2,$3)" _nodeInsertBefore :: JSVal -> JSVal -> JSVal -> IO () foreign import javascript "$1.removeChild($2)" _nodeRemoveChild :: JSVal -> JSVal -> IO () foreign import javascript "$1.addEventListener($2,$3)" js_eventTargetAddEventListener :: JSVal -> JSString -> JSVal -> IO () foreign import javascript "$1.removeEventListener($2,$3)" js_eventTargetRemoveEventListener :: JSVal -> JSString -> JSVal -> IO () foreign import javascript "document.createTextNode($1)" js_documentCreateTextNode :: JSString -> IO JSVal foreign import javascript "document.getElementById($1)" js_documentGetElementById :: JSString -> IO JSVal foreign import javascript "wrapper oneshot" makeHaskellCallback1 :: (JSVal -> IO ()) -> IO JSFunction # else module Web.Framework.Plzwrk.Asterius where ignoreMe :: IO () ignoreMe = print "ignore me" # endif